def union((boo1, boo2)): s = SomeBool() if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): s.const = boo1.const if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) if ktd: s.knowntypedata = ktd return s
def union((boo1, boo2)): s = SomeBool() if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): s.const = boo1.const if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) if ktd: s.knowntypedata = ktd return s
def builtin_isinstance(s_obj, s_type, variables=None): r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): r.const = issubclass(s_obj.knowntype, typ) else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") if s_obj.is_constant(): r.const = isinstance(s_obj.const, long) else: if type( s_obj ) is not SomeObject: # only SomeObjects could be longs # type(s_obj) < SomeObject -> SomeBool(False) # type(s_obj) == SomeObject -> SomeBool() r.const = False return r assert not issubclass( typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): if not s_obj.can_be_none(): r.const = True elif not our_issubclass(typ, s_obj.knowntype): r.const = False elif s_obj.knowntype == int and typ == bool: # xxx this will explode in case of generalisation # from bool to int, notice that isinstance( , bool|int) # is quite border case for RPython r.const = False # XXX HACK HACK HACK # XXX HACK HACK HACK # XXX HACK HACK HACK bk = getbookkeeper() if variables is None: fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "simple_call" assert len(op.args) == 3 assert op.args[0] == Constant(isinstance) variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} if (not isinstance(s_type, SomeBuiltin) or typ.__module__ == '__builtin__'): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r
def builtin_isinstance(s_obj, s_type, variables=None): r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): r.const = issubclass(s_obj.knowntype, typ) else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") if s_obj.is_constant(): r.const = isinstance(s_obj.const, long) else: if type(s_obj) is not SomeObject: # only SomeObjects could be longs # type(s_obj) < SomeObject -> SomeBool(False) # type(s_obj) == SomeObject -> SomeBool() r.const = False return r assert not issubclass(typ, (int, long)) or typ in ( bool, int, long, ), "for integers only isinstance(.,int|r_uint) are supported" if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): if not s_obj.can_be_none(): r.const = True elif not our_issubclass(typ, s_obj.knowntype): r.const = False elif s_obj.knowntype == int and typ == bool: # xxx this will explode in case of generalisation # from bool to int, notice that isinstance( , bool|int) # is quite border case for RPython r.const = False # XXX HACK HACK HACK # XXX HACK HACK HACK # XXX HACK HACK HACK bk = getbookkeeper() if variables is None: fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "simple_call" assert len(op.args) == 3 assert op.args[0] == Constant(isinstance) variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} if not isinstance(s_type, SomeBuiltin) or typ.__module__ == "__builtin__": add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r
assert len(op.args) == 2 def tointtype(int0): if int0.knowntype is bool: return int return int0.knowntype if int1.nonneg and isinstance(op.args[1], Variable): case = opname in ('lt', 'le', 'eq') add_knowntypedata(knowntypedata, case, [op.args[1]], SomeInteger(nonneg=True, knowntype=tointtype(int2))) if int2.nonneg and isinstance(op.args[0], Variable): case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) if knowntypedata: r.knowntypedata = knowntypedata # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) if (isinstance(op.args[1], Constant) and type(op.args[1].value) is int and # filter out Symbolics op.args[1].value == 0): if int1.nonneg: if opname == 'lt': r.const = False if opname == 'ge': r.const = True return r def lt(intint): return intint._compare_helper('lt', operator.lt) def le(intint): return intint._compare_helper('le', operator.le)
return int return int0.knowntype if int1.nonneg and isinstance(op.args[1], Variable): case = opname in ('lt', 'le', 'eq') add_knowntypedata( knowntypedata, case, [op.args[1]], SomeInteger(nonneg=True, knowntype=tointtype(int2))) if int2.nonneg and isinstance(op.args[0], Variable): case = opname in ('gt', 'ge', 'eq') add_knowntypedata( knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) if knowntypedata: r.knowntypedata = knowntypedata # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) if (isinstance(op.args[1], Constant) and type(op.args[1].value) is int and # filter out Symbolics op.args[1].value == 0): if int1.nonneg: if opname == 'lt': r.const = False if opname == 'ge': r.const = True return r def lt(intint): return intint._compare_helper('lt', operator.lt)