from pypy.translator.translator import TranslationContext from pypy import conftest from py.test import raises def get_annotation(func): argstypelist = [] if func.func_defaults: for spec in func.func_defaults: if isinstance(spec, tuple): # use the first type only for the tests spec = spec[0] argstypelist.append(spec) missing = [object] * (func.func_code.co_argcount - len(argstypelist)) return missing + argstypelist def getcompiled(func, view=conftest.option.view, inline_threshold=1, use_boehm=False): from pypy.translator.translator import TranslationContext from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.c import gc from pypy.translator.c.genc import CExtModuleBuilder global t # allow us to view later t = TranslationContext() t.buildannotator().build_types(func, get_annotation(func)) if view: t.viewcg() t.buildrtyper().specialize() if view: t.viewcg() t.checkgraphs() gcpolicy = None if use_boehm: gcpolicy = gc.BoehmGcPolicy cbuilder = CExtModuleBuilder(t, func, gcpolicy=gcpolicy) cbuilder.generate_source() cbuilder.compile() if view: t.viewcg() backend_optimizations(t, inline_threshold=inline_threshold) if view: t.viewcg() return getattr(cbuilder.import_module(), func.__name__) class DemoClass(object): def __init__(self, a, b): self.a = a self.b = b print 'init' def demo(self): print 'demo' return self.a + self.b def __del__(self): print 'del' def democlass_helper(a=int, b=int): inst = DemoClass(a, b) #ret = inst.demo() ret = create_pywrapper(inst) print 'del now' ret = 42 return ret, long(42) #, call_destructor(inst) from pypy.rpython import extregistry def create_pywrapper(thing): RaiseNameError create_pywrapper._annspecialcase_ = "specialize:argtype(0)" def call_destructor(thing): return ll_call_destructor(thing) # <<========== if you use return here # then we crash in backend_optimizations def ll_call_destructor(thang): return 42 from pypy.annotation import model as annmodel from pypy.rpython.rbuiltin import BUILTIN_TYPER from pypy.rpython.lltypesystem import lltype def rtype_wrap_object(hop): v_any, = hop.inputargs(hop.args_r[0]) # XXX no direct interface to gencapicall f = call_destructor hop.genop('gc_protect', [v_any]) ARGTYPE = lltype.Ptr(lltype.GcStruct('dummy')) FUNCTYPE = lltype.FuncType([ARGTYPE], lltype.Void) fp_dtor = hop.rtyper.annotate_helper_fn(f, [ARGTYPE]) c_dtor = hop.inputconst(lltype.Ptr(FUNCTYPE), fp_dtor) return hop.llops.gencapicall('PyCObject_FromVoidPtr', [v_any, c_dtor], resulttype=hop.r_result) def rtype_destruct_object(hop): v_any, = hop.inputargs(hop.args_r[0]) return hop.genop('gc_unprotect', [v_any], resulttype=lltype.Void) extregistry.register_value(create_pywrapper, compute_result_annotation=annmodel.SomeObject(), specialize_call=rtype_wrap_object) extregistry.register_value(ll_call_destructor, compute_result_annotation=lambda *s_args: None, specialize_call=rtype_destruct_object) #from pypy.annotation.registry import registerSomeObject #registerSomeObject(DemoClass, 0) def test_obj(): f = getcompiled(democlass_helper, use_boehm=not True) ret = f(2, 3)