예제 #1
0
    def rtyper_makerepr(self, rtyper):
        from rpython.rtyper.lltypesystem.rpbc import (FunctionsPBCRepr,
                                                      SmallFunctionSetPBCRepr)
        kind = self.getKind()
        if issubclass(kind, description.FunctionDesc):
            sample = self.any_description()
            callfamily = sample.querycallfamily()
            if callfamily and callfamily.total_calltable_size > 0:
                getRepr = FunctionsPBCRepr
                if small_cand(rtyper, self):
                    getRepr = SmallFunctionSetPBCRepr
            else:
                getRepr = getFrozenPBCRepr
        elif issubclass(kind, description.ClassDesc):
            # user classes
            getRepr = ClassesPBCRepr
        elif issubclass(kind, description.MethodDesc):
            getRepr = MethodsPBCRepr
        elif issubclass(kind, description.FrozenDesc):
            getRepr = getFrozenPBCRepr
        elif issubclass(kind, description.MethodOfFrozenDesc):
            getRepr = MethodOfFrozenPBCRepr
        else:
            raise TyperError("unexpected PBC kind %r" % (kind, ))

        return getRepr(rtyper, self)
예제 #2
0
파일: rbuiltin.py 프로젝트: Qointum/pypy
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)
예제 #3
0
파일: rbuiltin.py 프로젝트: Qointum/pypy
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)
예제 #4
0
파일: rrange.py 프로젝트: Mu-L/pypy
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)
예제 #5
0
파일: rtyper.py 프로젝트: zcxowwww/pypy
 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"
예제 #6
0
파일: rstr.py 프로젝트: sota/pypy-old
    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
예제 #7
0
파일: rbuiltin.py 프로젝트: soIu/rpython
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])
예제 #8
0
def _rtype_template(hop, func):
    """Write a simple operation implementing the given 'func'.
    It must be an operation that cannot raise.
    """
    r_result = hop.r_result
    if r_result.lowleveltype == Bool:
        repr = signed_repr
    else:
        repr = r_result
    if func.startswith(('lshift', 'rshift')):
        repr2 = signed_repr
    else:
        repr2 = repr
    vlist = hop.inputargs(repr, repr2)
    prefix = repr.opprefix

    if '_ovf' in func or func.startswith(('py_mod', 'py_div')):
        if prefix + func not in ('int_add_ovf', 'int_add_nonneg_ovf',
                                 'int_sub_ovf', 'int_mul_ovf'):
            raise TyperError("%r should not be used here any more" % (func, ))
        hop.has_implicit_exception(OverflowError)
        hop.exception_is_here()
    else:
        hop.exception_cannot_occur()

    v_res = hop.genop(prefix + func, vlist, resulttype=repr)
    v_res = hop.llops.convertvar(v_res, repr, r_result)
    return v_res
예제 #9
0
 def convert_const(self, value):
     if isinstance(value, objectmodel.Symbolic):
         return value
     T = typeOf(value)
     if isinstance(T, Number) or T is Bool:
         return cast_primitive(self.lowleveltype, value)
     raise TyperError("not an integer: %r" % (value, ))
예제 #10
0
def buildinstancerepr(rtyper, classdef, gcflavor='gc'):
    from rpython.rtyper.rvirtualizable import VirtualizableInstanceRepr

    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
    config = rtyper.annotator.translator.config
    usetagging = len(unboxed) != 0 and config.translation.taggedpointers

    if virtualizable:
        assert len(unboxed) == 0
        assert gcflavor == 'gc'
        return VirtualizableInstanceRepr(rtyper, classdef)
    elif usetagging:
        # 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 rpython.rtyper.lltypesystem import rtagged
        return rtagged.TaggedInstanceRepr(rtyper, classdef, unboxed[0])
    else:
        return InstanceRepr(rtyper, classdef, gcflavor)
예제 #11
0
 def convert_const(self, weakdict):
     if weakdict is None:
         return lltype.nullptr(self.WEAKDICT)
     if not isinstance(weakdict, RWeakValueDictionary):
         raise TyperError("expected an RWeakValueDictionary: %r" %
                          (weakdict, ))
     try:
         key = Constant(weakdict)
         return self.dict_cache[key]
     except KeyError:
         self.setup()
         l_dict = self.ll_new_weakdict()
         self.dict_cache[key] = l_dict
         bk = self.rtyper.annotator.bookkeeper
         classdef = bk.getuniqueclassdef(weakdict._valueclass)
         r_value = getinstancerepr(self.rtyper, classdef)
         any_value = False
         for dictkey, dictvalue in weakdict._dict.items():
             llkey = self.r_key.convert_const(dictkey)
             llvalue = r_value.convert_const(dictvalue)
             if llvalue:
                 llvalue = lltype.cast_pointer(rclass.OBJECTPTR, llvalue)
                 self.ll_set_nonnull(l_dict, llkey, llvalue)
                 any_value = True
         if any_value:
             l_dict.resize_counter = -1
         return l_dict
예제 #12
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)
예제 #13
0
파일: rclass.py 프로젝트: Qointum/pypy
 def _parse_field_list(self, fields, accessor, hints):
     ranking = {}
     for name in fields:
         quasi = False
         if name.endswith('?[*]'):  # a quasi-immutable field pointing to
             name = name[:-4]  # an immutable array
             rank = IR_QUASIIMMUTABLE_ARRAY
             quasi = True
         elif name.endswith('[*]'):  # for virtualizables' lists
             name = name[:-3]
             rank = IR_IMMUTABLE_ARRAY
         elif name.endswith('?'):  # a quasi-immutable field
             name = name[:-1]
             rank = IR_QUASIIMMUTABLE
             quasi = True
         else:  # a regular immutable/green field
             rank = IR_IMMUTABLE
         try:
             mangled_name, r = self._get_field(name)
         except KeyError:
             continue
         if quasi and hints.get("immutable"):
             raise TyperError(
                 "can't have _immutable_ = True and a quasi-immutable field "
                 "%s in class %s" % (name, self.classdef))
         ranking[mangled_name] = rank
     accessor.initialize(self.object_type, ranking)
     return ranking
예제 #14
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
예제 #15
0
    def rtyper_makerepr(self, rtyper):
        kind = self.getKind()
        if issubclass(kind, FunctionDesc):
            if len(self.descriptions) == 1 and not self.can_be_None:
                getRepr = FunctionRepr
            else:
                sample = self.any_description()
                callfamily = sample.querycallfamily()
                if callfamily and callfamily.total_calltable_size > 0:
                    getRepr = FunctionsPBCRepr
                    if small_cand(rtyper, self):
                        getRepr = SmallFunctionSetPBCRepr
                else:
                    getRepr = getFrozenPBCRepr
        elif issubclass(kind, ClassDesc):
            # user classes
            getRepr = ClassesPBCRepr
        elif issubclass(kind, MethodDesc):
            getRepr = MethodsPBCRepr
        elif issubclass(kind, FrozenDesc):
            getRepr = getFrozenPBCRepr
        elif issubclass(kind, MethodOfFrozenDesc):
            getRepr = MethodOfFrozenPBCRepr
        else:
            raise TyperError("unexpected PBC kind %r" % (kind,))

        return getRepr(rtyper, self)
예제 #16
0
파일: rdict.py 프로젝트: sota/pypy-old
def rtype_r_dict(hop, i_force_non_null=None):
    from rpython.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 rpython.rtyper.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)
예제 #17
0
 def specialize_call(self, hop):
     if not isinstance(hop.args_r[1], ControlledInstanceRepr):
         raise TyperError("unbox() should take a ControlledInstanceRepr,\n"
                          "got %r" % (hop.args_r[1], ))
     hop.exception_cannot_occur()
     v = hop.inputarg(hop.args_r[1], arg=1)
     return hop.llops.convertvar(v, hop.args_r[1].r_real_obj, hop.r_result)
예제 #18
0
def merge_classpbc_getattr_into_classdef(annotator):
    # 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 = 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 = commonbase.extra_access_sets
            if commonbase.repr is not None:
                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
예제 #19
0
파일: rbuiltin.py 프로젝트: soIu/rpython
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))
    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()
예제 #20
0
파일: rstr.py 프로젝트: sczfaker/pypy
 def rtype_method_replace(self, hop):
     rstr = hop.args_r[0].repr
     if not (hop.args_r[1] == rstr.char_repr and hop.args_r[2] == rstr.char_repr):
         raise TyperError('replace only works for char args')
     v_str, v_c1, v_c2 = hop.inputargs(rstr.repr, rstr.char_repr, rstr.char_repr)
     hop.exception_cannot_occur()
     return hop.gendirectcall(self.ll.ll_replace_chr_chr, v_str, v_c1, v_c2)
예제 #21
0
    def _setup_repr_final(self):
        self._setup_immutable_field_list()
        self._check_for_immutable_conflicts()
        if self.gcflavor == 'gc':
            if (self.classdef is not None
                    and self.classdef.classdesc.lookup('__del__') is not None):
                s_func = self.classdef.classdesc.s_read_attribute('__del__')
                source_desc = self.classdef.classdesc.lookup('__del__')
                source_classdef = source_desc.getclassdef(None)
                source_repr = getinstancerepr(self.rtyper, source_classdef)
                assert len(s_func.descriptions) == 1
                funcdesc, = s_func.descriptions
                graph = funcdesc.getuniquegraph()
                self.check_graph_of_del_does_not_call_too_much(
                    self.rtyper, graph)
                FUNCTYPE = FuncType([Ptr(source_repr.object_type)], Void)
                destrptr = functionptr(FUNCTYPE,
                                       graph.name,
                                       graph=graph,
                                       _callable=graph.func)
            else:
                destrptr = None
            self.rtyper.call_all_setups()  # compute ForwardReferences now
            args_s = [SomePtr(Ptr(OBJECT))]
            graph = self.rtyper.annotate_helper(ll_runtime_type_info, args_s)
            s = self.rtyper.annotation(graph.getreturnvar())
            if (not isinstance(s, SomePtr)
                    or s.ll_ptrtype != Ptr(RuntimeTypeInfo)):
                raise TyperError("runtime type info function returns %r, "
                                 "expected Ptr(RuntimeTypeInfo)" % (s))
            funcptr = self.rtyper.getcallable(graph)
            attachRuntimeTypeInfo(self.object_type, funcptr, destrptr)

            vtable = self.rclass.getvtable()
            self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO)
예제 #22
0
    def specialize_more_blocks(self):
        if self.already_seen:
            newtext = ' more'
        else:
            newtext = ''
        blockcount = 0
        self.annmixlevel = None
        while True:
            # look for blocks not specialized yet
            pending = [
                block for block in self.annotator.annotated
                if block not in self.already_seen
            ]
            if not pending:
                break
            # shuffle blocks a bit
            if self.seed:
                import random
                r = random.Random(self.seed)
                r.shuffle(pending)

            if self.order:
                tracking = self.order(self.annotator, pending)
            else:
                tracking = lambda block: None

            previous_percentage = 0
            # specialize all blocks in the 'pending' list
            for block in pending:
                tracking(block)
                blockcount += 1
                self.specialize_block(block)
                self.already_seen[block] = True
                # progress bar
                n = len(self.already_seen)
                if n % 100 == 0:
                    total = len(self.annotator.annotated)
                    percentage = 100 * n // total
                    if percentage >= previous_percentage + 5:
                        previous_percentage = percentage
                        if self.typererror_count:
                            error_report = " but %d errors" % self.typererror_count
                        else:
                            error_report = ''
                        self.log.event(
                            'specializing: %d / %d blocks   (%d%%)%s' %
                            (n, total, percentage, error_report))
            # make sure all reprs so far have had their setup() called
            self.call_all_setups()

        if self.typererrors:
            self.dump_typererrors(to_log=True)
            raise TyperError("there were %d error" % len(self.typererrors))
        self.log.event('-=- specialized %d%s blocks -=-' %
                       (blockcount, newtext))
        annmixlevel = self.annmixlevel
        del self.annmixlevel
        if annmixlevel is not None:
            annmixlevel.finish()
예제 #23
0
 def rtype_getattr(self, hop):
     s_attr = hop.args_s[1]
     attr = s_attr.const
     try:
         index = self.statvfs_field_indexes[attr]
     except KeyError:
         raise TyperError("os.statvfs().%s: field not available" % (attr, ))
     return self.redispatch_getfield(hop, index)
예제 #24
0
class __extend__(pairtype(OOInstanceRepr, IntegerRepr)):
    def rtype_getitem((r_inst, r_int), hop):
        if not r_inst.lowleveltype._isArray:
            raise TyperError("getitem() on a non-array instance")
        v_array, v_index = hop.inputargs(r_inst, ootype.Signed)
        hop.exception_is_here()
        return hop.genop('cli_getelem', [v_array, v_index],
                         hop.r_result.lowleveltype)
예제 #25
0
 def convert_desc(self, desc):
     if desc not in self.s_pbc.descriptions:
         raise TyperError("%r not in %r" % (desc, self))
     if self.lowleveltype is Void:
         return None
     subclassdef = desc.getuniqueclassdef()
     r_subclass = rclass.getclassrepr(self.rtyper, subclassdef)
     return r_subclass.getruntime(self.lowleveltype)
예제 #26
0
 def _call(self, hop2, **kwds_i):
     bltintyper = self.findbltintyper(hop2.rtyper)
     hop2.llops._called_exception_is_here_or_cannot_occur = False
     v_result = bltintyper(hop2, **kwds_i)
     if not hop2.llops._called_exception_is_here_or_cannot_occur:
         raise TyperError("missing hop.exception_cannot_occur() or "
                          "hop.exception_is_here() in %s" % bltintyper)
     return v_result
예제 #27
0
 def make_iterator_repr(self, *variant):
     if not variant:
         return ListIteratorRepr(self)
     elif variant == ("reversed", ):
         return ReversedListIteratorRepr(self)
     else:
         raise TyperError("unsupported %r iterator over a list" %
                          (variant, ))
예제 #28
0
 def convert_desc_or_const(self, desc_or_const):
     if isinstance(desc_or_const, description.Desc):
         return self.convert_desc(desc_or_const)
     elif isinstance(desc_or_const, Constant):
         return self.convert_const(desc_or_const.value)
     else:
         raise TyperError("convert_desc_or_const expects a Desc"
                          "or Constant: %r" % desc_or_const)
예제 #29
0
 def translate_hl_to_ll(self, hop, varmapping):
     #self.log.translating(hop.spaceop.opname, hop.args_s)
     resultvar = hop.dispatch()
     if hop.exceptionlinks and hop.llops.llop_raising_exceptions is None:
         raise TyperError(
             "the graph catches %s, but the rtyper did not "
             "take exceptions into account "
             "(exception_is_here() not called)" %
             ([link.exitcase.__name__ for link in hop.exceptionlinks], ))
     if resultvar is None:
         # no return value
         self.translate_no_return_value(hop)
     else:
         assert isinstance(resultvar, (Variable, Constant))
         op = hop.spaceop
         # for simplicity of the translate_meth, resultvar is usually not
         # op.result here.  We have to replace resultvar with op.result
         # in all generated operations.
         if hop.s_result.is_constant():
             if isinstance(resultvar, Constant) and \
                    isinstance(hop.r_result.lowleveltype, Primitive) and \
                    hop.r_result.lowleveltype is not Void:
                 assert resultvar.value == hop.s_result.const
         resulttype = resultvar.concretetype
         op.result.concretetype = hop.r_result.lowleveltype
         if op.result.concretetype != resulttype:
             raise TyperError("inconsistent type for the result of '%s':\n"
                              "annotator says %s,\n"
                              "whose repr is %r\n"
                              "but rtype_%s returned %r" %
                              (op.opname, hop.s_result, hop.r_result,
                               op.opname, resulttype))
         # figure out if the resultvar is a completely fresh Variable or not
         if (isinstance(resultvar, Variable)
                 and resultvar.annotation is None
                 and resultvar not in varmapping):
             # fresh Variable: rename it to the previously existing op.result
             varmapping[resultvar] = op.result
         elif resultvar is op.result:
             # special case: we got the previous op.result Variable again
             assert varmapping[resultvar] is resultvar
         else:
             # renaming unsafe.  Insert a 'same_as' operation...
             hop.llops.append(
                 SpaceOperation('same_as', [resultvar], op.result))
예제 #30
0
파일: rstr.py 프로젝트: Mu-L/pypy
 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)
     elif encoding == 'utf-8' or encoding == 'utf8':
         return hop.gendirectcall(self.ll_encode_utf8, v_self)
     else:
         raise TyperError("encoding %s not implemented" % (encoding, ))