Source

frompypy.translator.backendoptimportgraphanalyzefrompypy.rpython.lltypesystemimportlltypeclassFinalizerError(Exception):""" __del__ marked as lightweight finalizer, but the analyzer did not agree """classFinalizerAnalyzer(graphanalyze.BoolGraphAnalyzer):""" Analyzer that determines whether a finalizer is lightweight enough so it can be called without all the complicated logic in the garbage collector. The set of operations here is restrictive for a good reason - it's better to be safe. Specifically disallowed operations: * anything that escapes self * anything that can allocate """ok_operations=['ptr_nonzero','ptr_eq','ptr_ne','free','same_as','direct_ptradd','force_cast','track_alloc_stop','raw_free']defanalyze_light_finalizer(self,graph):result=self.analyze_direct_call(graph)if(resultisself.top_result()andgetattr(graph.func,'_must_be_light_finalizer_',False)):raiseFinalizerError(FinalizerError.__doc__,graph)returnresultdefanalyze_simple_operation(self,op,graphinfo):ifop.opnameinself.ok_operations:returnself.bottom_result()if(op.opname.startswith('int_')orop.opname.startswith('float_')orop.opname.startswith('cast_')):returnself.bottom_result()ifop.opname=='setfield'orop.opname=='bare_setfield':TP=op.args[2].concretetypeifnotisinstance(TP,lltype.Ptr)orTP.TO._gckind=='raw':# primitive typereturnself.bottom_result()ifop.opname=='getfield':TP=op.result.concretetypeifnotisinstance(TP,lltype.Ptr)orTP.TO._gckind=='raw':# primitive typereturnself.bottom_result()returnself.top_result()