Esempio n. 1
0
 def improve((ins1, ins2)):
     if ins1.classdef is None:
         resdef = ins2.classdef
     elif ins2.classdef is None:
         resdef = ins1.classdef
     else:
         basedef = ins1.classdef.commonbase(ins2.classdef)
         if basedef is ins1.classdef:
             resdef = ins2.classdef
         elif basedef is ins2.classdef:
             resdef = ins1.classdef
         else:
             if ins1.can_be_None and ins2.can_be_None:
                 return s_None
             else:
                 return s_ImpossibleValue
     res = SomeInstance(
         resdef, can_be_None=ins1.can_be_None and ins2.can_be_None)
     if ins1.contains(res) and ins2.contains(res):
         return res  # fine
     else:
         # this case can occur in the presence of 'const' attributes,
         # which we should try to preserve.  Fall-back...
         thistype = pairtype(SomeInstance, SomeInstance)
         return super(thistype, pair(ins1, ins2)).improve()
Esempio n. 2
0
 def is_((pbc1, pbc2)):
     thistype = pairtype(SomePBC, SomePBC)
     s = super(thistype, pair(pbc1, pbc2)).is_()
     if not s.is_constant():
         if not pbc1.can_be_None or not pbc2.can_be_None:
             for desc in pbc1.descriptions:
                 if desc in pbc2.descriptions:
                     break
             else:
                 s.const = False    # no common desc in the two sets
     return s
Esempio n. 3
0
 class __extend__(pairtype(Lisp_Generator, Block)):
     def emit((gen, block), inputvars):
         gen.progn.append("(do 'something)")
Esempio n. 4
0
 class __extend__(pairtype(C_Generator, Jump)):
     def emit((gen, jump), inputvars):
         gen.lines.append("goto xyz")
Esempio n. 5
0
 class __extend__(pairtype(int, int)):
     def add((x, y)):
         return 'integer: %s+%s' % (x, y)
     def sub((x, y)):
         return 'integer: %s-%s' % (x, y)
Esempio n. 6
0
 class __extend__(pairtype(MiniPickler, str)):
     def write((pickler, x)):
         pickler.emit('S%s' % x)
Esempio n. 7
0
 class __extend__(pairtype(bool, bool)):
     def add((x, y)):
         return 'bool: %s+%s' % (x, y)
Esempio n. 8
0
class __extend__(pairtype(ArrayRepr, ArrayRepr)):
    def convert_from_to((r_array0, r_array1), v, llops):
        assert 0
Esempio n. 9
0
                         'getitem_idx', 'getitem_key', 'getitem_idx_key',
                         'inplace_add', 'inplace_sub', 'inplace_mul',
                         'inplace_truediv', 'inplace_floordiv', 'inplace_div',
                         'inplace_mod', 'inplace_pow',
                         'inplace_lshift', 'inplace_rshift',
                         'inplace_and', 'inplace_or', 'inplace_xor',
                         'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp',
                         'coerce',
                         ]
                        +[opname+'_ovf' for opname in
                          """add sub mul floordiv div mod pow lshift
                           """.split()
                          ])

for opname in BINARY_OPERATIONS:
    missing_operation(pairtype(SomeObject, SomeObject), opname)

class __extend__(pairtype(SomeObject, SomeObject)):

    def union((obj1, obj2)):
        if obj1 == obj2:
            return obj1
        else:
            result = SomeObject()
            if obj1.knowntype == obj2.knowntype and obj1.knowntype != object:
                result.knowntype = obj1.knowntype
            is_type_of1 = getattr(obj1, 'is_type_of', None)
            is_type_of2 = getattr(obj2, 'is_type_of', None)
            if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const:
                result.const = obj1.const
                is_type_of = {}
Esempio n. 10
0
class __extend__(pairtype(SomeDict, SomeDict)):
    def union((dic1, dic2)):
        return SomeDict(dic1.dictdef.union(dic2.dictdef))
Esempio n. 11
0
class __extend__(pairtype(SomeLongFloat, SomeLongFloat)):
    def union((flt1, flt2)):
        return SomeLongFloat()
Esempio n. 12
0
class __extend__(pairtype(SomeString, SomeObject)):
    def mod((str, args)):
        getbookkeeper().count('strformat', str, args)
        return SomeString()
Esempio n. 13
0
class __extend__(pairtype(SomeString, SomeUnicodeString),
                 pairtype(SomeUnicodeString, SomeString)):
    def mod((str, unistring)):
        raise NotImplementedError(
            "string formatting mixing strings and unicode not supported")
Esempio n. 14
0
                            resulttype = r_ins2.lowleveltype)
            return v
        else:
            return NotImplemented

    def rtype_is_((r_ins1, r_ins2), hop):
        if r_ins1.gcflavor != r_ins2.gcflavor:
            # obscure logic, the is can be true only if both are None
            v_ins1, v_ins2 = hop.inputargs(r_ins1.common_repr(), r_ins2.common_repr())
            return hop.gendirectcall(ll_both_none, v_ins1, v_ins2)
        if r_ins1.classdef is None or r_ins2.classdef is None:
            basedef = None
        else:
            basedef = r_ins1.classdef.commonbase(r_ins2.classdef)
        r_ins = getinstancerepr(r_ins1.rtyper, basedef, r_ins1.gcflavor)
        return pairtype(Repr, Repr).rtype_is_(pair(r_ins, r_ins), hop)

    rtype_eq = rtype_is_

    def rtype_ne(rpair, hop):
        v = rpair.rtype_eq(hop)
        return hop.genop("bool_not", [v], resulttype=Bool)

# ____________________________________________________________
#
#  Low-level implementation of operations on classes and instances

# doesn't work for non-gc stuff!
def ll_cast_to_object(obj):
    return cast_pointer(OBJECTPTR, obj)
Esempio n. 15
0
#  after converting all other arguments to PyObjRepr as well.  This
#  basically defers the operations to the care of the code generator.

def make_operation(opname, cls=PyObjRepr):
    def rtype_op(_, hop):
        vlist = hop.inputargs(*([pyobj_repr]*hop.nb_args))
        hop.exception_is_here()
        v = hop.genop(opname, vlist, resulttype=pyobj_repr)
        if not isinstance(hop.r_result, VoidRepr):
            return hop.llops.convertvar(v, pyobj_repr, hop.r_result)

    funcname = 'rtype_' + opname
    func = func_with_new_name(rtype_op, funcname)
    assert funcname not in cls.__dict__  # can be in Repr; overridden then.
    setattr(cls, funcname, func)


for opname in annmodel.UNARY_OPERATIONS:
    make_operation(opname)

for opname in annmodel.BINARY_OPERATIONS:
    make_operation(opname, pairtype(PyObjRepr, Repr))
    make_operation(opname, pairtype(Repr, PyObjRepr))

    
class __extend__(pairtype(PyObjRepr, PyObjRepr)): 
    def rtype_contains((r_seq, r_item), hop):
        v_seq, v_item = hop.inputargs(r_seq, r_item)
        return hop.llops.gencapicall('PySequence_Contains_with_exc',
                                     [v_seq, v_item], resulttype=Bool)
Esempio n. 16
0
# ____________________________________________________________


def make_missing_op(rcls, opname):
    attr = 'rtype_' + opname
    if not hasattr(rcls, attr):
        def missing_rtype_operation(self, hop):
            raise MissingRTypeOperation("unimplemented operation: "
                                        "'%s' on %r" % (opname, self))
        setattr(rcls, attr, missing_rtype_operation)

for opname in annmodel.UNARY_OPERATIONS:
    make_missing_op(Repr, opname)

for opname in annmodel.BINARY_OPERATIONS:
    make_missing_op(pairtype(Repr, Repr), opname)

# not in BINARY_OPERATIONS
make_missing_op(pairtype(Repr, Repr), 'contains')

class __extend__(pairtype(Repr, Repr)):
    def convert_from_to((r_from, r_to), v, llops):
        return NotImplemented

# ____________________________________________________________
# Primitive Repr classes, in the same hierarchical order as
# the corresponding SomeObjects

class FloatRepr(Repr):
    lowleveltype = Float
Esempio n. 17
0
class __extend__(pairtype(AddressRepr, AddressRepr)):
    def rtype_sub((r_addr1, r_addr2), hop):
        v_addr1, v_addr2 = hop.inputargs(Address, Address)
        return hop.genop('adr_delta', [v_addr1, v_addr2],
                         resulttype=lltype.Signed)
Esempio n. 18
0
class __extend__(pairtype(SomeInteger, SomeString),
                 pairtype(SomeInteger, SomeUnicodeString)):
    def mul((int1, str2)):  # xxx do we want to support this
        getbookkeeper().count("str_mul", str2, int1)
        return str2.basestringclass()
Esempio n. 19
0
    if isinstance(r_array1.lowleveltype, Primitive):
        r_array1, v_array1 = convert_scalar_to_array(r_array1, v_array1, hop.llops)
    elif isinstance(r_array1, AbstractBaseListRepr):
        r_array1, v_array1 = convert_list_to_array(r_array1, v_array1, hop.llops)
    elif not isinstance(r_array1, ArrayRepr):
        raise TyperError("can't operate with %s"%r_array1)

    if isinstance(r_array2.lowleveltype, Primitive):
        r_array2, v_array2 = convert_scalar_to_array(r_array2, v_array2, hop.llops)
    elif isinstance(r_array2, AbstractBaseListRepr):
        r_array2, v_array2 = convert_list_to_array(r_array2, v_array2, hop.llops)
    elif not isinstance(r_array2, ArrayRepr):
        raise TyperError("can't operate with %s"%r_array2)
    return _rtype_binop(r_array0, r_array1, r_array2, v_array1, v_array2, hop, binop)

for tp in (pairtype(ArrayRepr, ArrayRepr),
           pairtype(ArrayRepr, Repr),
           pairtype(Repr, ArrayRepr)):
    for (binop, methname) in ((lambda a,b:a+b, "rtype_add"),
                              (lambda a,b:a-b, "rtype_sub"),
                              (lambda a,b:a*b, "rtype_mul"),
                              (lambda a,b:a/b, "rtype_div")):
        setattr(tp, methname, lambda self, hop, binop=binop : rtype_binop(self, hop, binop))

#______________________________________________________________________________

def ll_array_inplace_binop(ITEM, it0, it1, binop):
    ll_assert(it0.size == it1.size, "it0.size == it1.size")
    while it0.index < it0.size:
        it0.dataptr[0] = cast_primitive(ITEM, binop(it0.dataptr[0], it1.dataptr[0]))
        it0.ll_next()
Esempio n. 20
0
class __extend__(pairtype(SomeInteger, SomeList)):
    def mul((int1, lst2)):
        return lst2.listdef.offspring()
Esempio n. 21
0
class __extend__(pairtype(AbstractRangeRepr, ArrayRepr)):
    def convert_from_to((r_rng, r_array), v, llops):
        cARRAY = inputconst(lltype.Void, r_array.lowleveltype.TO)
        return llops.gendirectcall(ll_build_from_list, cARRAY, v)
Esempio n. 22
0
class __extend__(pairtype(SomeIterator, SomeIterator)):
    def union((iter1, iter2)):
        s_cont = unioncheck(iter1.s_container, iter2.s_container)
        if iter1.variant != iter2.variant:
            raise UnionError("merging incompatible iterators variants")
        return SomeIterator(s_cont, *iter1.variant)
Esempio n. 23
0
 class __extend__(pairtype(MiniPickler, int)):
     def write((pickler, x)):
         pickler.emit('I%d' % x)
Esempio n. 24
0
class __extend__(pairtype(SomePBC, SomeGenericCallable)):
    def union((pbc, gencall)):
        return pair(gencall, pbc).union()
Esempio n. 25
0
 class __extend__(pairtype(MiniPickler, list)):
     def write((pickler, x)):
         for item in x:
             pair(pickler, item).write()
         pickler.emit('L%d' % len(x))
Esempio n. 26
0
class __extend__(pairtype(SomeImpossibleValue, SomeObject)):
    def union((imp1, obj2)):
        return obj2
Esempio n. 27
0
 class __extend__(pairtype(C_Generator, Block)):
     def emit((gen, block), inputvars):
         gen.lines.append("C code for block")
         outputvars = inputvars + ['v4', 'v5']
         pair(gen, block.exit).emit(outputvars)
Esempio n. 28
0
class __extend__(pairtype(SomeObject, SomeImpossibleValue)):
    def union((obj1, imp2)):
        return obj1
Esempio n. 29
0
 class __extend__(pairtype(C_Generator, Switch)):
     def emit((gen, jump), inputvars):
         gen.lines.append("switch (%s) { ... }" % inputvars[-1])
Esempio n. 30
0
class __extend__(pairtype(SomeObject, SomeObject)):
    def union((obj1, obj2)):
        if obj1 == obj2:
            return obj1
        else:
            result = SomeObject()
            if obj1.knowntype == obj2.knowntype and obj1.knowntype != object:
                result.knowntype = obj1.knowntype
            is_type_of1 = getattr(obj1, 'is_type_of', None)
            is_type_of2 = getattr(obj2, 'is_type_of', None)
            if obj1.is_immutable_constant() and obj2.is_immutable_constant(
            ) and obj1.const == obj2.const:
                result.const = obj1.const
                is_type_of = {}
                if is_type_of1:
                    for v in is_type_of1:
                        is_type_of[v] = True
                if is_type_of2:
                    for v in is_type_of2:
                        is_type_of[v] = True
                if is_type_of:
                    result.is_type_of = is_type_of.keys()
            else:
                if is_type_of1 and is_type_of1 == is_type_of2:
                    result.is_type_of = is_type_of1
            # try to preserve the origin of SomeObjects
            if obj1 == result:
                result = obj1
            elif obj2 == result:
                result = obj2
            unioncheck(result)
            return result

    # inplace_xxx ---> xxx by default
    def inplace_add((obj1, obj2)):
        return pair(obj1, obj2).add()

    def inplace_sub((obj1, obj2)):
        return pair(obj1, obj2).sub()

    def inplace_mul((obj1, obj2)):
        return pair(obj1, obj2).mul()

    def inplace_truediv((obj1, obj2)):
        return pair(obj1, obj2).truediv()

    def inplace_floordiv((obj1, obj2)):
        return pair(obj1, obj2).floordiv()

    def inplace_div((obj1, obj2)):
        return pair(obj1, obj2).div()

    def inplace_mod((obj1, obj2)):
        return pair(obj1, obj2).mod()

    def inplace_pow((obj1, obj2)):
        return pair(obj1, obj2).pow(s_None)

    def inplace_lshift((obj1, obj2)):
        return pair(obj1, obj2).lshift()

    def inplace_rshift((obj1, obj2)):
        return pair(obj1, obj2).rshift()

    def inplace_and((obj1, obj2)):
        return pair(obj1, obj2).and_()

    def inplace_or((obj1, obj2)):
        return pair(obj1, obj2).or_()

    def inplace_xor((obj1, obj2)):
        return pair(obj1, obj2).xor()

    for name, func in locals().items():
        if name.startswith('inplace_'):
            func.can_only_throw = []

    inplace_div.can_only_throw = [ZeroDivisionError]
    inplace_truediv.can_only_throw = [ZeroDivisionError]
    inplace_floordiv.can_only_throw = [ZeroDivisionError]
    inplace_mod.can_only_throw = [ZeroDivisionError]

    def lt((obj1, obj2)):
        if obj1.is_immutable_constant() and obj2.is_immutable_constant():
            return immutablevalue(obj1.const < obj2.const)
        else:
            getbookkeeper().count("non_int_comp", obj1, obj2)
            return s_Bool

    def le((obj1, obj2)):
        if obj1.is_immutable_constant() and obj2.is_immutable_constant():
            return immutablevalue(obj1.const <= obj2.const)
        else:
            getbookkeeper().count("non_int_comp", obj1, obj2)
            return s_Bool

    def eq((obj1, obj2)):
        if obj1.is_immutable_constant() and obj2.is_immutable_constant():
            return immutablevalue(obj1.const == obj2.const)
        else:
            getbookkeeper().count("non_int_eq", obj1, obj2)
            return s_Bool

    def ne((obj1, obj2)):
        if obj1.is_immutable_constant() and obj2.is_immutable_constant():
            return immutablevalue(obj1.const != obj2.const)
        else:
            getbookkeeper().count("non_int_eq", obj1, obj2)
            return s_Bool

    def gt((obj1, obj2)):
        if obj1.is_immutable_constant() and obj2.is_immutable_constant():
            return immutablevalue(obj1.const > obj2.const)
        else:
            getbookkeeper().count("non_int_comp", obj1, obj2)
            return s_Bool

    def ge((obj1, obj2)):
        if obj1.is_immutable_constant() and obj2.is_immutable_constant():
            return immutablevalue(obj1.const >= obj2.const)
        else:
            getbookkeeper().count("non_int_comp", obj1, obj2)
            return s_Bool

    def cmp((obj1, obj2)):
        getbookkeeper().count("cmp", obj1, obj2)
        if obj1.is_immutable_constant() and obj2.is_immutable_constant():
            return immutablevalue(cmp(obj1.const, obj2.const))
        else:
            return SomeInteger()

    def is_((obj1, obj2)):
        r = SomeBool()
        if obj2.is_constant():
            if obj1.is_constant():
                r.const = obj1.const is obj2.const
            if obj2.const is None and not obj1.can_be_none():
                r.const = False
        elif obj1.is_constant():
            if obj1.const is None and not obj2.can_be_none():
                r.const = False
        # XXX HACK HACK HACK
        # XXX HACK HACK HACK
        # XXX HACK HACK HACK
        bk = getbookkeeper()
        if bk is not None:  # for testing
            knowntypedata = r.knowntypedata = {}
            fn, block, i = bk.position_key

            annotator = bk.annotator
            op = block.operations[i]
            assert op.opname == "is_"
            assert len(op.args) == 2

            def bind(src_obj, tgt_obj, tgt_arg):
                if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant():
                    add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of,
                                      bk.valueoftype(src_obj.const))

                assert annotator.binding(op.args[tgt_arg]) == tgt_obj
                add_knowntypedata(knowntypedata, True, [op.args[tgt_arg]],
                                  src_obj)

                nonnone_obj = tgt_obj
                if src_obj.is_constant(
                ) and src_obj.const is None and tgt_obj.can_be_none():
                    nonnone_obj = tgt_obj.nonnoneify()

                add_knowntypedata(knowntypedata, False, [op.args[tgt_arg]],
                                  nonnone_obj)

            bind(obj2, obj1, 0)
            bind(obj1, obj2, 1)

        return r

    def divmod((obj1, obj2)):
        getbookkeeper().count("divmod", obj1, obj2)
        return SomeTuple([pair(obj1, obj2).div(), pair(obj1, obj2).mod()])

    def coerce((obj1, obj2)):
        getbookkeeper().count("coerce", obj1, obj2)
        return pair(obj1, obj2).union()  # reasonable enough

    # approximation of an annotation intersection, the result should be the annotation obj or
    # the intersection of obj and improvement
    def improve((obj, improvement)):
        if not improvement.contains(obj) and obj.contains(improvement):
            return improvement
        else:
            return obj

    # checked getitems

    def _getitem_can_only_throw(s_c1, s_o2):
        impl = pair(s_c1, s_o2).getitem
        return read_can_only_throw(impl, s_c1, s_o2)

    def getitem_idx_key((s_c1, s_o2)):
        impl = pair(s_c1, s_o2).getitem
        return impl()

    getitem_idx_key.can_only_throw = _getitem_can_only_throw

    getitem_idx = getitem_idx_key
    getitem_key = getitem_idx_key
Esempio n. 31
0
class __extend__(pairtype(StatResultRepr, IntegerRepr)):
    def rtype_getitem((r_sta, r_int), hop):
        s_int = hop.args_s[1]
        index = s_int.const
        return r_sta.redispatch_getfield(hop, index)
Esempio n. 32
0
class __extend__(pairtype(SomeString, SomePBC)):
    def add((o, pbc)):
        if not pbc.isNone():
            raise AnnotatorError('add on %r' % pbc)
        return s_ImpossibleValue
Esempio n. 33
0
class __extend__(pairtype(BoolRepr, PyObjRepr)):
    def convert_from_to((r_from, r_to), v, llops):
        if r_from.lowleveltype == Bool:
            return llops.gencapicall('PyBool_FromLong', [v],
                                     resulttype=pyobj_repr)
        return NotImplemented
Esempio n. 34
0
class __extend__(pairtype(SomeExternalObject, SomeExternalObject)):
    def union((ext1, ext2)):
        if ext1.knowntype == ext2.knowntype:
            return SomeExternalObject(ext1.knowntype)
        return SomeObject()
Esempio n. 35
0
class __extend__(pairtype(PtrRepr, AddressRepr)):
    def convert_from_to((r_ptr, r_addr), v, llops):
        return llops.genop('cast_ptr_to_adr', [v], resulttype=Address)
Esempio n. 36
0
class __extend__(pairtype(SomePtr, SomePtr)):
    def union((p1, p2)):
        assert p1.ll_ptrtype == p2.ll_ptrtype, (
            "mixing of incompatible pointer types: %r, %r" %
            (p1.ll_ptrtype, p2.ll_ptrtype))
        return SomePtr(p1.ll_ptrtype)
Esempio n. 37
0
    elif not isinstance(r_array1, ArrayRepr):
        raise TyperError("can't operate with %s" % r_array1)

    if isinstance(r_array2.lowleveltype, Primitive):
        r_array2, v_array2 = convert_scalar_to_array(r_array2, v_array2,
                                                     hop.llops)
    elif isinstance(r_array2, AbstractBaseListRepr):
        r_array2, v_array2 = convert_list_to_array(r_array2, v_array2,
                                                   hop.llops)
    elif not isinstance(r_array2, ArrayRepr):
        raise TyperError("can't operate with %s" % r_array2)
    return _rtype_binop(r_array0, r_array1, r_array2, v_array1, v_array2, hop,
                        binop)


for tp in (pairtype(ArrayRepr,
                    ArrayRepr), pairtype(ArrayRepr,
                                         Repr), pairtype(Repr, ArrayRepr)):
    for (binop, methname) in ((lambda a, b: a + b,
                               "rtype_add"), (lambda a, b: a - b, "rtype_sub"),
                              (lambda a, b: a * b, "rtype_mul"),
                              (lambda a, b: a / b, "rtype_div")):
        setattr(tp,
                methname,
                lambda self, hop, binop=binop: rtype_binop(self, hop, binop))

#______________________________________________________________________________


def ll_array_inplace_binop(ITEM, it0, it1, binop):
    ll_assert(it0.size == it1.size, "it0.size == it1.size")
    while it0.index < it0.size:
Esempio n. 38
0
    d = newset(hs_c1.origins, hs_c2.origins, {origin: True})
    RESTYPE = bk.current_op_concretetype()
    hs_res = SomeLLAbstractConstant(RESTYPE, d,
                                    eager_concrete = hs_c1.eager_concrete or
                                                     hs_c2.eager_concrete,
                                    myorigin = origin)
    if hs_c1.is_constant() and hs_c2.is_constant():
        try:
            hs_res.const = llop(RESTYPE, hs_c1.const, hs_c2.const)
        except Exception:   # XXX not too nice
            pass
    return hs_res

def setup(oplist, ValueCls, var_fn, ConstantCls, const_fn):
    for name in oplist:
        llop = getattr(lloperation.llop, name)
        if not llop.sideeffects or llop.tryfold:
            if name not in ValueCls.__dict__:
                setattr(ValueCls, name, var_fn)
            if llop.canfold or llop.tryfold:
                if name not in ConstantCls.__dict__:
                    setattr(ConstantCls, name,
                            lambda s, llop=llop: const_fn(llop, s))
setup(UNARY_OPERATIONS,
      SomeLLAbstractValue, var_unary,
      SomeLLAbstractConstant, const_unary)
setup(BINARY_OPERATIONS,
      pairtype(SomeLLAbstractValue, SomeLLAbstractValue), var_binary,
      pairtype(SomeLLAbstractConstant, SomeLLAbstractConstant), const_binary)
del setup