/rpython/rtyper/controllerentry.py
Python | 266 lines | 194 code | 71 blank | 1 comment | 13 complexity | 526ece65db385a0222e84eeb42936fe3 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
- from rpython.annotator import model as annmodel
- from rpython.tool.pairtype import pairtype
- from rpython.annotator.bookkeeper import getbookkeeper
- from rpython.rtyper.extregistry import ExtRegistryEntry
- from rpython.rtyper.annlowlevel import cachedtype
- from rpython.rtyper.error import TyperError
- class ControllerEntry(ExtRegistryEntry):
- def compute_result_annotation(self, *args_s, **kwds_s):
- controller = self.getcontroller(*args_s, **kwds_s)
- return controller.ctrl_new_ex(self.bookkeeper, *args_s, **kwds_s)
- def getcontroller(self, *args_s, **kwds_s):
- return self._controller_()
- def specialize_call(self, hop, **kwds_i):
- if hop.s_result == annmodel.s_ImpossibleValue:
- raise TyperError("object creation always raises: %s" % (
- hop.spaceop,))
- controller = hop.s_result.controller
- return controller.rtype_new(hop, **kwds_i)
- def controlled_instance_box(controller, obj):
- XXX # only for special-casing by ExtRegistryEntry below
- def controlled_instance_unbox(controller, obj):
- XXX # only for special-casing by ExtRegistryEntry below
- def controlled_instance_is_box(controller, obj):
- XXX # only for special-casing by ExtRegistryEntry below
- class ControllerEntryForPrebuilt(ExtRegistryEntry):
- def compute_annotation(self):
- controller = self.getcontroller()
- real_obj = controller.convert(self.instance)
- s_real_obj = self.bookkeeper.immutablevalue(real_obj)
- return SomeControlledInstance(s_real_obj, controller)
- def getcontroller(self):
- return self._controller_()
- class Controller(object):
- __metaclass__ = cachedtype
- can_be_None = False
- def _freeze_(self):
- return True
- def box(self, obj):
- return controlled_instance_box(self, obj)
- box._annspecialcase_ = 'specialize:arg(0)'
- def unbox(self, obj):
- return controlled_instance_unbox(self, obj)
- unbox._annspecialcase_ = 'specialize:arg(0)'
- def is_box(self, obj):
- return controlled_instance_is_box(self, obj)
- is_box._annspecialcase_ = 'specialize:arg(0)'
- def ctrl_new(self, *args_s, **kwds_s):
- if kwds_s:
- raise TypeError("cannot handle keyword arguments in %s" % (
- self.new,))
- s_real_obj = delegate(self.new, *args_s)
- if s_real_obj == annmodel.s_ImpossibleValue:
- return annmodel.s_ImpossibleValue
- else:
- return SomeControlledInstance(s_real_obj, controller=self)
- def ctrl_new_ex(self, bookkeeper, *args_s, **kwds_s):
- return self.ctrl_new(*args_s, **kwds_s)
- def rtype_new(self, hop):
- from rpython.rtyper.rcontrollerentry import rtypedelegate
- return rtypedelegate(self.new, hop, revealargs=[], revealresult=True)
- def getattr(self, obj, attr):
- return getattr(self, 'get_' + attr)(obj)
- getattr._annspecialcase_ = 'specialize:arg(0, 2)'
- def ctrl_getattr(self, s_obj, s_attr):
- return delegate(self.getattr, s_obj, s_attr)
- def rtype_getattr(self, hop):
- from rpython.rtyper.rcontrollerentry import rtypedelegate
- return rtypedelegate(self.getattr, hop)
- def setattr(self, obj, attr, value):
- return getattr(self, 'set_' + attr)(obj, value)
- setattr._annspecialcase_ = 'specialize:arg(0, 2)'
- def ctrl_setattr(self, s_obj, s_attr, s_value):
- return delegate(self.setattr, s_obj, s_attr, s_value)
- def rtype_setattr(self, hop):
- from rpython.rtyper.rcontrollerentry import rtypedelegate
- return rtypedelegate(self.setattr, hop)
- def ctrl_getitem(self, s_obj, s_key):
- return delegate(self.getitem, s_obj, s_key)
- def rtype_getitem(self, hop):
- from rpython.rtyper.rcontrollerentry import rtypedelegate
- return rtypedelegate(self.getitem, hop)
- def ctrl_setitem(self, s_obj, s_key, s_value):
- return delegate(self.setitem, s_obj, s_key, s_value)
- def rtype_setitem(self, hop):
- from rpython.rtyper.rcontrollerentry import rtypedelegate
- return rtypedelegate(self.setitem, hop)
- def ctrl_delitem(self, s_obj, s_key):
- return delegate(self.delitem, s_obj, s_key)
- def rtype_delitem(self, hop):
- from rpython.rtyper.rcontrollerentry import rtypedelegate
- return rtypedelegate(self.delitem, hop)
- def ctrl_bool(self, s_obj):
- return delegate(self.bool, s_obj)
- def rtype_bool(self, hop):
- from rpython.rtyper.rcontrollerentry import rtypedelegate
- return rtypedelegate(self.bool, hop)
- def ctrl_call(self, s_obj, *args_s):
- return delegate(self.call, s_obj, *args_s)
- def rtype_call(self, hop):
- from rpython.rtyper.rcontrollerentry import rtypedelegate
- return rtypedelegate(self.call, hop)
- def delegate(boundmethod, *args_s):
- bk = getbookkeeper()
- s_meth = bk.immutablevalue(boundmethod)
- return bk.emulate_pbc_call(bk.position_key, s_meth, args_s,
- callback = bk.position_key)
- class BoxEntry(ExtRegistryEntry):
- _about_ = controlled_instance_box
- def compute_result_annotation(self, s_controller, s_real_obj):
- if s_real_obj == annmodel.s_ImpossibleValue:
- return annmodel.s_ImpossibleValue
- else:
- assert s_controller.is_constant()
- controller = s_controller.const
- return SomeControlledInstance(s_real_obj, controller=controller)
- def specialize_call(self, hop):
- from rpython.rtyper.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)
- class UnboxEntry(ExtRegistryEntry):
- _about_ = controlled_instance_unbox
- def compute_result_annotation(self, s_controller, s_obj):
- if s_obj == annmodel.s_ImpossibleValue:
- return annmodel.s_ImpossibleValue
- else:
- assert isinstance(s_obj, SomeControlledInstance)
- return s_obj.s_real_obj
- def specialize_call(self, hop):
- from rpython.rtyper.rcontrollerentry import ControlledInstanceRepr
- 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)
- class IsBoxEntry(ExtRegistryEntry):
- _about_ = controlled_instance_is_box
- def compute_result_annotation(self, s_controller, s_obj):
- if s_obj == annmodel.s_ImpossibleValue:
- return annmodel.s_ImpossibleValue
- else:
- assert s_controller.is_constant()
- controller = s_controller.const
- result = (isinstance(s_obj, SomeControlledInstance) and
- s_obj.controller == controller)
- return self.bookkeeper.immutablevalue(result)
- def specialize_call(self, hop):
- from rpython.rtyper.lltypesystem import lltype
- assert hop.s_result.is_constant()
- hop.exception_cannot_occur()
- return hop.inputconst(lltype.Bool, hop.s_result.const)
- # ____________________________________________________________
- class SomeControlledInstance(annmodel.SomeObject):
- def __init__(self, s_real_obj, controller):
- self.s_real_obj = s_real_obj
- self.controller = controller
- self.knowntype = controller.knowntype
- def can_be_none(self):
- return self.controller.can_be_None
- def noneify(self):
- return SomeControlledInstance(self.s_real_obj, self.controller)
- def rtyper_makerepr(self, rtyper):
- from rpython.rtyper.rcontrollerentry import ControlledInstanceRepr
- return ControlledInstanceRepr(rtyper, self.s_real_obj, self.controller)
- def rtyper_makekey(self):
- real_key = self.s_real_obj.rtyper_makekey()
- return self.__class__, real_key, self.controller
- class __extend__(SomeControlledInstance):
- def getattr(s_cin, s_attr):
- assert s_attr.is_constant()
- return s_cin.controller.ctrl_getattr(s_cin.s_real_obj, s_attr)
- def setattr(s_cin, s_attr, s_value):
- assert s_attr.is_constant()
- s_cin.controller.ctrl_setattr(s_cin.s_real_obj, s_attr, s_value)
- def bool(s_cin):
- return s_cin.controller.ctrl_is_true(s_cin.s_real_obj)
- def simple_call(s_cin, *args_s):
- return s_cin.controller.ctrl_call(s_cin.s_real_obj, *args_s)
- class __extend__(pairtype(SomeControlledInstance, annmodel.SomeObject)):
- def getitem((s_cin, s_key)):
- return s_cin.controller.ctrl_getitem(s_cin.s_real_obj, s_key)
- def setitem((s_cin, s_key), s_value):
- s_cin.controller.ctrl_setitem(s_cin.s_real_obj, s_key, s_value)
- def delitem((s_cin, s_key)):
- s_cin.controller.ctrl_delitem(s_cin.s_real_obj, s_key)
- class __extend__(pairtype(SomeControlledInstance, SomeControlledInstance)):
- def union((s_cin1, s_cin2)):
- if s_cin1.controller is not s_cin2.controller:
- raise annmodel.UnionError("different controller!")
- return SomeControlledInstance(annmodel.unionof(s_cin1.s_real_obj,
- s_cin2.s_real_obj),
- s_cin1.controller)