def redispatch_call(self, hop, call_args): r_class = self.r_im_self.rclass mangled_name, r_func = r_class.clsfields[self.methodname] assert isinstance(r_func, (FunctionsPBCRepr, OverriddenFunctionPBCRepr, 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) opname = 'simple_call' if call_args: opname = 'call_args' hop2.forced_opname = opname 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()
def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res): key = (oopspec_name, tuple(ll_args), ll_res) try: return rtyper._builtin_func_for_spec_cache[key] except (KeyError, AttributeError): pass args_s = [annmodel.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 = annmodel.lltype_to_annotation(ll_res) impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s)) if getattr(impl, 'need_result_type', False): bk = rtyper.annotator.bookkeeper args_s.insert(0, annmodel.SomePBC([bk.getdesc(deref(ll_res))])) # mixlevelann = MixLevelHelperAnnotator(rtyper) c_func = mixlevelann.constfunc(impl, args_s, s_result) mixlevelann.finish() # 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
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): if not s_value.isNone() 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
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
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()
def __init__(self, rtyper, s_pbc): self.rtyper = rtyper self.funcdesc = s_pbc.descriptions.keys()[0].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: assert desc.funcdesc is self.funcdesc 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
def get_s_callable(self): return annmodel.SomePBC([self.funcdesc])