Beispiel #1
0
    def test_del_inheritance(self):
        from rpython.rlib import rgc

        class State:
            pass

        s = State()
        s.a_dels = 0
        s.b_dels = 0

        class A(object):
            def __del__(self):
                s.a_dels += 1

        class B(A):
            def __del__(self):
                s.b_dels += 1

        class C(A):
            pass

        def f():
            A()
            B()
            C()
            A()
            B()
            C()
            rgc.collect()
            return s.a_dels * 10 + s.b_dels

        res = f()
        assert res == 42
        t = TranslationContext()
        t.buildannotator().build_types(f, [])
        t.buildrtyper().specialize()
        graph = graphof(t, f)
        TYPEA = graph.startblock.operations[0].args[0].value
        RTTIA = getRuntimeTypeInfo(TYPEA)
        TYPEB = graph.startblock.operations[3].args[0].value
        RTTIB = getRuntimeTypeInfo(TYPEB)
        TYPEC = graph.startblock.operations[6].args[0].value
        RTTIC = getRuntimeTypeInfo(TYPEC)
        queryptra = RTTIA._obj.query_funcptr  # should not raise
        queryptrb = RTTIB._obj.query_funcptr  # should not raise
        queryptrc = RTTIC._obj.query_funcptr  # should not raise
        destrptra = RTTIA._obj.destructor_funcptr
        destrptrb = RTTIB._obj.destructor_funcptr
        destrptrc = RTTIC._obj.destructor_funcptr
        assert destrptra == destrptrc
        assert typeOf(destrptra).TO.ARGS[0] != typeOf(destrptrb).TO.ARGS[0]
        assert destrptra is not None
        assert destrptrb is not None
Beispiel #2
0
def find_malloc_creps(graph, adi, translator, malloc_graphs):
    # mapping from malloc creation point to graphs that it flows into
    malloc_creps = {}
    # find all mallocs that don't escape
    for block, op in graph.iterblockops():
        if op.opname == "malloc":
            STRUCT = op.args[0].value
            # must not remove mallocs of structures that have a RTTI with a destructor
            flags = op.args[1].value
            if flags != {"flavor": "gc"}:
                continue
            try:
                destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
                if destr_ptr:
                    continue
            except (ValueError, AttributeError):
                pass
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep, = varstate.creation_points
            if not crep.escapes and not crep.returns:
                malloc_creps[crep] = {}
        if op.opname == "direct_call":
            called_graph = get_graph(op.args[0], translator)
            if called_graph not in malloc_graphs:
                continue
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep, = varstate.creation_points
            if not crep.escapes and not crep.returns:
                malloc_creps[crep] = {}
    return malloc_creps
Beispiel #3
0
def get_rtti(TYPE):
    if isinstance(TYPE, lltype.RttiStruct):
        try:
            return lltype.getRuntimeTypeInfo(TYPE)
        except ValueError:
            pass
    return None
Beispiel #4
0
 def test_del_inheritance(self):
     from rpython.rlib import rgc
     class State:
         pass
     s = State()
     s.a_dels = 0
     s.b_dels = 0
     class A(object):
         def __del__(self):
             s.a_dels += 1
     class B(A):
         def __del__(self):
             s.b_dels += 1
     class C(A):
         pass
     def f():
         A()
         B()
         C()
         A()
         B()
         C()
         rgc.collect()
         return s.a_dels * 10 + s.b_dels
     res = f()
     assert res == 42
     t = TranslationContext()
     t.buildannotator().build_types(f, [])
     t.buildrtyper().specialize()
     graph = graphof(t, f)
     TYPEA = graph.startblock.operations[0].args[0].value
     RTTIA = getRuntimeTypeInfo(TYPEA)
     TYPEB = graph.startblock.operations[3].args[0].value
     RTTIB = getRuntimeTypeInfo(TYPEB)
     TYPEC = graph.startblock.operations[6].args[0].value
     RTTIC = getRuntimeTypeInfo(TYPEC)
     queryptra = RTTIA._obj.query_funcptr # should not raise
     queryptrb = RTTIB._obj.query_funcptr # should not raise
     queryptrc = RTTIC._obj.query_funcptr # should not raise
     destrptra = RTTIA._obj.destructor_funcptr
     destrptrb = RTTIB._obj.destructor_funcptr
     destrptrc = RTTIC._obj.destructor_funcptr
     assert destrptra == destrptrc
     assert typeOf(destrptra).TO.ARGS[0] != typeOf(destrptrb).TO.ARGS[0]
     assert destrptra is not None
     assert destrptrb is not None
Beispiel #5
0
 def RTTI_dtor(self, STRUCT):
     try:
         destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
         if destr_ptr:
             return True
     except (ValueError, AttributeError):
         pass
     return False
Beispiel #6
0
 def check_no_destructor(self):
     STRUCT = self.MALLOCTYPE
     try:
         rttiptr = lltype.getRuntimeTypeInfo(STRUCT)
     except ValueError:
         return  # ok
     destr_ptr = getattr(rttiptr._obj, 'destructor_funcptr', None)
     if destr_ptr:
         raise CannotRemoveThisType
Beispiel #7
0
 def check_no_destructor(self):
     STRUCT = self.MALLOCTYPE
     try:
         rttiptr = lltype.getRuntimeTypeInfo(STRUCT)
     except ValueError:
         return    # ok
     destr_ptr = getattr(rttiptr._obj, 'destructor_funcptr', None)
     if destr_ptr:
         raise CannotRemoveThisType
Beispiel #8
0
    def setup_vtable(self, vtable, rsubcls):
        """Initialize the 'self' portion of the 'vtable' belonging to the
        given subclass."""
        if self.classdef is None:
            vtable.hash = hash(rsubcls)
            # initialize the 'subclassrange_*' and 'name' fields
            if rsubcls.classdef is not None:
                #vtable.parenttypeptr = rsubcls.rbase.getvtable()
                vtable.subclassrange_min = rsubcls.classdef.minid
                vtable.subclassrange_max = rsubcls.classdef.maxid
            else: #for the root class
                vtable.subclassrange_min = 0
                vtable.subclassrange_max = sys.maxint
            rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
            rinstance.setup()
            if rinstance.gcflavor == 'gc':
                vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
            if rsubcls.classdef is None:
                name = 'object'
            else:
                name = rsubcls.classdef.shortname
            vtable.name = alloc_array_name(name)
            if hasattr(rsubcls.classdef, 'my_instantiate_graph'):
                graph = rsubcls.classdef.my_instantiate_graph
                vtable.instantiate = self.rtyper.getcallable(graph)
            #else: the classdef was created recently, so no instantiate()
            #      could reach it
        else:
            # setup class attributes: for each attribute name at the level
            # of 'self', look up its value in the subclass rsubcls
            def assign(mangled_name, value):
                if isinstance(value, Constant) and isinstance(value.value, staticmethod):
                    value = Constant(value.value.__get__(42))   # staticmethod => bare function
                llvalue = r.convert_desc_or_const(value)
                setattr(vtable, mangled_name, llvalue)

            mro = list(rsubcls.classdef.getmro())
            for fldname in self.clsfields:
                mangled_name, r = self.clsfields[fldname]
                if r.lowleveltype is Void:
                    continue
                value = rsubcls.classdef.classdesc.read_attribute(fldname, None)
                if value is not None:
                    assign(mangled_name, value)
            # extra PBC attributes
            for (access_set, attr), (mangled_name, r) in self.pbcfields.items():
                if rsubcls.classdef.classdesc not in access_set.descs:
                    continue   # only for the classes in the same pbc access set
                if r.lowleveltype is Void:
                    continue
                attrvalue = rsubcls.classdef.classdesc.read_attribute(attr, None)
                if attrvalue is not None:
                    assign(mangled_name, attrvalue)

            # then initialize the 'super' portion of the vtable
            self.rbase.setup_vtable(vtable.super, rsubcls)
Beispiel #9
0
def test_runtime_type_info():
    S = lltype.GcStruct('s', ('x', lltype.Signed), rtti=True)
    def ll_example(p):
        return (lltype.runtime_type_info(p),
                lltype.runtime_type_info(p) == lltype.getRuntimeTypeInfo(S))

    assert ll_example(lltype.malloc(S)) == (lltype.getRuntimeTypeInfo(S), True)
    s, t = ll_rtype(ll_example, [SomePtr(lltype.Ptr(S))])
    assert s == annmodel.SomeTuple([SomePtr(lltype.Ptr(lltype.RuntimeTypeInfo)),
                                    annmodel.SomeBool()])
Beispiel #10
0
def can_remove(op):
    S = op.args[0].value
    if op.args[1].value != {'flavor': 'gc'}:
        return False
    try:
        # cannot remove if there is a destructor
        destr_ptr = lltype.getRuntimeTypeInfo(S)._obj.destructor_funcptr
        if destr_ptr:
            return False
    except (ValueError, AttributeError):
        pass
    return True
Beispiel #11
0
def test_runtime_type_info():
    S = lltype.GcStruct('s', ('x', lltype.Signed), rtti=True)

    def ll_example(p):
        return (lltype.runtime_type_info(p),
                lltype.runtime_type_info(p) == lltype.getRuntimeTypeInfo(S))

    assert ll_example(lltype.malloc(S)) == (lltype.getRuntimeTypeInfo(S), True)
    s, t = ll_rtype(ll_example, [SomePtr(lltype.Ptr(S))])
    assert s == annmodel.SomeTuple(
        [SomePtr(lltype.Ptr(lltype.RuntimeTypeInfo)),
         annmodel.SomeBool()])
Beispiel #12
0
 def computegcinfo(self, gcpolicy):
     # let the gcpolicy do its own setup
     self.gcinfo = None   # unless overwritten below
     rtti = None
     STRUCT = self.STRUCT
     if isinstance(STRUCT, RttiStruct):
         try:
             rtti = getRuntimeTypeInfo(STRUCT)
         except ValueError:
             pass
     if self.varlength is None:
         gcpolicy.struct_setup(self, rtti)
     return self.gcinfo
Beispiel #13
0
 def computegcinfo(self, gcpolicy):
     # let the gcpolicy do its own setup
     self.gcinfo = None   # unless overwritten below
     rtti = None
     STRUCT = self.STRUCT
     if isinstance(STRUCT, RttiStruct):
         try:
             rtti = getRuntimeTypeInfo(STRUCT)
         except ValueError:
             pass
     if self.varlength is None:
         gcpolicy.struct_setup(self, rtti)
     return self.gcinfo
Beispiel #14
0
 def test__del__(self):
     class A(object):
         def __init__(self):
             self.a = 2
         def __del__(self):
             self.a = 3
     def f():
         a = A()
         return a.a
     t = TranslationContext()
     t.buildannotator().build_types(f, [])
     t.buildrtyper().specialize()
     graph = graphof(t, f)
     TYPE = graph.startblock.operations[0].args[0].value
     RTTI = getRuntimeTypeInfo(TYPE)
     RTTI._obj.query_funcptr # should not raise
     destrptr = RTTI._obj.destructor_funcptr
     assert destrptr is not None
Beispiel #15
0
 def test__del__(self):
     class A(object):
         def __init__(self):
             self.a = 2
         def __del__(self):
             self.a = 3
     def f():
         a = A()
         return a.a
     t = TranslationContext()
     t.buildannotator().build_types(f, [])
     t.buildrtyper().specialize()
     graph = graphof(t, f)
     TYPE = graph.startblock.operations[0].args[0].value
     RTTI = getRuntimeTypeInfo(TYPE)
     RTTI._obj.query_funcptr # should not raise
     destrptr = RTTI._obj.destructor_funcptr
     assert destrptr is not None
Beispiel #16
0
 def fill_vtable_root(self, vtable):
     """Initialize the head of the vtable."""
     # initialize the 'subclassrange_*' and 'name' fields
     if self.classdef is not None:
         vtable.subclassrange_min = self.classdef.minid
         vtable.subclassrange_max = self.classdef.maxid
     else:  # for the root class
         vtable.subclassrange_min = 0
         vtable.subclassrange_max = sys.maxint
     rinstance = getinstancerepr(self.rtyper, self.classdef)
     rinstance.setup()
     if rinstance.gcflavor == 'gc':
         vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
     if self.classdef is None:
         name = 'object'
     else:
         name = self.classdef.shortname
     vtable.name = alloc_array_name(name)
     if hasattr(self.classdef, 'my_instantiate_graph'):
         graph = self.classdef.my_instantiate_graph
         vtable.instantiate = self.rtyper.getcallable(graph)
Beispiel #17
0
 def fill_vtable_root(self, vtable):
     """Initialize the head of the vtable."""
     vtable.hash = hash(self)
     # initialize the 'subclassrange_*' and 'name' fields
     if self.classdef is not None:
         #vtable.parenttypeptr = self.rbase.getvtable()
         vtable.subclassrange_min = self.classdef.minid
         vtable.subclassrange_max = self.classdef.maxid
     else:  # for the root class
         vtable.subclassrange_min = 0
         vtable.subclassrange_max = sys.maxint
     rinstance = getinstancerepr(self.rtyper, self.classdef)
     rinstance.setup()
     if rinstance.gcflavor == 'gc':
         vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
     if self.classdef is None:
         name = 'object'
     else:
         name = self.classdef.shortname
     vtable.name = alloc_array_name(name)
     if hasattr(self.classdef, 'my_instantiate_graph'):
         graph = self.classdef.my_instantiate_graph
         vtable.instantiate = self.rtyper.getcallable(graph)
Beispiel #18
0
 def type_info_S(s):
     return lltype.getRuntimeTypeInfo(S)
Beispiel #19
0
 def ll_example(p):
     return (lltype.runtime_type_info(p),
             lltype.runtime_type_info(p) == lltype.getRuntimeTypeInfo(S))
Beispiel #20
0
 def type_info_S(s):
     return lltype.getRuntimeTypeInfo(S)
Beispiel #21
0
 def ll_example(p):
     return (lltype.runtime_type_info(p),
             lltype.runtime_type_info(p) == lltype.getRuntimeTypeInfo(S))
Beispiel #22
0
def getRuntimeTypeInfo(T):
    assert T.is_constant()
    return immutablevalue(lltype.getRuntimeTypeInfo(T.const))
Beispiel #23
0
 def type_info_T(p):
     return lltype.getRuntimeTypeInfo(T)
Beispiel #24
0
    def setup_vtable(self, vtable, rsubcls):
        """Initialize the 'self' portion of the 'vtable' belonging to the
        given subclass."""
        if self.classdef is None:
            vtable.hash = hash(rsubcls)
            # initialize the 'subclassrange_*' and 'name' fields
            if rsubcls.classdef is not None:
                #vtable.parenttypeptr = rsubcls.rbase.getvtable()
                vtable.subclassrange_min = rsubcls.classdef.minid
                vtable.subclassrange_max = rsubcls.classdef.maxid
            else:  #for the root class
                vtable.subclassrange_min = 0
                vtable.subclassrange_max = sys.maxint
            rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
            rinstance.setup()
            if rinstance.gcflavor == 'gc':
                vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
            if rsubcls.classdef is None:
                name = 'object'
            else:
                name = rsubcls.classdef.shortname
            vtable.name = alloc_array_name(name)
            if hasattr(rsubcls.classdef, 'my_instantiate_graph'):
                graph = rsubcls.classdef.my_instantiate_graph
                vtable.instantiate = self.rtyper.getcallable(graph)
            #else: the classdef was created recently, so no instantiate()
            #      could reach it
        else:
            # setup class attributes: for each attribute name at the level
            # of 'self', look up its value in the subclass rsubcls
            def assign(mangled_name, value):
                if isinstance(value, Constant) and isinstance(
                        value.value, staticmethod):
                    value = Constant(value.value.__get__(
                        42))  # staticmethod => bare function
                llvalue = r.convert_desc_or_const(value)
                setattr(vtable, mangled_name, llvalue)

            mro = list(rsubcls.classdef.getmro())
            for fldname in self.clsfields:
                mangled_name, r = self.clsfields[fldname]
                if r.lowleveltype is Void:
                    continue
                value = rsubcls.classdef.classdesc.read_attribute(
                    fldname, None)
                if value is not None:
                    assign(mangled_name, value)
            # extra PBC attributes
            for (access_set, attr), (mangled_name,
                                     r) in self.pbcfields.items():
                if rsubcls.classdef.classdesc not in access_set.descs:
                    continue  # only for the classes in the same pbc access set
                if r.lowleveltype is Void:
                    continue
                attrvalue = rsubcls.classdef.classdesc.read_attribute(
                    attr, None)
                if attrvalue is not None:
                    assign(mangled_name, attrvalue)

            # then initialize the 'super' portion of the vtable
            self.rbase.setup_vtable(vtable.super, rsubcls)
Beispiel #25
0
 def type_info_T(p):
     return lltype.getRuntimeTypeInfo(T)