def check_inline(self, func, in_func, sig, entry=None, inline_guarded_calls=False, graph=False): if entry is None: entry = in_func t = self.translate(entry, sig) # inline! sanity_check(t) # also check before inlining (so we don't blame it) if option.view: t.view() raise_analyzer = canraise.RaiseAnalyzer(t) inliner = Inliner(t, graphof(t, in_func), func, t.rtyper.lltype_to_classdef_mapping(), inline_guarded_calls, raise_analyzer=raise_analyzer) inliner.inline_all() if option.view: t.view() sanity_check(t) interp = LLInterpreter(t.rtyper) def eval_func(args): return interp.eval_graph(graphof(t, entry), args) if graph: return eval_func, graphof(t, func) return eval_func
def __init__(self, translator): self.translator = translator self.raise_analyzer = canraise.RaiseAnalyzer(translator) edata = translator.rtyper.exceptiondata self.lltype_of_exception_value = edata.lltype_of_exception_value self.lltype_of_exception_type = edata.lltype_of_exception_type self.mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper) exc_data, null_type, null_value = self.setup_excdata() (assertion_error_ll_exc_type, assertion_error_ll_exc) = self.get_builtin_exception(AssertionError) (n_i_error_ll_exc_type, n_i_error_ll_exc) = self.get_builtin_exception(NotImplementedError) self.c_assertion_error_ll_exc_type = constant_value( assertion_error_ll_exc_type) self.c_n_i_error_ll_exc_type = constant_value(n_i_error_ll_exc_type) def rpyexc_occured(): exc_type = exc_data.exc_type return bool(exc_type) def rpyexc_fetch_type(): return exc_data.exc_type def rpyexc_fetch_value(): return exc_data.exc_value def rpyexc_clear(): exc_data.exc_type = null_type exc_data.exc_value = null_value def rpyexc_raise(etype, evalue): # When compiling in debug mode, the following ll_asserts will # crash the program as soon as it raises AssertionError or # NotImplementedError. Useful when you are in a debugger. # When compiling in release mode, AssertionErrors and # NotImplementedErrors are raised normally, and only later # caught by debug_catch_exception and printed, which allows # us to see at least part of the traceback for them. ll_assert(etype != assertion_error_ll_exc_type, "AssertionError") ll_assert(etype != n_i_error_ll_exc_type, "NotImplementedError") exc_data.exc_type = etype exc_data.exc_value = evalue lloperation.llop.debug_start_traceback(lltype.Void, etype) def rpyexc_reraise(etype, evalue): exc_data.exc_type = etype exc_data.exc_value = evalue lloperation.llop.debug_reraise_traceback(lltype.Void, etype) def rpyexc_fetch_exception(): evalue = rpyexc_fetch_value() rpyexc_clear() return evalue def rpyexc_restore_exception(evalue): if evalue: exc_data.exc_type = ll_inst_type(evalue) exc_data.exc_value = evalue self.rpyexc_occured_ptr = self.build_func("RPyExceptionOccurred", rpyexc_occured, [], lltype.Bool) self.rpyexc_fetch_type_ptr = self.build_func( "RPyFetchExceptionType", rpyexc_fetch_type, [], self.lltype_of_exception_type) self.rpyexc_fetch_value_ptr = self.build_func( "RPyFetchExceptionValue", rpyexc_fetch_value, [], self.lltype_of_exception_value) self.rpyexc_clear_ptr = self.build_func("RPyClearException", rpyexc_clear, [], lltype.Void) self.rpyexc_raise_ptr = self.build_func( "RPyRaiseException", self.noinline(rpyexc_raise), [self.lltype_of_exception_type, self.lltype_of_exception_value], lltype.Void, jitcallkind='rpyexc_raise') # for the JIT self.rpyexc_reraise_ptr = self.build_func( "RPyReRaiseException", rpyexc_reraise, [self.lltype_of_exception_type, self.lltype_of_exception_value], lltype.Void, jitcallkind='rpyexc_raise') # for the JIT self.rpyexc_fetch_exception_ptr = self.build_func( "RPyFetchException", rpyexc_fetch_exception, [], self.lltype_of_exception_value) self.rpyexc_restore_exception_ptr = self.build_func( "RPyRestoreException", self.noinline(rpyexc_restore_exception), [self.lltype_of_exception_value], lltype.Void) self.build_extra_funcs() self.mixlevelannotator.finish() self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping( )