frompypy.translator.backendopt.supportimportlog,all_operations,annotateimportpypy.rpython.raisingops.raisingopslog=log.raisingop2directcalldefis_raisingop(op):s=op.opnameif(nots.startswith('int_')andnots.startswith('uint_')andnots.startswith('float_')andnots.startswith('llong_')):returnFalseifnots.endswith('_zer')andnots.endswith('_ovf')andnots.endswith('_val'):#not s in special_operations:returnFalsereturnTruedefraisingop2direct_call(translator,graphs=None):"""search for operations that could raise an exception and change that operation into a direct_call to a function from the raisingops directory. This function also needs to be annotated and specialized. note: this could be extended to allow for any operation to be changed into a direct_call to a (RPython) function! """#special_operations = "int_floordiv int_mod".split()ifgraphsisNone:graphs=translator.graphslog('starting')seen={}foropinall_operations(graphs):ifnotis_raisingop(op):continuefunc=getattr(pypy.rpython.raisingops.raisingops,op.opname,None)ifnotfunc:log.warning("%s not found"%op.opname)continueifop.opnamenotinseen:seen[op.opname]=0seen[op.opname]+=1op.args.insert(0,annotate(translator,func,op.result,op.args))op.opname='direct_call'#statistics...fork,vinseen.iteritems():log("%dx %s"%(v,k))#specialize newly annotated functionsifseen!={}:translator.rtyper.specialize_more_blocks()#rename some operations (that were introduced in the newly specialized graphs)#so this transformation becomes idempotent...#for op in all_operations(graphs):# if op.opname in special_operations:# log('renamed %s to %s_' % (op.opname, op.opname))# op.opname += '_'#selfdiagnostics... assert that there are no more raisingopsforopinall_operations(graphs):ifis_raisingop(op):log.warning("%s not transformed"%op.opname)#translator.view()log('finished')