/pypy/rpython/lltypesystem/lloperation.py
Python | 601 lines | 453 code | 84 blank | 64 comment | 33 complexity | 32ffa4672d78e47a9f426a475c46a728 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
- """
- The table of all LL operations.
- """
- from pypy.rpython.extregistry import ExtRegistryEntry
- from pypy.tool.descriptor import roproperty
- class LLOp(object):
- def __init__(self, sideeffects=True, canfold=False, canraise=(),
- pyobj=False, canmallocgc=False, canrun=False, oo=False,
- tryfold=False):
- # self.opname = ... (set afterwards)
- if canfold:
- sideeffects = False
- # The operation has no side-effects: it can be removed
- # if its result is not used
- self.sideeffects = sideeffects
- # Can be safely constant-folded: no side-effects
- # and always gives the same result for given args
- self.canfold = canfold
- # Can *try* to fold the operation, but it may raise on you
- self.tryfold = tryfold or canfold
- # Exceptions that can be raised
- self.canraise = canraise
- assert isinstance(canraise, tuple)
- assert not canraise or not canfold
- # The operation manipulates PyObjects
- self.pyobj = pyobj
- # The operation can go a GC malloc
- self.canmallocgc = canmallocgc
- if canmallocgc:
- if (MemoryError not in self.canraise and
- Exception not in self.canraise):
- self.canraise += (MemoryError,)
- # The operation can be run directly with __call__
- self.canrun = canrun or canfold
- # The operation belongs to the ootypesystem
- self.oo = oo
- # __________ make the LLOp instances callable from LL helpers __________
- __name__ = property(lambda self: 'llop_'+self.opname)
- def __call__(self, RESULTTYPE, *args):
- # llop is meant to be rtyped and not called directly, unless it is
- # a canfold=True operation
- fold = self.fold
- if getattr(fold, 'need_result_type', False):
- val = fold(RESULTTYPE, *args)
- else:
- val = fold(*args)
- if RESULTTYPE is not lltype.Void:
- val = lltype.enforce(RESULTTYPE, val)
- return val
- def get_fold_impl(self):
- global lltype # <- lazy import hack, worth an XXX
- from pypy.rpython.lltypesystem import lltype
- if self.canrun:
- if self.oo:
- from pypy.rpython.ootypesystem.ooopimpl import get_op_impl
- else:
- from pypy.rpython.lltypesystem.opimpl import get_op_impl
- op_impl = get_op_impl(self.opname)
- else:
- error = TypeError("cannot constant-fold operation %r" % (
- self.opname,))
- def op_impl(*args):
- raise error
- # cache the implementation function into 'self'
- self.fold = op_impl
- return op_impl
- fold = roproperty(get_fold_impl)
- def is_pure(self, args_v):
- if self.canfold: # canfold => pure operation
- return True
- if self is llop.debug_assert: # debug_assert is pure enough
- return True
- # reading from immutable (lltype)
- if self is llop.getfield or self is llop.getarrayitem:
- field = getattr(args_v[1], 'value', None)
- return args_v[0].concretetype.TO._immutable_field(field)
- # reading from immutable (ootype) (xxx what about arrays?)
- if self is llop.oogetfield:
- field = getattr(args_v[1], 'value', None)
- return args_v[0].concretetype._immutable_field(field)
- # default
- return False
- def __repr__(self):
- return '<LLOp %s>' % (getattr(self, 'opname', '?'),)
- class _LLOP(object):
- def _freeze_(self):
- return True
- llop = _LLOP()
- class VoidMarker(object):
- # marker wrapper for void arguments to llops
- def __init__(self, value):
- self.value = value
- def _freeze_(self):
- return True
- def void(value):
- return VoidMarker(value)
- class Entry(ExtRegistryEntry):
- _about_ = void
- def compute_result_annotation(self, s_value):
- assert s_value.is_constant()
- from pypy.annotation.bookkeeper import getbookkeeper
- bk = getbookkeeper()
- return bk.immutablevalue(VoidMarker(s_value.const))
- def specialize_call(self, hop):
- from pypy.rpython.lltypesystem import lltype
- return hop.inputconst(lltype.Void, None)
- def enum_ops_without_sideeffects(raising_is_ok=False):
- """Enumerate operations that have no side-effects
- (see also enum_foldable_ops)."""
- for opname, opdesc in LL_OPERATIONS.iteritems():
- if not opdesc.sideeffects:
- if not opdesc.canraise or raising_is_ok:
- yield opname
- def enum_foldable_ops(_ignored=None):
- """Enumerate operations that can be constant-folded."""
- for opname, opdesc in LL_OPERATIONS.iteritems():
- if opdesc.canfold:
- assert not opdesc.canraise
- yield opname
- class Entry(ExtRegistryEntry):
- "Annotation and rtyping of LLOp instances, which are callable."
- _type_ = LLOp
- def compute_result_annotation(self, RESULTTYPE, *args):
- from pypy.annotation.model import lltype_to_annotation
- assert RESULTTYPE.is_constant()
- return lltype_to_annotation(RESULTTYPE.const)
- def specialize_call(self, hop):
- from pypy.rpython.lltypesystem import lltype
- op = self.instance # the LLOp object that was called
- args_v = []
- for i, s_arg in enumerate(hop.args_s[1:]):
- if s_arg.is_constant() and isinstance(s_arg.const, VoidMarker):
- v_arg = hop.inputconst(lltype.Void, s_arg.const.value)
- else:
- v_arg = hop.inputarg(hop.args_r[i+1], i+1)
- args_v.append(v_arg)
- if op.canraise:
- hop.exception_is_here()
- else:
- hop.exception_cannot_occur()
- return hop.genop(op.opname, args_v, resulttype=hop.r_result.lowleveltype)
- # ____________________________________________________________
- #
- # This list corresponds to the operations implemented by the LLInterpreter.
- # Note that many exception-raising operations can be replaced by calls
- # to helper functions in pypy.rpython.raisingops.raisingops.
- # ***** Run test_lloperation after changes. *****
- LL_OPERATIONS = {
- 'direct_call': LLOp(canraise=(Exception,)),
- 'indirect_call': LLOp(canraise=(Exception,)),
- # __________ numeric operations __________
- 'bool_not': LLOp(canfold=True),
- 'char_lt': LLOp(canfold=True),
- 'char_le': LLOp(canfold=True),
- 'char_eq': LLOp(canfold=True),
- 'char_ne': LLOp(canfold=True),
- 'char_gt': LLOp(canfold=True),
- 'char_ge': LLOp(canfold=True),
- 'unichar_eq': LLOp(canfold=True),
- 'unichar_ne': LLOp(canfold=True),
- 'int_is_true': LLOp(canfold=True),
- 'int_neg': LLOp(canfold=True),
- 'int_neg_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- 'int_abs': LLOp(canfold=True),
- 'int_abs_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- 'int_invert': LLOp(canfold=True),
- 'int_add': LLOp(canfold=True),
- 'int_sub': LLOp(canfold=True),
- 'int_mul': LLOp(canfold=True),
- 'int_floordiv': LLOp(canfold=True),
- 'int_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'int_mod': LLOp(canfold=True),
- 'int_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'int_lt': LLOp(canfold=True),
- 'int_le': LLOp(canfold=True),
- 'int_eq': LLOp(canfold=True),
- 'int_ne': LLOp(canfold=True),
- 'int_gt': LLOp(canfold=True),
- 'int_ge': LLOp(canfold=True),
- 'int_and': LLOp(canfold=True),
- 'int_or': LLOp(canfold=True),
- 'int_lshift': LLOp(canfold=True),
- 'int_rshift': LLOp(canfold=True),
- 'int_xor': LLOp(canfold=True),
- 'int_between': LLOp(canfold=True), # a <= b < c
- 'int_add_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- 'int_add_nonneg_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- # ^^^ more efficient version when 2nd arg is nonneg
- 'int_sub_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- 'int_mul_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- # the following operations overflow in one case: (-sys.maxint-1) // (-1)
- 'int_floordiv_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- 'int_floordiv_ovf_zer': LLOp(canraise=(OverflowError, ZeroDivisionError),
- tryfold=True),
- 'int_mod_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- 'int_mod_ovf_zer': LLOp(canraise=(OverflowError, ZeroDivisionError),
- tryfold=True),
- 'int_lshift_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
- 'uint_is_true': LLOp(canfold=True),
- 'uint_invert': LLOp(canfold=True),
- 'uint_add': LLOp(canfold=True),
- 'uint_sub': LLOp(canfold=True),
- 'uint_mul': LLOp(canfold=True),
- 'uint_floordiv': LLOp(canfold=True),
- 'uint_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'uint_mod': LLOp(canfold=True),
- 'uint_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'uint_lt': LLOp(canfold=True),
- 'uint_le': LLOp(canfold=True),
- 'uint_eq': LLOp(canfold=True),
- 'uint_ne': LLOp(canfold=True),
- 'uint_gt': LLOp(canfold=True),
- 'uint_ge': LLOp(canfold=True),
- 'uint_and': LLOp(canfold=True),
- 'uint_or': LLOp(canfold=True),
- 'uint_lshift': LLOp(canfold=True), # args (r_uint, int)
- 'uint_rshift': LLOp(canfold=True), # args (r_uint, int)
- 'uint_xor': LLOp(canfold=True),
- 'float_is_true': LLOp(canfold=True), # it really means "x != 0.0"
- 'float_neg': LLOp(canfold=True),
- 'float_abs': LLOp(canfold=True),
- 'float_add': LLOp(canfold=True),
- 'float_sub': LLOp(canfold=True),
- 'float_mul': LLOp(canfold=True),
- 'float_truediv': LLOp(canfold=True),
- 'float_lt': LLOp(canfold=True),
- 'float_le': LLOp(canfold=True),
- 'float_eq': LLOp(canfold=True),
- 'float_ne': LLOp(canfold=True),
- 'float_gt': LLOp(canfold=True),
- 'float_ge': LLOp(canfold=True),
- # don't implement float_mod, use math.fmod instead
- # don't implement float_pow, use math.pow instead
- 'llong_is_true': LLOp(canfold=True),
- 'llong_neg': LLOp(canfold=True),
- 'llong_abs': LLOp(canfold=True),
- 'llong_invert': LLOp(canfold=True),
- 'llong_add': LLOp(canfold=True),
- 'llong_sub': LLOp(canfold=True),
- 'llong_mul': LLOp(canfold=True),
- 'llong_floordiv': LLOp(canfold=True),
- 'llong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'llong_mod': LLOp(canfold=True),
- 'llong_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'llong_lt': LLOp(canfold=True),
- 'llong_le': LLOp(canfold=True),
- 'llong_eq': LLOp(canfold=True),
- 'llong_ne': LLOp(canfold=True),
- 'llong_gt': LLOp(canfold=True),
- 'llong_ge': LLOp(canfold=True),
- 'llong_and': LLOp(canfold=True),
- 'llong_or': LLOp(canfold=True),
- 'llong_lshift': LLOp(canfold=True), # args (r_longlong, int)
- 'llong_rshift': LLOp(canfold=True), # args (r_longlong, int)
- 'llong_xor': LLOp(canfold=True),
- 'ullong_is_true': LLOp(canfold=True),
- 'ullong_invert': LLOp(canfold=True),
- 'ullong_add': LLOp(canfold=True),
- 'ullong_sub': LLOp(canfold=True),
- 'ullong_mul': LLOp(canfold=True),
- 'ullong_floordiv': LLOp(canfold=True),
- 'ullong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'ullong_mod': LLOp(canfold=True),
- 'ullong_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'ullong_lt': LLOp(canfold=True),
- 'ullong_le': LLOp(canfold=True),
- 'ullong_eq': LLOp(canfold=True),
- 'ullong_ne': LLOp(canfold=True),
- 'ullong_gt': LLOp(canfold=True),
- 'ullong_ge': LLOp(canfold=True),
- 'ullong_and': LLOp(canfold=True),
- 'ullong_or': LLOp(canfold=True),
- 'ullong_lshift': LLOp(canfold=True), # args (r_ulonglong, int)
- 'ullong_rshift': LLOp(canfold=True), # args (r_ulonglong, int)
- 'ullong_xor': LLOp(canfold=True),
- 'cast_primitive': LLOp(canfold=True),
- 'cast_bool_to_int': LLOp(canfold=True),
- 'cast_bool_to_uint': LLOp(canfold=True),
- 'cast_bool_to_float': LLOp(canfold=True),
- 'cast_char_to_int': LLOp(canfold=True),
- 'cast_unichar_to_int': LLOp(canfold=True),
- 'cast_int_to_char': LLOp(canfold=True),
- 'cast_int_to_unichar': LLOp(canfold=True),
- 'cast_int_to_uint': LLOp(canfold=True),
- 'cast_int_to_float': LLOp(canfold=True),
- 'cast_int_to_longlong': LLOp(canfold=True),
- 'cast_uint_to_int': LLOp(canfold=True),
- 'cast_uint_to_float': LLOp(canfold=True),
- 'cast_longlong_to_float' :LLOp(canfold=True),
- 'cast_ulonglong_to_float':LLOp(canfold=True),
- 'cast_float_to_int': LLOp(canfold=True),
- 'cast_float_to_uint': LLOp(canfold=True),
- 'cast_float_to_longlong' :LLOp(canfold=True),
- 'cast_float_to_ulonglong':LLOp(canfold=True),
- 'truncate_longlong_to_int':LLOp(canfold=True),
- 'force_cast': LLOp(sideeffects=False), # only for rffi.cast()
- # __________ pointer operations __________
- 'malloc': LLOp(canmallocgc=True),
- 'malloc_varsize': LLOp(canmallocgc=True),
- 'malloc_nonmovable': LLOp(canmallocgc=True),
- 'malloc_nonmovable_varsize':LLOp(canmallocgc=True),
- 'shrink_array': LLOp(canrun=True),
- 'zero_gc_pointers_inside': LLOp(),
- 'free': LLOp(),
- 'getfield': LLOp(sideeffects=False, canrun=True),
- 'getarrayitem': LLOp(sideeffects=False, canrun=True),
- 'getarraysize': LLOp(canfold=True),
- 'getsubstruct': LLOp(canfold=True),
- 'getinteriorfield': LLOp(sideeffects=False, canrun=True),
- 'getinteriorarraysize': LLOp(canfold=True),
- 'setinteriorfield': LLOp(),
- 'bare_setinteriorfield': LLOp(),
- 'getarraysubstruct': LLOp(canfold=True),
- 'setfield': LLOp(),
- 'bare_setfield': LLOp(),
- 'setarrayitem': LLOp(),
- 'bare_setarrayitem': LLOp(),
- 'cast_pointer': LLOp(canfold=True),
- 'ptr_eq': LLOp(canfold=True),
- 'ptr_ne': LLOp(canfold=True),
- 'ptr_nonzero': LLOp(canfold=True),
- 'ptr_iszero': LLOp(canfold=True),
- 'cast_ptr_to_int': LLOp(sideeffects=False),
- 'cast_int_to_ptr': LLOp(sideeffects=False),
- 'direct_fieldptr': LLOp(canfold=True),
- 'direct_arrayitems': LLOp(canfold=True),
- 'direct_ptradd': LLOp(canfold=True),
- 'cast_opaque_ptr': LLOp(sideeffects=False),
- # __________ address operations __________
- 'boehm_malloc': LLOp(),
- 'boehm_malloc_atomic': LLOp(),
- 'boehm_register_finalizer': LLOp(),
- 'boehm_disappearing_link': LLOp(),
- 'raw_malloc': LLOp(),
- 'raw_malloc_usage': LLOp(sideeffects=False),
- 'raw_free': LLOp(),
- 'raw_memclear': LLOp(),
- 'raw_memcopy': LLOp(),
- 'raw_memmove': LLOp(),
- 'raw_load': LLOp(sideeffects=False),
- 'raw_store': LLOp(),
- 'stack_malloc': LLOp(), # mmh
- 'track_alloc_start': LLOp(),
- 'track_alloc_stop': LLOp(),
- 'adr_add': LLOp(canfold=True),
- 'adr_sub': LLOp(canfold=True),
- 'adr_delta': LLOp(canfold=True),
- 'adr_lt': LLOp(canfold=True),
- 'adr_le': LLOp(canfold=True),
- 'adr_eq': LLOp(canfold=True),
- 'adr_ne': LLOp(canfold=True),
- 'adr_gt': LLOp(canfold=True),
- 'adr_ge': LLOp(canfold=True),
- 'cast_ptr_to_adr': LLOp(sideeffects=False),
- 'cast_adr_to_ptr': LLOp(canfold=True),
- 'cast_adr_to_int': LLOp(sideeffects=False),
- 'cast_int_to_adr': LLOp(canfold=True),
- 'get_group_member': LLOp(canfold=True),
- 'get_next_group_member':LLOp(canfold=True),
- 'is_group_member_nonzero':LLOp(canfold=True),
- 'extract_ushort': LLOp(canfold=True),
- 'combine_ushort': LLOp(canfold=True),
- 'gc_gettypeptr_group': LLOp(canfold=True),
- 'get_member_index': LLOp(canfold=True),
- # __________ used by the JIT ________
- 'jit_marker': LLOp(),
- 'jit_force_virtualizable':LLOp(canrun=True),
- 'jit_force_virtual': LLOp(canrun=True),
- 'jit_is_virtual': LLOp(canrun=True),
- 'jit_force_quasi_immutable': LLOp(canrun=True),
- 'jit_record_known_class' : LLOp(canrun=True),
- 'get_exception_addr': LLOp(),
- 'get_exc_value_addr': LLOp(),
- 'do_malloc_fixedsize_clear':LLOp(canmallocgc=True),
- 'do_malloc_varsize_clear': LLOp(canmallocgc=True),
- 'get_write_barrier_failing_case': LLOp(sideeffects=False),
- 'get_write_barrier_from_array_failing_case': LLOp(sideeffects=False),
- 'gc_get_type_info_group': LLOp(sideeffects=False),
- 'll_read_timestamp': LLOp(canrun=True),
- # __________ GC operations __________
- 'gc__collect': LLOp(canmallocgc=True),
- 'gc_free': LLOp(),
- 'gc_fetch_exception': LLOp(),
- 'gc_restore_exception': LLOp(),
- 'gc_call_rtti_destructor': LLOp(),
- 'gc_deallocate': LLOp(),
- 'gc_push_alive_pyobj': LLOp(),
- 'gc_pop_alive_pyobj': LLOp(),
- 'gc_reload_possibly_moved': LLOp(),
- # see rlib/objectmodel for gc_identityhash and gc_id
- 'gc_identityhash': LLOp(sideeffects=False, canmallocgc=True),
- 'gc_id': LLOp(sideeffects=False, canmallocgc=True),
- 'gc_obtain_free_space': LLOp(),
- 'gc_set_max_heap_size': LLOp(),
- 'gc_can_move' : LLOp(sideeffects=False),
- 'gc_thread_prepare' : LLOp(canmallocgc=True),
- 'gc_thread_run' : LLOp(),
- 'gc_thread_start' : LLOp(),
- 'gc_thread_die' : LLOp(),
- 'gc_thread_before_fork':LLOp(), # returns an opaque address
- 'gc_thread_after_fork': LLOp(), # arguments: (result_of_fork, opaqueaddr)
- 'gc_assume_young_pointers': LLOp(canrun=True),
- 'gc_writebarrier_before_copy': LLOp(canrun=True),
- 'gc_heap_stats' : LLOp(canmallocgc=True),
- 'gc_get_rpy_roots' : LLOp(),
- 'gc_get_rpy_referents': LLOp(),
- 'gc_get_rpy_memory_usage': LLOp(),
- 'gc_get_rpy_type_index': LLOp(),
- 'gc_is_rpy_instance' : LLOp(),
- 'gc_dump_rpy_heap' : LLOp(),
- 'gc_typeids_z' : LLOp(),
- 'gc_add_memory_pressure': LLOp(),
- # ------- JIT & GC interaction, only for some GCs ----------
- 'gc_adr_of_nursery_free' : LLOp(),
- # ^^^ returns an address of nursery free pointer, for later modifications
- 'gc_adr_of_nursery_top' : LLOp(),
- # ^^^ returns an address of pointer, since it can change at runtime
- 'gc_adr_of_root_stack_base': LLOp(),
- 'gc_adr_of_root_stack_top': LLOp(),
- # returns the address of gcdata.root_stack_base/top (for shadowstack only)
- # for asmgcroot support to get the address of various static structures
- # see translator/c/src/mem.h for the valid indices
- 'gc_asmgcroot_static': LLOp(sideeffects=False),
- 'gc_stack_bottom': LLOp(canrun=True),
- # for stacklet+shadowstack support
- 'gc_shadowstackref_new': LLOp(canmallocgc=True),
- 'gc_shadowstackref_context': LLOp(),
- 'gc_shadowstackref_destroy': LLOp(),
- 'gc_save_current_state_away': LLOp(),
- 'gc_forget_current_state': LLOp(),
- 'gc_restore_state_from': LLOp(),
- 'gc_start_fresh_new_state': LLOp(),
- # NOTE NOTE NOTE! don't forget *** canmallocgc=True *** for anything that
- # can malloc a GC object.
- # __________ weakrefs __________
- 'weakref_create': LLOp(sideeffects=False, canmallocgc=True),
- 'weakref_deref': LLOp(sideeffects=False),
- 'cast_ptr_to_weakrefptr': LLOp(sideeffects=False), # no-op type hiding
- 'cast_weakrefptr_to_ptr': LLOp(sideeffects=False), # no-op type revealing
- # __________ misc operations __________
- 'stack_current': LLOp(sideeffects=False),
- 'keepalive': LLOp(),
- 'same_as': LLOp(canfold=True),
- 'hint': LLOp(),
- 'check_no_more_arg': LLOp(canraise=(Exception,)),
- 'check_self_nonzero': LLOp(canraise=(Exception,)),
- 'decode_arg': LLOp(canraise=(Exception,)),
- 'decode_arg_def': LLOp(canraise=(Exception,)),
- 'getslice': LLOp(canraise=(Exception,)),
- 'check_and_clear_exc': LLOp(),
- # __________ debugging __________
- 'debug_view': LLOp(),
- 'debug_print': LLOp(canrun=True),
- 'debug_start': LLOp(canrun=True),
- 'debug_stop': LLOp(canrun=True),
- 'have_debug_prints': LLOp(canrun=True),
- 'debug_offset': LLOp(canrun=True),
- 'debug_flush': LLOp(canrun=True),
- 'debug_assert': LLOp(tryfold=True),
- 'debug_fatalerror': LLOp(),
- 'debug_llinterpcall': LLOp(canraise=(Exception,)),
- # Python func call 'res=arg[0](*arg[1:])'
- # in backends, abort() or whatever is fine
- 'debug_start_traceback': LLOp(),
- 'debug_record_traceback': LLOp(),
- 'debug_catch_exception': LLOp(),
- 'debug_reraise_traceback': LLOp(),
- 'debug_print_traceback': LLOp(),
- 'debug_nonnull_pointer': LLOp(canrun=True),
- # __________ instrumentation _________
- 'instrument_count': LLOp(),
- # __________ ootype operations __________
- 'new': LLOp(oo=True, canraise=(MemoryError,)),
- 'runtimenew': LLOp(oo=True, canraise=(MemoryError,)),
- 'oonewcustomdict': LLOp(oo=True, canraise=(MemoryError,)),
- 'oonewarray': LLOp(oo=True, canraise=(MemoryError,)),
- 'oosetfield': LLOp(oo=True),
- 'oogetfield': LLOp(oo=True, sideeffects=False, canrun=True),
- 'oosend': LLOp(oo=True, canraise=(Exception,)),
- 'ooupcast': LLOp(oo=True, canfold=True),
- 'oodowncast': LLOp(oo=True, canfold=True),
- 'cast_to_object': LLOp(oo=True, canfold=True),
- 'cast_from_object': LLOp(oo=True, canfold=True),
- 'oononnull': LLOp(oo=True, canfold=True),
- 'ooisnot': LLOp(oo=True, canfold=True),
- 'ooisnull': LLOp(oo=True, canfold=True),
- 'oois': LLOp(oo=True, canfold=True),
- 'instanceof': LLOp(oo=True, canfold=True),
- 'classof': LLOp(oo=True, canfold=True),
- 'subclassof': LLOp(oo=True, canfold=True),
- 'oostring': LLOp(oo=True, sideeffects=False),
- 'oobox_int': LLOp(oo=True, sideeffects=False),
- 'oounbox_int': LLOp(oo=True, sideeffects=False),
- 'ooparse_int': LLOp(oo=True, canraise=(ValueError,)),
- 'ooparse_float': LLOp(oo=True, canraise=(ValueError,)),
- 'oounicode': LLOp(oo=True, canraise=(UnicodeDecodeError,)),
- }
- # ***** Run test_lloperation after changes. *****
- # __________ operations on PyObjects __________
- from pypy.objspace.flow.operation import FunctionByName
- opimpls = FunctionByName.copy()
- opimpls['is_true'] = bool
- for opname in opimpls:
- LL_OPERATIONS[opname] = LLOp(canraise=(Exception,), pyobj=True)
- LL_OPERATIONS['simple_call'] = LLOp(canraise=(Exception,), pyobj=True)
- del opname, FunctionByName
- # ____________________________________________________________
- # Post-processing
- # Stick the opnames into the LLOp instances
- for opname, opdesc in LL_OPERATIONS.iteritems():
- opdesc.opname = opname
- del opname, opdesc
- # Also export all operations in an attribute-based namespace.
- # Example usage from LL helpers: z = llop.int_add(Signed, x, y)
- for opname, opdesc in LL_OPERATIONS.iteritems():
- setattr(llop, opname, opdesc)
- del opname, opdesc