PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/translator/c/primitive.py

https://bitbucket.org/pypy/pypy/
Python | 227 lines | 222 code | 2 blank | 3 comment | 2 complexity | 0a07a0673f3da64cf1edf69fbdf26bc7 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import sys
  2. from pypy.rlib.objectmodel import Symbolic, ComputedIntSymbolic
  3. from pypy.rlib.objectmodel import CDefinedIntSymbolic
  4. from pypy.rlib.rarithmetic import r_longlong
  5. from pypy.rlib.rfloat import isinf, isnan
  6. from pypy.rpython.lltypesystem.lltype import *
  7. from pypy.rpython.lltypesystem import rffi, llgroup
  8. from pypy.rpython.lltypesystem.llmemory import Address, \
  9. AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset, \
  10. CompositeOffset, ArrayLengthOffset, \
  11. GCHeaderOffset, GCREF, AddressAsInt
  12. from pypy.rpython.lltypesystem.llarena import RoundedUpForAllocation
  13. from pypy.translator.c.support import cdecl, barebonearray
  14. # ____________________________________________________________
  15. #
  16. # Primitives
  17. def name_signed(value, db):
  18. if isinstance(value, Symbolic):
  19. if isinstance(value, FieldOffset):
  20. structnode = db.gettypedefnode(value.TYPE)
  21. return 'offsetof(%s, %s)'%(
  22. cdecl(db.gettype(value.TYPE), ''),
  23. structnode.c_struct_field_name(value.fldname))
  24. elif isinstance(value, ItemOffset):
  25. if value.TYPE != Void and value.repeat != 0:
  26. size = 'sizeof(%s)' % (cdecl(db.gettype(value.TYPE), ''),)
  27. if value.repeat != 1:
  28. size = '(%s * %s)' % (size, value.repeat)
  29. return size
  30. else:
  31. return '0'
  32. elif isinstance(value, ArrayItemsOffset):
  33. if (isinstance(value.TYPE, FixedSizeArray) or
  34. barebonearray(value.TYPE)):
  35. return '0'
  36. elif value.TYPE.OF != Void:
  37. return 'offsetof(%s, items)'%(
  38. cdecl(db.gettype(value.TYPE), ''))
  39. else:
  40. return 'sizeof(%s)'%(cdecl(db.gettype(value.TYPE), ''),)
  41. elif isinstance(value, ArrayLengthOffset):
  42. return 'offsetof(%s, length)'%(
  43. cdecl(db.gettype(value.TYPE), ''))
  44. elif isinstance(value, CompositeOffset):
  45. names = [name_signed(item, db) for item in value.offsets]
  46. return '(%s)' % (' + '.join(names),)
  47. elif type(value) == AddressOffset:
  48. return '0'
  49. elif type(value) == GCHeaderOffset:
  50. return '0'
  51. elif type(value) == RoundedUpForAllocation:
  52. return 'ROUND_UP_FOR_ALLOCATION(%s, %s)' % (
  53. name_signed(value.basesize, db),
  54. name_signed(value.minsize, db))
  55. elif isinstance(value, CDefinedIntSymbolic):
  56. return str(value.expr)
  57. elif isinstance(value, ComputedIntSymbolic):
  58. value = value.compute_fn()
  59. elif isinstance(value, llgroup.CombinedSymbolic):
  60. name = name_small_integer(value.lowpart, db)
  61. assert (value.rest & value.MASK) == 0
  62. return '(%s+%dL)' % (name, value.rest)
  63. elif isinstance(value, AddressAsInt):
  64. return '((long)%s)' % name_address(value.adr, db)
  65. else:
  66. raise Exception("unimplemented symbolic %r"%value)
  67. if value is None:
  68. assert not db.completed
  69. return None
  70. if value == -sys.maxint-1: # blame C
  71. return '(-%dL-1L)' % sys.maxint
  72. else:
  73. return '%dL' % value
  74. def name_unsigned(value, db):
  75. assert value >= 0
  76. return '%dUL' % value
  77. def name_unsignedlonglong(value, db):
  78. assert value >= 0
  79. return '%dULL' % value
  80. def name_signedlonglong(value, db):
  81. maxlonglong = r_longlong.MASK>>1
  82. if value == -maxlonglong-1: # blame C
  83. return '(-%dLL-1LL)' % maxlonglong
  84. else:
  85. return '%dLL' % value
  86. def name_float(value, db):
  87. if isinf(value):
  88. if value > 0:
  89. return '(Py_HUGE_VAL)'
  90. else:
  91. return '(-Py_HUGE_VAL)'
  92. elif isnan(value):
  93. return '(Py_HUGE_VAL/Py_HUGE_VAL)'
  94. else:
  95. x = repr(value)
  96. assert not x.startswith('n')
  97. return x
  98. name_longfloat = name_float
  99. def name_singlefloat(value, db):
  100. value = float(value)
  101. if isinf(value):
  102. if value > 0:
  103. return '((float)Py_HUGE_VAL)'
  104. else:
  105. return '((float)-Py_HUGE_VAL)'
  106. elif isnan(value):
  107. # XXX are these expressions ok?
  108. return '((float)(Py_HUGE_VAL/Py_HUGE_VAL))'
  109. else:
  110. return repr(value) + 'f'
  111. def name_char(value, db):
  112. assert type(value) is str and len(value) == 1
  113. if ' ' <= value < '\x7f':
  114. return "'%s'" % (value.replace("\\", r"\\").replace("'", r"\'"),)
  115. else:
  116. return '((char)%d)' % ord(value)
  117. def name_bool(value, db):
  118. return '%d' % value
  119. def name_void(value, db):
  120. return '/* nothing */'
  121. def name_unichar(value, db):
  122. assert type(value) is unicode and len(value) == 1
  123. return '((wchar_t)%d)' % ord(value)
  124. def name_address(value, db):
  125. if value:
  126. return db.get(value.ref())
  127. else:
  128. return 'NULL'
  129. def name_gcref(value, db):
  130. if value:
  131. obj = value._obj
  132. if isinstance(obj, int):
  133. # a tagged pointer
  134. return _name_tagged(obj, db)
  135. realobj = obj.container
  136. if isinstance(realobj, int):
  137. return _name_tagged(realobj, db)
  138. realvalue = cast_opaque_ptr(Ptr(typeOf(realobj)), value)
  139. return db.get(realvalue)
  140. else:
  141. return 'NULL'
  142. def _name_tagged(obj, db):
  143. assert obj & 1 == 1
  144. return '((%s) %d)' % (cdecl("void*", ''), obj)
  145. def name_small_integer(value, db):
  146. """Works for integers of size at most INT or UINT."""
  147. if isinstance(value, Symbolic):
  148. if isinstance(value, llgroup.GroupMemberOffset):
  149. groupnode = db.getcontainernode(value.grpptr._as_obj())
  150. return 'GROUP_MEMBER_OFFSET(%s, member%s)' % (
  151. cdecl(groupnode.implementationtypename, ''),
  152. value.index,
  153. )
  154. else:
  155. raise Exception("unimplemented symbolic %r" % value)
  156. return str(value)
  157. # On 64 bit machines, SignedLongLong and Signed are the same, so the
  158. # order matters, because we want the Signed implementation.
  159. PrimitiveName = {
  160. SignedLongLong: name_signedlonglong,
  161. Signed: name_signed,
  162. UnsignedLongLong: name_unsignedlonglong,
  163. Unsigned: name_unsigned,
  164. Float: name_float,
  165. SingleFloat: name_singlefloat,
  166. LongFloat: name_longfloat,
  167. Char: name_char,
  168. UniChar: name_unichar,
  169. Bool: name_bool,
  170. Void: name_void,
  171. Address: name_address,
  172. GCREF: name_gcref,
  173. }
  174. PrimitiveType = {
  175. SignedLongLong: 'long long @',
  176. Signed: 'long @',
  177. UnsignedLongLong: 'unsigned long long @',
  178. Unsigned: 'unsigned long @',
  179. Float: 'double @',
  180. SingleFloat: 'float @',
  181. LongFloat: 'long double @',
  182. Char: 'char @',
  183. UniChar: 'wchar_t @',
  184. Bool: 'bool_t @',
  185. Void: 'void @',
  186. Address: 'void* @',
  187. GCREF: 'void* @',
  188. }
  189. def define_c_primitive(ll_type, c_name, suffix=''):
  190. if ll_type in PrimitiveName:
  191. return
  192. if suffix == '':
  193. PrimitiveName[ll_type] = name_small_integer
  194. else:
  195. name_str = '((%s) %%d%s)' % (c_name, suffix)
  196. PrimitiveName[ll_type] = lambda value, db: name_str % value
  197. PrimitiveType[ll_type] = '%s @'% c_name
  198. define_c_primitive(rffi.SIGNEDCHAR, 'signed char')
  199. define_c_primitive(rffi.UCHAR, 'unsigned char')
  200. define_c_primitive(rffi.SHORT, 'short')
  201. define_c_primitive(rffi.USHORT, 'unsigned short')
  202. define_c_primitive(rffi.INT, 'int')
  203. define_c_primitive(rffi.INT_real, 'int')
  204. define_c_primitive(rffi.UINT, 'unsigned int')
  205. define_c_primitive(rffi.LONG, 'long', 'L')
  206. define_c_primitive(rffi.ULONG, 'unsigned long', 'UL')
  207. define_c_primitive(rffi.LONGLONG, 'long long', 'LL')
  208. define_c_primitive(rffi.ULONGLONG, 'unsigned long long', 'ULL')