def constfold(self): args = [] if all(w_arg.foldable() for w_arg in self.args): args = [w_arg.value for w_arg in self.args] # All arguments are constants: call the operator now try: result = self.pyfunc(*args) except Exception as e: from rpython.flowspace.flowcontext import FlowingError msg = "%s%r always raises %s: %s" % ( self.opname, tuple(args), type(e), e) raise FlowingError(msg) else: # don't try to constant-fold operations giving a 'long' # result. The result is probably meant to be sent to # an intmask(), but the 'long' constant confuses the # annotator a lot. if self.can_overflow and type(result) is long: pass # don't constant-fold getslice on lists, either elif self.opname == 'getslice' and type(result) is list: pass # otherwise, fine else: try: return const(result) except WrapException: # type cannot sanely appear in flow graph, # store operation with variable result instead pass
def eval(self, ctx): w_callable = self.args[0] if isinstance(w_callable, Constant): fn = w_callable.value try: sc = SPECIAL_CASES[fn] # TypeError if 'fn' not hashable except (KeyError, TypeError): pass else: from rpython.flowspace.flowcontext import FlowingError raise FlowingError( "should not call %r with keyword arguments" % (fn,)) return ctx.do_op(self)
def constfold(self): from rpython.flowspace.flowcontext import FlowingError if len(self.args) == 3: raise FlowingError( "getattr() with three arguments not supported: %s" % (self,)) w_obj, w_name = self.args # handling special things like sys if (w_obj in NOT_REALLY_CONST and w_name not in NOT_REALLY_CONST[w_obj]): return if w_obj.foldable() and w_name.foldable(): obj, name = w_obj.value, w_name.value try: result = getattr(obj, name) except Exception as e: etype = e.__class__ msg = "getattr(%s, %s) always raises %s: %s" % ( obj, name, etype, e) raise FlowingError(msg) try: return const(result) except WrapException: pass
def sc_gettype(ctx, v_decl): if not isinstance(v_decl, Constant): raise FlowingError( "The argument of cts.gettype() must be a constant.") return const(self.gettype(v_decl.value))
def sc_cast(ctx, v_decl, v_arg): if not isinstance(v_decl, Constant): raise FlowingError( "The first argument of cts.cast() must be a constant.") TP = self.gettype(v_decl.value) return ctx.appcall(rffi.cast, const(TP), v_arg)