def compute_result_annotation(self, s_Struct, s_fieldname): assert s_Struct.is_constant() assert s_fieldname.is_constant() ofs = offsetof(s_Struct.const, s_fieldname.const) assert ofs >= 0 s_result = SomeInteger(nonneg=True) s_result.const = ofs return s_result
def compute_result_annotation(self, s_arg): from pypy.annotation.model import SomeInteger if isinstance(s_arg, SomeInteger) and s_arg.unsigned: raise UnexpectedRUInt("check_nonneg() arg is a %s" % (s_arg.knowntype,)) s_nonneg = SomeInteger(nonneg=True) if not s_nonneg.contains(s_arg): raise IntegerCanBeNegative return s_arg
def compute_result_annotation(self, s_arg): from pypy.annotation.model import SomeInteger if isinstance(s_arg, SomeInteger) and s_arg.unsigned: raise UnexpectedRUInt("check_nonneg() arg is a %s" % ( s_arg.knowntype,)) s_nonneg = SomeInteger(nonneg=True) if not s_nonneg.contains(s_arg): raise IntegerCanBeNegative return s_arg
def getattr(s_array, s_attr): s = None if s_attr.is_constant() and isinstance(s_attr.const, str): attr = s_attr.const if attr == 'shape': s = SomeTuple([SomeInteger()] * s_array.ndim) elif attr == 'ndim': s = SomeInteger() elif attr == 'dtype': s = SomeChar() if s is None: return SomeObject.getattr(s_array, s_attr) return s
def test_llinterp_refcounted_graph_with_del(self): from pypy.annotation.model import SomeInteger class D: pass delcounter = D() delcounter.dels = 0 class C: def __del__(self): delcounter.dels += 1 c = C() c.x = 1 def h(x): if x: return c else: d = C() d.x = 2 return d def g(x): return h(x).x def f(x): r = g(x) return r + delcounter.dels llinterp, graph = self.llinterpreter_for_transformed_graph(f, [SomeInteger()]) res = llinterp.eval_graph(graph, [1]) assert res == 1 res = llinterp.eval_graph(graph, [0]) assert res == 3
def union((int1, int2)): if int1.unsigned == int2.unsigned: knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) else: t1 = int1.knowntype if t1 is bool: t1 = int t2 = int2.knowntype if t2 is bool: t2 = int if t2 is int: if int2.nonneg == False: raise UnionError, "Merging %s and a possibly negative int is not allowed" % t1 knowntype = t1 elif t1 is int: if int1.nonneg == False: raise UnionError, "Merging %s and a possibly negative int is not allowed" % t2 knowntype = t2 else: raise UnionError, "Merging these types (%s, %s) is not supported" % ( t1, t2) return SomeInteger(nonneg=int1.nonneg and int2.nonneg, knowntype=knowntype)
def test_simple(self): from pypy.annotation.model import SomeInteger class C: pass c = C() c.x = 1 def g(x): if x: return c else: d = C() d.x = 2 return d def f(x): return g(x).x llinterp, graph = self.llinterpreter_for_transformed_graph( f, [SomeInteger()]) res = llinterp.eval_graph(graph, [0]) assert res == f(0) res = llinterp.eval_graph(graph, [1]) assert res == f(1)
def register_os_write(self): os_write = self.llexternal(underscore_on_windows+'write', [rffi.INT, rffi.VOIDP, rffi.SIZE_T], rffi.SIZE_T) def os_write_llimpl(fd, data): count = len(data) outbuf = lltype.malloc(rffi.CCHARP.TO, count, flavor='raw') try: for i in range(count): outbuf[i] = data[i] written = rffi.cast(lltype.Signed, os_write( rffi.cast(rffi.INT, fd), outbuf, rffi.cast(rffi.SIZE_T, count))) if written < 0: raise OSError(rposix.get_errno(), "os_write failed") finally: lltype.free(outbuf, flavor='raw') return written def os_write_oofakeimpl(fd, data): return os.write(fd, OOSupport.from_rstr(data)) return extdef([int, str], SomeInteger(nonneg=True), "ll_os.ll_os_write", llimpl=os_write_llimpl, oofakeimpl=os_write_oofakeimpl)
def builtin_int(s_obj, s_base=None): assert (s_base is None or isinstance(s_base, SomeInteger) and s_obj.knowntype == str), "only int(v|string) or int(string,int) expected" if s_base is not None: args_s = [s_obj, s_base] else: args_s = [s_obj] nonneg = isinstance(s_obj, SomeInteger) and s_obj.nonneg return constpropagate(int, args_s, SomeInteger(nonneg=nonneg))
class __extend__(pairtype(SomeInteger, SomeInteger)): # unsignedness is considered a rare and contagious disease def union((int1, int2)): knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) return SomeInteger(nonneg=int1.nonneg and int2.nonneg, knowntype=knowntype) or_ = xor = add = mul = _clone(union, []) add_ovf = mul_ovf = _clone(union, [OverflowError]) div = floordiv = mod = _clone(union, [ZeroDivisionError]) div_ovf = floordiv_ovf = mod_ovf = _clone( union, [ZeroDivisionError, OverflowError]) def truediv((int1, int2)): return SomeFloat() truediv.can_only_throw = [ZeroDivisionError] truediv_ovf = _clone(truediv, [ZeroDivisionError, OverflowError]) inplace_div = div inplace_truediv = truediv def sub((int1, int2)): knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) return SomeInteger(knowntype=knowntype) sub.can_only_throw = [] sub_ovf = _clone(sub, [OverflowError]) def and_((int1, int2)): knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) return SomeInteger(nonneg=int1.nonneg or int2.nonneg, knowntype=knowntype) and_.can_only_throw = [] def lshift((int1, int2)): if isinstance(int1, SomeBool): return SomeInteger() else: return SomeInteger(knowntype=int1.knowntype) lshift.can_only_throw = [] lshift_ovf = _clone(lshift, [OverflowError]) def rshift((int1, int2)): if isinstance(int1, SomeBool): return SomeInteger(nonneg=True) else: return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype) rshift.can_only_throw = [] def pow((int1, int2), obj3): knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) return SomeInteger(nonneg=int1.nonneg, knowntype=knowntype)
def test_newlist_nonconst(): from pypy.annotation.model import SomeInteger def f(z): x = newlist_hint(sizehint=z) return len(x) graph = getgraph(f, [SomeInteger()]) for llop in graph.startblock.operations: if llop.opname == 'malloc_varsize': break assert llop.args[2] is graph.startblock.inputargs[0]
def test_newlist(): from pypy.annotation.model import SomeInteger def f(z): x = newlist_hint(sizehint=38) if z < 0: x.append(1) return len(x) graph = getgraph(f, [SomeInteger()]) for llop in graph.startblock.operations: if llop.opname == 'malloc_varsize': break assert llop.args[2].value == 38
def write_barrier_check(spaceop, needs_write_barrier=True): t = TranslationContext() t.buildannotator().build_types(lambda x: x, [SomeInteger()]) t.buildrtyper().specialize() transformer = WriteBarrierTransformer(t) llops = LowLevelOpList() hop = GcHighLevelOp(transformer, spaceop, 0, llops) hop.dispatch() found = False print spaceop, '======>' for op in llops: print '\t', op if op.opname == 'direct_call': found = True assert found == needs_write_barrier
def test_simple_varsize(self): from pypy.annotation.model import SomeInteger def f(x): r = [] for i in range(x): if i % 2: r.append(x) return len(r) llinterp, graph = self.llinterpreter_for_transformed_graph( f, [SomeInteger()]) res = llinterp.eval_graph(graph, [0]) assert res == f(0) res = llinterp.eval_graph(graph, [10]) assert res == f(10)
def next(itr): if itr.variant == ("enumerate", ): s_item = itr.s_container.getanyitem() return SomeTuple((SomeInteger(nonneg=True), s_item)) return itr.s_container.getanyitem(*itr.variant)
def ord(str): return SomeInteger(nonneg=True)
def method_count(str, frag, start=None, end=None): return SomeInteger(nonneg=True)
def method_rfind(str, frag, start=None, end=None): return SomeInteger()
def method_index(lst, s_value): getbookkeeper().count("list_index") lst.listdef.generalize(s_value) return SomeInteger(nonneg=True)
def pos(self): return SomeInteger(nonneg=True)