1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
"""
Code for annotating low-level thingies.
"""
from rpython.tool.pairtype import pair, pairtype
from rpython.annotator.model import (
SomeObject, SomeSingleFloat, SomeFloat, SomeLongFloat, SomeChar,
SomeUnicodeCodePoint, SomeInteger, SomeImpossibleValue,
s_None, s_Bool, UnionError, AnnotatorError)
from rpython.rtyper.lltypesystem import lltype, llmemory
from rpython.rtyper.lltypesystem.lltype import SomePtr
from rpython.rtyper.lltypesystem.llmemory import (
SomeAddress, SomeTypedAddressAccess)
class __extend__(pairtype(SomeAddress, SomeAddress)):
def union((s_addr1, s_addr2)):
return SomeAddress()
def sub((s_addr1, s_addr2)):
from rpython.annotator.bookkeeper import getbookkeeper
if s_addr1.is_null_address() and s_addr2.is_null_address():
return getbookkeeper().immutablevalue(0)
return SomeInteger()
def is_((s_addr1, s_addr2)):
assert False, "comparisons with is not supported by addresses"
class __extend__(pairtype(SomeTypedAddressAccess, SomeTypedAddressAccess)):
def union((s_taa1, s_taa2)):
assert s_taa1.type == s_taa2.type
return s_taa1
class __extend__(pairtype(SomeTypedAddressAccess, SomeInteger)):
def getitem((s_taa, s_int)):
return lltype_to_annotation(s_taa.type)
getitem.can_only_throw = []
def setitem((s_taa, s_int), s_value):
assert annotation_to_lltype(s_value) is s_taa.type
setitem.can_only_throw = []
class __extend__(pairtype(SomeAddress, SomeInteger)):
def add((s_addr, s_int)):
return SomeAddress()
def sub((s_addr, s_int)):
return SomeAddress()
class __extend__(pairtype(SomeAddress, SomeImpossibleValue)):
# need to override this specifically to hide the 'raise UnionError'
# of pairtype(SomeAddress, SomeObject).
def union((s_addr, s_imp)):
return s_addr
class __extend__(pairtype(SomeImpossibleValue, SomeAddress)):
# need to override this specifically to hide the 'raise UnionError'
# of pairtype(SomeObject, SomeAddress).
def union((s_imp, s_addr)):
return s_addr
class __extend__(pairtype(SomeAddress, SomeObject)):
def union((s_addr, s_obj)):
raise UnionError(s_addr, s_obj)
class __extend__(pairtype(SomeObject, SomeAddress)):
def union((s_obj, s_addr)):
raise UnionError(s_obj, s_addr)
class SomeInteriorPtr(SomePtr):
def __init__(self, ll_ptrtype):
assert isinstance(ll_ptrtype, lltype.InteriorPtr)
self.ll_ptrtype = ll_ptrtype
class SomeLLADTMeth(SomeObject):
immutable = True
def __init__(self, ll_ptrtype, func):
self.ll_ptrtype = ll_ptrtype
self.func = func
def can_be_none(self):
return False
def call(self, args):
from rpython.annotator.bookkeeper import getbookkeeper
bookkeeper = getbookkeeper()
s_func = bookkeeper.immutablevalue(self.func)
return s_func.call(args.prepend(lltype_to_annotation(self.ll_ptrtype)))
class __extend__(pairtype(SomePtr, SomePtr)):
def union((p1, p2)):
if p1.ll_ptrtype != p2.ll_ptrtype:
raise UnionError(p1, p2)
return SomePtr(p1.ll_ptrtype)
class __extend__(pairtype(SomePtr, SomeInteger)):
def getitem((p, int1)):
example = p.ll_ptrtype._example()
try:
v = example[0]
except IndexError:
return None # impossible value, e.g. FixedSizeArray(0)
return ll_to_annotation(v)
getitem.can_only_throw = []
def setitem((p, int1), s_value): # just doing checking
example = p.ll_ptrtype._example()
if example[0] is not None: # ignore Void s_value
v_lltype = annotation_to_lltype(s_value)
example[0] = v_lltype._defl()
setitem.can_only_throw = []
class __extend__(pairtype(SomePtr, SomeObject)):
def union((p, obj)):
raise UnionError(p, obj)
def getitem((p, obj)):
raise AnnotatorError("ptr %r getitem index not an int: %r" %
(p.ll_ptrtype, obj))
def setitem((p, obj), s_value):
raise AnnotatorError("ptr %r setitem index not an int: %r" %
(p.ll_ptrtype, obj))
class __extend__(pairtype(SomeObject, SomePtr)):
def union((obj, p2)):
return pair(p2, obj).union()
annotation_to_ll_map = [
(SomeSingleFloat(), lltype.SingleFloat),
(s_None, lltype.Void), # also matches SomeImpossibleValue()
(s_Bool, lltype.Bool),
(SomeFloat(), lltype.Float),
(SomeLongFloat(), lltype.LongFloat),
(SomeChar(), lltype.Char),
(SomeUnicodeCodePoint(), lltype.UniChar),
(SomeAddress(), llmemory.Address),
]
def annotation_to_lltype(s_val, info=None):
if isinstance(s_val, SomeInteriorPtr):
p = s_val.ll_ptrtype
if 0 in p.offsets:
assert list(p.offsets).count(0) == 1
return lltype.Ptr(lltype.Ptr(p.PARENTTYPE)._interior_ptr_type_with_index(p.TO))
else:
return lltype.Ptr(p.PARENTTYPE)
if isinstance(s_val, SomePtr):
return s_val.ll_ptrtype
if type(s_val) is SomeInteger:
return lltype.build_number(None, s_val.knowntype)
for witness, T in annotation_to_ll_map:
if witness.contains(s_val):
return T
if info is None:
info = ''
else:
info = '%s: ' % info
raise ValueError("%sshould return a low-level type,\ngot instead %r" % (
info, s_val))
ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map])
def lltype_to_annotation(T):
try:
s = ll_to_annotation_map.get(T)
except TypeError:
s = None # unhashable T, e.g. a Ptr(GcForwardReference())
if s is None:
if isinstance(T, lltype.Typedef):
return lltype_to_annotation(T.OF)
if isinstance(T, lltype.Number):
return SomeInteger(knowntype=T._type)
elif isinstance(T, lltype.InteriorPtr):
return SomeInteriorPtr(T)
else:
return SomePtr(T)
else:
return s
def ll_to_annotation(v):
if v is None:
# i think we can only get here in the case of void-returning
# functions
return s_None
if isinstance(v, lltype._interior_ptr):
ob = v._parent
if ob is None:
raise RuntimeError
T = lltype.InteriorPtr(lltype.typeOf(ob), v._T, v._offsets)
return SomeInteriorPtr(T)
return lltype_to_annotation(lltype.typeOf(v))
|