Exemple #1
0
    def rtype_method_join(self, hop):
        hop.exception_cannot_occur()
        rstr = hop.args_r[0]
        if hop.s_result.is_constant():
            return inputconst(rstr.repr, hop.s_result.const)
        r_lst = hop.args_r[1]
        if not isinstance(r_lst, hop.rtyper.type_system.rlist.BaseListRepr):
            raise TyperError("string.join of non-list: %r" % r_lst)
        v_str, v_lst = hop.inputargs(rstr.repr, r_lst)
        v_length, v_items = self._list_length_items(hop, v_lst,
                                                    r_lst.lowleveltype)

        if hop.args_s[0].is_constant() and hop.args_s[0].const == '':
            if r_lst.item_repr == rstr.repr:
                llfn = self.ll.ll_join_strs
            elif (r_lst.item_repr == hop.rtyper.type_system.rstr.char_repr or
                  r_lst.item_repr == hop.rtyper.type_system.rstr.unichar_repr):
                v_tp = hop.inputconst(Void, self.lowleveltype)
                return hop.gendirectcall(self.ll.ll_join_chars, v_length,
                                         v_items, v_tp)
            else:
                raise TyperError("''.join() of non-string list: %r" % r_lst)
            return hop.gendirectcall(llfn, v_length, v_items)
        else:
            if r_lst.item_repr == rstr.repr:
                llfn = self.ll.ll_join
            else:
                raise TyperError("sep.join() of non-string list: %r" % r_lst)
            return hop.gendirectcall(llfn, v_str, v_length, v_items)
Exemple #2
0
    def __init__(self, rtyper, s_pbc):
        self.rtyper = rtyper
        self.s_pbc = s_pbc
        if s_pbc.isNone():
            raise TyperError("unsupported: variable of type "
                             "bound-method-object or None")
        mdescs = s_pbc.descriptions.keys()
        methodname = mdescs[0].name
        classdef = mdescs[0].selfclassdef
        flags = mdescs[0].flags
        for mdesc in mdescs[1:]:
            if mdesc.name != methodname:
                raise TyperError("cannot find a unique name under which the "
                                 "methods can be found: %r" % (mdescs, ))
            if mdesc.flags != flags:
                raise TyperError("inconsistent 'flags': %r versus %r" %
                                 (mdesc.flags, flags))
            classdef = classdef.commonbase(mdesc.selfclassdef)
            if classdef is None:
                raise TyperError("mixing methods coming from instances of "
                                 "classes with no common base: %r" %
                                 (mdescs, ))

        self.methodname = methodname
        self.classdef = classdef.locate_attribute(methodname)
        # the low-level representation is just the bound 'self' argument.
        self.s_im_self = annmodel.SomeInstance(self.classdef, flags=flags)
        self.r_im_self = rclass.getinstancerepr(rtyper, self.classdef)
        self.lowleveltype = self.r_im_self.lowleveltype
Exemple #3
0
def call_args_expand(hop, takes_kwds = True):
    hop = hop.copy()
    from pypy.interpreter.argument import Arguments
    arguments = Arguments.fromshape(None, hop.args_s[1].const, # shape
                                    range(hop.nb_args-2))
    if arguments.w_starstararg is not None:
        raise TyperError("**kwds call not implemented")
    if arguments.w_stararg is not None:
        # expand the *arg in-place -- it must be a tuple
        from pypy.rpython.rtuple import AbstractTupleRepr
        if arguments.w_stararg != hop.nb_args - 3:
            raise TyperError("call pattern too complex")
        hop.nb_args -= 1
        v_tuple = hop.args_v.pop()
        s_tuple = hop.args_s.pop()
        r_tuple = hop.args_r.pop()
        if not isinstance(r_tuple, AbstractTupleRepr):
            raise TyperError("*arg must be a tuple")
        for i in range(len(r_tuple.items_r)):
            v_item = r_tuple.getitem_internal(hop.llops, v_tuple, i)
            hop.nb_args += 1
            hop.args_v.append(v_item)
            hop.args_s.append(s_tuple.items[i])
            hop.args_r.append(r_tuple.items_r[i])

    kwds = arguments.kwds_w or {}
    if not takes_kwds and kwds:
        raise TyperError("kwds args not supported")
    # prefix keyword arguments with 'i_'
    kwds_i = {}
    for key, index in kwds.items():
        kwds_i['i_'+key] = index

    return hop, kwds_i
Exemple #4
0
 def rtype_method_find(self, hop, reverse=False):
     # XXX binaryop
     string_repr = hop.args_r[0].repr
     char_repr = hop.args_r[0].char_repr
     v_str = hop.inputarg(string_repr, arg=0)
     if hop.args_r[1] == char_repr:
         v_value = hop.inputarg(char_repr, arg=1)
         llfn = reverse and self.ll.ll_rfind_char or self.ll.ll_find_char
     else:
         v_value = hop.inputarg(string_repr, arg=1)
         llfn = reverse and self.ll.ll_rfind or self.ll.ll_find
     if hop.nb_args > 2:
         v_start = hop.inputarg(Signed, arg=2)
         if not hop.args_s[2].nonneg:
             raise TyperError(
                 "str.find() start must be proven non-negative")
     else:
         v_start = hop.inputconst(Signed, 0)
     if hop.nb_args > 3:
         v_end = hop.inputarg(Signed, arg=3)
         if not hop.args_s[3].nonneg:
             raise TyperError("str.find() end must be proven non-negative")
     else:
         v_end = hop.gendirectcall(self.ll.ll_strlen, v_str)
     hop.exception_cannot_occur()
     return hop.gendirectcall(llfn, v_str, v_value, v_start, v_end)
Exemple #5
0
def rtypedelegate(callable, hop, revealargs=[0], revealresult=False):
    bk = hop.rtyper.annotator.bookkeeper
    c_meth = Constant(callable)
    s_meth = bk.immutablevalue(callable)
    hop2 = hop.copy()
    for index in revealargs:
        r_controlled = hop2.args_r[index]
        if not isinstance(r_controlled, ControlledInstanceRepr):
            raise TyperError(
                "args_r[%d] = %r, expected ControlledInstanceRepr" %
                (index, r_controlled))
        s_new, r_new = r_controlled.s_real_obj, r_controlled.r_real_obj
        hop2.args_s[index], hop2.args_r[index] = s_new, r_new
        v = hop2.args_v[index]
        if isinstance(v, Constant):
            real_value = r_controlled.controller.convert(v.value)
            hop2.args_v[index] = Constant(real_value)
    if revealresult:
        r_controlled = hop2.r_result
        if not isinstance(r_controlled, ControlledInstanceRepr):
            raise TyperError("r_result = %r, expected ControlledInstanceRepr" %
                             (r_controlled, ))
        s_new, r_new = r_controlled.s_real_obj, r_controlled.r_real_obj
        hop2.s_result, hop2.r_result = s_new, r_new
    hop2.v_s_insertfirstarg(c_meth, s_meth)
    hop2.forced_opname = 'simple_call'
    return hop2.dispatch()
Exemple #6
0
 def rtype_getattr(self, hop):
     s_attr = hop.args_s[1]
     if s_attr.is_constant() and isinstance(s_attr.const, str):
         attr = s_attr.const
         s_obj = hop.args_s[0]
         if s_obj.find_method(attr) is None:
             raise TyperError("no method %s on %r" % (attr, s_obj))
         else:
             # implement methods (of a known name) as just their 'self'
             return hop.inputarg(self, arg=0)
     else:
         raise TyperError("getattr() with a non-constant attribute name")
Exemple #7
0
 def rtype_method_decode(self, hop):
     if not hop.args_s[1].is_constant():
         raise TyperError("encoding must be a constant")
     encoding = hop.args_s[1].const
     v_self = hop.inputarg(self.repr, 0)
     hop.exception_is_here()
     if encoding == 'ascii':
         return hop.gendirectcall(self.ll.ll_str2unicode, v_self)
     elif encoding == 'latin-1':
         return hop.gendirectcall(self.ll_decode_latin1, v_self)
     else:
         raise TyperError("encoding %s not implemented" % (encoding, ))
Exemple #8
0
def rtype_r_dict(hop):
    r_dict = hop.r_result
    if not r_dict.custom_eq_hash:
        raise TyperError("r_dict() call does not return an r_dict instance")
    cDICT = hop.inputconst(ootype.Void, r_dict.DICT)
    hop.exception_cannot_occur()

    # the signature of oonewcustomdict is a bit complicated because we
    # can have three different ways to pass the equal (and hash)
    # callables:
    #   1. pass a plain function: v_eqfn is a StaticMethod, v_eqobj
    #      and c_eq_method_name are None
    #   2. pass a bound method: v_eqfn is None, v_eqobj is the
    #      instance, c_method_name is the name of the method,
    #   3. pass a method of a frozen PBC: v_eqfn is a StaticMethod,
    #      v_eqobj is the PBC to be pushed in front of the StaticMethod,
    #      c_eq_method_name is None

    s_key = r_dict.dictkey.s_value
    v_eqfn, v_eqobj, c_eq_method_name =\
             _get_call_vars(hop, r_dict.r_rdict_eqfn, 0, [s_key, s_key])
    v_hashfn, v_hashobj, c_hash_method_name =\
               _get_call_vars(hop, r_dict.r_rdict_hashfn, 1, [s_key])

    return hop.genop("oonewcustomdict", [
        cDICT, v_eqfn, v_eqobj, c_eq_method_name, v_hashfn, v_hashobj,
        c_hash_method_name
    ],
                     resulttype=hop.r_result.lowleveltype)
Exemple #9
0
def rtype_builtin_range(hop):
    vstep = hop.inputconst(Signed, 1)
    if hop.nb_args == 1:
        vstart = hop.inputconst(Signed, 0)
        vstop, = hop.inputargs(Signed)
    elif hop.nb_args == 2:
        vstart, vstop = hop.inputargs(Signed, Signed)
    else:
        vstart, vstop, vstep = hop.inputargs(Signed, Signed, Signed)
        if isinstance(vstep, Constant) and vstep.value == 0:
            # not really needed, annotator catches it. Just in case...
            raise TyperError("range cannot have a const step of zero")
    if isinstance(hop.r_result, AbstractRangeRepr):
        if hop.r_result.step != 0:
            c_rng = hop.inputconst(Void, hop.r_result.RANGE)
            hop.exception_is_here()
            return hop.gendirectcall(hop.r_result.ll_newrange, c_rng, vstart,
                                     vstop)
        else:
            hop.exception_is_here()
            return hop.gendirectcall(hop.r_result.ll_newrangest, vstart, vstop,
                                     vstep)
    else:
        # cannot build a RANGE object, needs a real list
        r_list = hop.r_result
        ITEMTYPE = r_list.lowleveltype
        if isinstance(ITEMTYPE, Ptr):
            ITEMTYPE = ITEMTYPE.TO
        cLIST = hop.inputconst(Void, ITEMTYPE)
        hop.exception_is_here()
        return hop.gendirectcall(ll_range2list, cLIST, vstart, vstop, vstep)
Exemple #10
0
def merge_classpbc_getattr_into_classdef(rtyper):
    # code like 'some_class.attr' will record an attribute access in the
    # PBC access set of the family of classes of 'some_class'.  If the classes
    # have corresponding ClassDefs, they are not updated by the annotator.
    # We have to do it now.
    all_families = rtyper.annotator.bookkeeper.classpbc_attr_families
    for attrname, access_sets in all_families.items():
        for access_set in access_sets.infos():
            descs = access_set.descs
            if len(descs) <= 1:
                continue
            if not isinstance(descs.iterkeys().next(), description.ClassDesc):
                continue
            classdefs = [desc.getuniqueclassdef() for desc in descs]
            commonbase = classdefs[0]
            for cdef in classdefs[1:]:
                commonbase = commonbase.commonbase(cdef)
                if commonbase is None:
                    raise TyperError("reading attribute %r: no common base "
                                     "class for %r" % (attrname, descs.keys()))
            extra_access_sets = rtyper.class_pbc_attributes.setdefault(
                commonbase, {})
            if commonbase in rtyper.class_reprs:
                assert access_set in extra_access_sets # minimal sanity check
                continue
            access_set.commonbase = commonbase
            if access_set not in extra_access_sets:
                counter = len(extra_access_sets)
                extra_access_sets[access_set] = attrname, counter
Exemple #11
0
def rtype_r_dict(hop):
    from pypy.rlib import jit

    r_dict = hop.r_result
    if not r_dict.custom_eq_hash:
        raise TyperError("r_dict() call does not return an r_dict instance")
    cDICT = hop.inputconst(ootype.Void, r_dict.DICT)
    hop.exception_cannot_occur()

    # the signature of oonewcustomdict is a bit complicated because we
    # can have three different ways to pass the equal (and hash)
    # callables:
    #   1. pass a plain function: eqfn is a StaticMethod, v_eqobj
    #      and eq_method_name are None
    #   2. pass a bound method: eqfn is None, v_eqobj is the
    #      instance, eq_method_name is the name of the method,
    #   3. pass a method of a frozen PBC: eqfn is a StaticMethod, v_eqobj is a
    #      non-None Void value (to be ignored by all the backends except the
    #      llinterp), eq_method_name is None

    s_key = r_dict.dictkey.s_value
    eqfn, v_eqobj, eq_method_name =\
             _get_call_args(hop, r_dict.r_rdict_eqfn, 0, [s_key, s_key])
    hashfn, v_hashobj, hash_method_name =\
               _get_call_args(hop, r_dict.r_rdict_hashfn, 1, [s_key])

    @jit.dont_look_inside
    def ll_newcustomdict(DICT, v_eqobj, v_hashobj):
        from pypy.rpython.lltypesystem.lloperation import llop
        return llop.oonewcustomdict(DICT, DICT, eqfn, v_eqobj, eq_method_name,
                                    hashfn, v_hashobj, hash_method_name)

    ll_newcustomdict._dont_inline_ = True

    return hop.gendirectcall(ll_newcustomdict, cDICT, v_eqobj, v_hashobj)
Exemple #12
0
def buildinstancerepr(rtyper, classdef, gcflavor='gc'):
    if classdef is None:
        unboxed = []
        virtualizable = False
    else:
        unboxed = [subdef for subdef in classdef.getallsubdefs()
                          if subdef.classdesc.pyobj is not None and
                             issubclass(subdef.classdesc.pyobj, UnboxedValue)]
        virtualizable = classdef.classdesc.read_attribute('_virtualizable_',
                                                          Constant(False)).value
    if virtualizable:
        assert len(unboxed) == 0
        assert gcflavor == 'gc'
        from pypy.rpython.lltypesystem import rvirtualizable
        return rvirtualizable.VirtualizableInstanceRepr(rtyper, classdef)
    elif len(unboxed) == 0:
        return InstanceRepr(rtyper, classdef, gcflavor)
    else:
        # the UnboxedValue class and its parent classes need a
        # special repr for their instances
        if len(unboxed) != 1:
            raise TyperError("%r has several UnboxedValue subclasses" % (
                classdef,))
        assert gcflavor == 'gc'
        from pypy.rpython.lltypesystem import rtagged
        return rtagged.TaggedInstanceRepr(rtyper, classdef, unboxed[0])
Exemple #13
0
 def convert_desc(self, funcdesc):
     # get the whole "column" of the call table corresponding to this desc
     try:
         return self.funccache[funcdesc]
     except KeyError:
         pass
     if self.lowleveltype is Void:
         result = None
     else:
         llfns = {}
         found_anything = False
         for row in self.uniquerows:
             if funcdesc in row:
                 llfn = row[funcdesc]
                 found_anything = True
             else:
                 # missing entry -- need a 'null' of the type that matches
                 # this row
                 llfn = self.rtyper.type_system.null_callable(row.fntype)
             llfns[row.attrname] = llfn
         if not found_anything:
             raise TyperError("%r not in %r" %
                              (funcdesc, self.s_pbc.descriptions))
         if len(self.uniquerows) == 1:
             result = llfn  # from the loop above
         else:
             # build a Struct with all the values collected in 'llfns'
             result = self.create_specfunc()
             for attrname, llfn in llfns.items():
                 setattr(result, attrname, llfn)
     self.funccache[funcdesc] = result
     return result
Exemple #14
0
 def specialize_call(self, hop):
     from pypy.rpython.rcontrollerentry import ControlledInstanceRepr
     if not isinstance(hop.r_result, ControlledInstanceRepr):
         raise TyperError("box() should return ControlledInstanceRepr,\n"
                          "got %r" % (hop.r_result,))
     hop.exception_cannot_occur()
     return hop.inputarg(hop.r_result.r_real_obj, arg=1)
Exemple #15
0
    def parse_fmt_string(fmt):
        # we support x, d, s, f, [r]
        it = iter(fmt)
        r = []
        curstr = ''
        for c in it:
            if c == '%':
                f = it.next()
                if f == '%':
                    curstr += '%'
                    continue

                if curstr:
                    r.append(curstr)
                curstr = ''
                if f not in 'xdosrf':
                    raise TyperError(
                        "Unsupported formatting specifier: %r in %r" %
                        (f, fmt))

                r.append((f, ))
            else:
                curstr += c
        if curstr:
            r.append(curstr)
        return r
Exemple #16
0
def rtype_hlinvoke(hop):
    _, s_repr = hop.r_s_popfirstarg()
    r_callable = s_repr.const

    r_func, nimplicitarg = r_callable.get_r_implfunc()
    s_callable = r_callable.get_s_callable()

    nbargs = len(hop.args_s) - 1 + nimplicitarg 
    s_sigs = r_func.get_s_signatures((nbargs, (), False, False))
    if len(s_sigs) != 1:
        raise TyperError("cannot hlinvoke callable %r with not uniform"
                         "annotations: %r" % (r_callable,
                                              s_sigs))
    args_s, s_ret = s_sigs[0]
    rinputs = [hop.rtyper.getrepr(s_obj) for s_obj in args_s]
    rresult = hop.rtyper.getrepr(s_ret)

    args_s = args_s[nimplicitarg:]
    rinputs = rinputs[nimplicitarg:]

    new_args_r = [r_callable] + rinputs

    for i in range(len(new_args_r)):
        assert hop.args_r[i].lowleveltype == new_args_r[i].lowleveltype

    hop.args_r = new_args_r
    hop.args_s = [s_callable] + args_s

    hop.s_result = s_ret
    assert hop.r_result.lowleveltype == rresult.lowleveltype
    hop.r_result = rresult

    return hop.dispatch()
Exemple #17
0
def buildinstancerepr(rtyper, classdef, gcflavor='gc'):
    from pypy.rlib.objectmodel import UnboxedValue
    from pypy.objspace.flow.model import Constant
    
    if classdef is None:
        unboxed = []
        virtualizable2 = False
    else:
        unboxed = [subdef for subdef in classdef.getallsubdefs()
                          if subdef.classdesc.pyobj is not None and
                             issubclass(subdef.classdesc.pyobj, UnboxedValue)]
        virtualizable2 = classdef.classdesc.read_attribute('_virtualizable2_',
                                                           Constant(False)).value
    config = rtyper.annotator.translator.config
    usetagging = len(unboxed) != 0 and config.translation.taggedpointers

    if virtualizable2:
        assert len(unboxed) == 0
        assert gcflavor == 'gc'
        return rtyper.type_system.rvirtualizable2.Virtualizable2InstanceRepr(rtyper, classdef)
    elif usetagging and rtyper.type_system.name == 'lltypesystem':
        # the UnboxedValue class and its parent classes need a
        # special repr for their instances
        if len(unboxed) != 1:
            raise TyperError("%r has several UnboxedValue subclasses" % (
                classdef,))
        assert gcflavor == 'gc'
        from pypy.rpython.lltypesystem import rtagged
        return rtagged.TaggedInstanceRepr(rtyper, classdef, unboxed[0])
    else:
        return rtyper.type_system.rclass.InstanceRepr(rtyper, classdef, gcflavor)
Exemple #18
0
 def rtype_method_encode(self, hop):
     if not hop.args_s[1].is_constant():
         raise TyperError("encoding must be constant")
     encoding = hop.args_s[1].const
     if encoding == "ascii" and self.lowleveltype == UniChar:
         expect = UniChar  # only for unichar.encode('ascii')
     else:
         expect = self.repr  # must be a regular unicode string
     v_self = hop.inputarg(expect, 0)
     hop.exception_is_here()
     if encoding == "ascii":
         return hop.gendirectcall(self.ll_str, v_self)
     elif encoding == "latin-1":
         return hop.gendirectcall(self.ll_encode_latin1, v_self)
     else:
         raise TyperError("encoding %s not implemented" % (encoding, ))
Exemple #19
0
def rtype_raw_free(hop):
    s_addr = hop.args_s[0]
    if s_addr.is_null_address():
        raise TyperError("raw_free(x) where x is the constant NULL")
    v_addr, = hop.inputargs(llmemory.Address)
    hop.exception_cannot_occur()
    return hop.genop('raw_free', [v_addr])
Exemple #20
0
def rtype_raw_memcopy(hop):
    for s_addr in hop.args_s[:2]:
        if s_addr.is_null_address():
            raise TyperError("raw_memcopy() with a constant NULL")
    v_list = hop.inputargs(llmemory.Address, llmemory.Address, lltype.Signed)
    hop.exception_cannot_occur()
    return hop.genop('raw_memcopy', v_list)
Exemple #21
0
def commonbase(classdefs):
    result = classdefs[0]
    for cdef in classdefs[1:]:
        result = result.commonbase(cdef)
        if result is None:
            raise TyperError("no common base class in %r" % (classdefs, ))
    return result
Exemple #22
0
 def getpbcfield(self, vcls, access_set, attr, llops):
     if (access_set, attr) not in self.pbcfields:
         raise TyperError("internal error: missing PBC field")
     mangled_name, r = self.pbcfields[access_set, attr]
     v_vtable = self.fromtypeptr(vcls, llops)
     cname = inputconst(Void, mangled_name)
     return llops.genop('getfield', [v_vtable, cname], resulttype=r)
Exemple #23
0
 def exception_cannot_occur(self):
     self.llops._called_exception_is_here_or_cannot_occur = True
     if self.llops.llop_raising_exceptions is not None:
         raise TyperError("cannot catch an exception at more than one llop")
     if not self.exceptionlinks:
         return  # ignored for high-level ops before the last one in the block
     self.llops.llop_raising_exceptions = "removed"
Exemple #24
0
class __extend__(pairtype(ArrayRepr, Repr)):
    def rtype_getitem((r_array, r_key), hop):

        v_array, v_key = hop.inputargs(r_array, r_key)
        if isinstance(r_key, IntegerRepr):
            r_tuple, v_tuple = convert_int_to_tuple(r_key, v_key, hop.llops)
        elif isinstance(r_key, AbstractSliceRepr):
            r_tuple, v_tuple = convert_slice_to_tuple(r_key, v_key, hop.llops)
        elif isinstance(r_key, TupleRepr):
            r_tuple, v_tuple = r_key, v_key
        else:
            raise TyperError("bad key: %s" % r_key)

        ndim = get_view_ndim(r_array, r_tuple)
        if ndim == 0:
            # return a scalar
            cARRAY = hop.inputconst(Void, r_array.ARRAY.TO)
            get_item, set_item = gen_getset_item(r_array.ndim)
            return hop.gendirectcall(get_item, cARRAY, v_array, v_tuple)
        r_result = hop.r_result
        ARRAY = r_result.ARRAY
        assert dim_of_ARRAY(ARRAY) == ndim
        cARRAY = hop.inputconst(Void, ARRAY.TO)
        ll_get_view = gen_get_view(r_array, r_tuple, hop)
        return hop.gendirectcall(ll_get_view, cARRAY, v_array, v_tuple)
Exemple #25
0
def rtype_raw_memclear(hop):
    s_addr = hop.args_s[0]
    if s_addr.is_null_address():
        raise TyperError("raw_memclear(x, n) where x is the constant NULL")
    v_list = hop.inputargs(llmemory.Address, lltype.Signed)
    hop.exception_cannot_occur()
    return hop.genop('raw_memclear', v_list)