PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/rpython/lltypesystem/rtuple.py

https://bitbucket.org/pypy/pypy/
Python | 143 lines | 124 code | 7 blank | 12 comment | 6 complexity | b3a1b1c233465b7cb57b327715c9e283 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from pypy.tool.pairtype import pairtype
  2. from pypy.rpython.rmodel import inputconst
  3. from pypy.rpython.robject import PyObjRepr, pyobj_repr
  4. from pypy.rpython.rtuple import AbstractTupleRepr, AbstractTupleIteratorRepr
  5. from pypy.rpython.lltypesystem.lltype import \
  6. Ptr, GcStruct, Void, Signed, malloc, typeOf, nullptr
  7. from pypy.rpython.lltypesystem.rtupletype import TUPLE_TYPE
  8. from pypy.rpython.lltypesystem import rstr
  9. # ____________________________________________________________
  10. #
  11. # Concrete implementation of RPython tuples:
  12. #
  13. # struct tuple {
  14. # type0 item0;
  15. # type1 item1;
  16. # type2 item2;
  17. # ...
  18. # }
  19. class TupleRepr(AbstractTupleRepr):
  20. rstr_ll = rstr.LLHelpers
  21. def __init__(self, rtyper, items_r):
  22. AbstractTupleRepr.__init__(self, rtyper, items_r)
  23. self.lowleveltype = TUPLE_TYPE(self.lltypes)
  24. def newtuple(cls, llops, r_tuple, items_v):
  25. # items_v should have the lowleveltype of the internal reprs
  26. assert len(r_tuple.items_r) == len(items_v)
  27. for r_item, v_item in zip(r_tuple.items_r, items_v):
  28. assert r_item.lowleveltype == v_item.concretetype
  29. #
  30. if len(r_tuple.items_r) == 0:
  31. return inputconst(Void, ()) # a Void empty tuple
  32. c1 = inputconst(Void, r_tuple.lowleveltype.TO)
  33. cflags = inputconst(Void, {'flavor': 'gc'})
  34. v_result = llops.genop('malloc', [c1, cflags],
  35. resulttype = r_tuple.lowleveltype)
  36. for i in range(len(r_tuple.items_r)):
  37. cname = inputconst(Void, r_tuple.fieldnames[i])
  38. llops.genop('setfield', [v_result, cname, items_v[i]])
  39. return v_result
  40. newtuple = classmethod(newtuple)
  41. def instantiate(self):
  42. if len(self.items_r) == 0:
  43. return dum_empty_tuple # PBC placeholder for an empty tuple
  44. else:
  45. return malloc(self.lowleveltype.TO)
  46. def rtype_bltn_list(self, hop):
  47. from pypy.rpython.lltypesystem import rlist
  48. nitems = len(self.items_r)
  49. vtup = hop.inputarg(self, 0)
  50. LIST = hop.r_result.lowleveltype.TO
  51. cno = inputconst(Signed, nitems)
  52. vlist = hop.gendirectcall(LIST.ll_newlist, cno)
  53. v_func = hop.inputconst(Void, rlist.dum_nocheck)
  54. for index in range(nitems):
  55. name = self.fieldnames[index]
  56. ritem = self.items_r[index]
  57. cname = hop.inputconst(Void, name)
  58. vitem = hop.genop('getfield', [vtup, cname], resulttype = ritem)
  59. vitem = hop.llops.convertvar(vitem, ritem, hop.r_result.item_repr)
  60. cindex = inputconst(Signed, index)
  61. hop.gendirectcall(rlist.ll_setitem_nonneg, v_func, vlist, cindex, vitem)
  62. return vlist
  63. def getitem_internal(self, llops, v_tuple, index):
  64. """Return the index'th item, in internal repr."""
  65. name = self.fieldnames[index]
  66. llresult = self.lltypes[index]
  67. cname = inputconst(Void, name)
  68. return llops.genop('getfield', [v_tuple, cname], resulttype = llresult)
  69. def rtype_newtuple(hop):
  70. return TupleRepr._rtype_newtuple(hop)
  71. newtuple = TupleRepr.newtuple
  72. def dum_empty_tuple(): pass
  73. #
  74. # _________________________ Conversions _________________________
  75. class __extend__(pairtype(PyObjRepr, TupleRepr)):
  76. def convert_from_to((r_from, r_to), v, llops):
  77. vlist = []
  78. for i in range(len(r_to.items_r)):
  79. ci = inputconst(Signed, i)
  80. v_item = llops.gencapicall('PyTuple_GetItem_WithIncref', [v, ci],
  81. resulttype = pyobj_repr)
  82. v_converted = llops.convertvar(v_item, pyobj_repr,
  83. r_to.items_r[i])
  84. vlist.append(v_converted)
  85. return r_to.newtuple(llops, r_to, vlist)
  86. class __extend__(pairtype(TupleRepr, PyObjRepr)):
  87. def convert_from_to((r_from, r_to), v, llops):
  88. ci = inputconst(Signed, len(r_from.items_r))
  89. v_result = llops.gencapicall('PyTuple_New', [ci],
  90. resulttype = pyobj_repr)
  91. for i in range(len(r_from.items_r)):
  92. cname = inputconst(Void, r_from.fieldnames[i])
  93. v_item = llops.genop('getfield', [v, cname],
  94. resulttype = r_from.external_items_r[i].lowleveltype)
  95. v_converted = llops.convertvar(v_item, r_from.external_items_r[i],
  96. pyobj_repr)
  97. ci = inputconst(Signed, i)
  98. llops.gencapicall('PyTuple_SetItem_WithIncref', [v_result, ci,
  99. v_converted])
  100. return v_result
  101. # ____________________________________________________________
  102. #
  103. # Iteration.
  104. class Length1TupleIteratorRepr(AbstractTupleIteratorRepr):
  105. def __init__(self, r_tuple):
  106. self.r_tuple = r_tuple
  107. self.lowleveltype = Ptr(GcStruct('tuple1iter',
  108. ('tuple', r_tuple.lowleveltype)))
  109. self.ll_tupleiter = ll_tupleiter
  110. self.ll_tuplenext = ll_tuplenext
  111. TupleRepr.IteratorRepr = Length1TupleIteratorRepr
  112. def ll_tupleiter(ITERPTR, tuple):
  113. iter = malloc(ITERPTR.TO)
  114. iter.tuple = tuple
  115. return iter
  116. def ll_tuplenext(iter):
  117. # for iterating over length 1 tuples only!
  118. t = iter.tuple
  119. if t:
  120. iter.tuple = nullptr(typeOf(t).TO)
  121. return t.item0
  122. else:
  123. raise StopIteration