Exemple #1
0
    def __init__(self, rtyper, s_pbc):
        self.rtyper = rtyper
        self.funcdesc = s_pbc.any_description().funcdesc

        # a hack to force the underlying function to show up in call_families
        # (generally not needed, as normalizecalls() should ensure this,
        # but needed for bound methods that are ll helpers)
        # XXX sort this out
        #call_families = rtyper.annotator.getpbccallfamilies()
        #call_families.find((None, self.function))

        if s_pbc.can_be_none():
            raise TyperError("unsupported: variable of type "
                             "method-of-frozen-PBC or None")

        im_selves = []
        for desc in s_pbc.descriptions:
            if desc.funcdesc is not self.funcdesc:
                raise TyperError(
                    "You can't mix a set of methods on a frozen PBC in "
                    "RPython that are different underlying functions")
            im_selves.append(desc.frozendesc)

        self.s_im_self = annmodel.SomePBC(im_selves)
        self.r_im_self = rtyper.getrepr(self.s_im_self)
        self.lowleveltype = self.r_im_self.lowleveltype
Exemple #2
0
    def redispatch_call(self, hop, call_args):
        from rpython.rtyper.lltypesystem.rpbc import (FunctionsPBCRepr,
                                                      SmallFunctionSetPBCRepr)
        r_class = self.r_im_self.rclass
        mangled_name, r_func = r_class.clsfields[self.methodname]
        assert isinstance(r_func, (FunctionsPBCRepr, SmallFunctionSetPBCRepr))
        # s_func = r_func.s_pbc -- not precise enough, see
        # test_precise_method_call_1.  Build a more precise one...
        funcdescs = [desc.funcdesc for desc in hop.args_s[0].descriptions]
        s_func = annmodel.SomePBC(funcdescs, subset_of=r_func.s_pbc)
        v_im_self = hop.inputarg(self, arg=0)
        v_cls = self.r_im_self.getfield(v_im_self, '__class__', hop.llops)
        v_func = r_class.getclsfield(v_cls, self.methodname, hop.llops)

        hop2 = self.add_instance_arg_to_hop(hop, call_args)
        hop2.v_s_insertfirstarg(v_func, s_func)  # insert 'function'

        if (type(hop2.args_r[0]) is SmallFunctionSetPBCRepr
                and type(r_func) is FunctionsPBCRepr):
            hop2.args_r[0] = FunctionsPBCRepr(self.rtyper, s_func)
        else:
            hop2.args_v[0] = hop2.llops.convertvar(hop2.args_v[0], r_func,
                                                   hop2.args_r[0])

        # now hop2 looks like simple_call(function, self, args...)
        return hop2.dispatch()
Exemple #3
0
 def prepare_method(self, s_value):
     # special-casing for methods:
     #  if s_value is SomePBC([MethodDescs...])
     #  return a PBC representing the underlying functions
     if (isinstance(s_value, annmodel.SomePBC)
             and s_value.getKind() == description.MethodDesc):
         s_value = self.classdef.lookup_filter(s_value)
         funcdescs = [mdesc.funcdesc for mdesc in s_value.descriptions]
         return annmodel.SomePBC(funcdescs)
     return None  # not a method
Exemple #4
0
 def convert_desc(self, frozendesc):
     try:
         return self.converted_pbc_cache[frozendesc]
     except KeyError:
         r = self.rtyper.getrepr(annmodel.SomePBC([frozendesc]))
         if r.lowleveltype is Void:
             # must create a new empty structure, as a placeholder
             pbc = self.create_instance()
         else:
             pbc = r.convert_desc(frozendesc)
         convpbc = self.convert_pbc(pbc)
         self.converted_pbc_cache[frozendesc] = convpbc
         return convpbc
Exemple #5
0
def builtin_func_for_spec(rtyper,
                          oopspec_name,
                          ll_args,
                          ll_res,
                          extra=None,
                          extrakey=None):
    assert (extra is None) == (extrakey is None)
    key = (oopspec_name, tuple(ll_args), ll_res, extrakey)
    try:
        return rtyper._builtin_func_for_spec_cache[key]
    except (KeyError, AttributeError):
        pass
    args_s = [lltype_to_annotation(v) for v in ll_args]
    if '.' not in oopspec_name:  # 'newxxx' operations
        LIST_OR_DICT = ll_res
    else:
        LIST_OR_DICT = ll_args[0]
    s_result = lltype_to_annotation(ll_res)
    impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s), extra)
    if getattr(impl, 'need_result_type', False):
        if hasattr(rtyper, 'annotator'):
            bk = rtyper.annotator.bookkeeper
            ll_restype = ll_res
            if impl.need_result_type != 'exact':
                ll_restype = ll_restype.TO
            desc = bk.getdesc(ll_restype)
        else:

            class TestingDesc(object):
                knowntype = int
                pyobj = None

            desc = TestingDesc()
        args_s.insert(0, annmodel.SomePBC([desc]))
    #
    if hasattr(rtyper, 'annotator'):  # regular case
        mixlevelann = MixLevelHelperAnnotator(rtyper)
        c_func = mixlevelann.constfunc(impl, args_s, s_result)
        mixlevelann.finish()
    else:
        # for testing only
        c_func = Constant(oopspec_name,
                          lltype.Ptr(lltype.FuncType(ll_args, ll_res)))
    #
    if not hasattr(rtyper, '_builtin_func_for_spec_cache'):
        rtyper._builtin_func_for_spec_cache = {}
    rtyper._builtin_func_for_spec_cache[key] = (c_func, LIST_OR_DICT)
    #
    return c_func, LIST_OR_DICT
Exemple #6
0
 def redispatch_call(self, hop, call_args):
     # XXX obscure, try to refactor...
     s_function = annmodel.SomePBC([self.funcdesc])
     hop2 = hop.copy()
     hop2.args_s[0] = self.s_im_self  # make the 1st arg stand for 'im_self'
     hop2.args_r[0] = self.r_im_self  # (same lowleveltype as 'self')
     if isinstance(hop2.args_v[0], Constant):
         boundmethod = hop2.args_v[0].value
         hop2.args_v[0] = Constant(boundmethod.im_self)
     if call_args:
         hop2.swap_fst_snd_args()
         _, s_shape = hop2.r_s_popfirstarg()  # temporarely remove shape
         adjust_shape(hop2, s_shape)
     # a marker that would crash if actually used...
     c = Constant("obscure-don't-use-me")
     hop2.v_s_insertfirstarg(c, s_function)  # insert 'function'
     # now hop2 looks like simple_call(function, self, args...)
     return hop2.dispatch()
Exemple #7
0
    def __init__(self, rtyper, s_pbc):
        self.rtyper = rtyper
        funcdescs = set([desc.funcdesc for desc in s_pbc.descriptions])
        assert len(funcdescs) == 1
        self.funcdesc = funcdescs.pop()

        # a hack to force the underlying function to show up in call_families
        # (generally not needed, as normalizecalls() should ensure this,
        # but needed for bound methods that are ll helpers)
        # XXX sort this out
        #call_families = rtyper.annotator.getpbccallfamilies()
        #call_families.find((None, self.function))

        if s_pbc.can_be_none():
            raise TyperError("unsupported: variable of type "
                             "method-of-frozen-PBC or None")

        im_selves = [desc.frozendesc for desc in s_pbc.descriptions]
        self.s_im_self = annmodel.SomePBC(im_selves)
        self.r_im_self = rtyper.getrepr(self.s_im_self)
        self.lowleveltype = self.r_im_self.lowleveltype
Exemple #8
0
 def compute_annotation(self):
     from rpython.annotator import model as annmodel
     bk = self.bookkeeper
     translator = bk.annotator.translator
     fn = getattr(translator, 'll_hash_string', ll_hash_string)
     return annmodel.SomePBC([bk.getdesc(fn)])
Exemple #9
0
 def get_s_callable(self):
     return annmodel.SomePBC([self.funcdesc])