File: exceptiondata.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (80 lines) | stat: -rw-r--r-- 3,304 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
from rpython.annotator import model as annmodel
from rpython.annotator.exception import standardexceptions
from rpython.rtyper.llannotation import SomePtr
from rpython.rtyper.rclass import (
    ll_issubclass, ll_type, ll_cast_to_object, getclassrepr, getinstancerepr)

class UnknownException(Exception):
    pass


class ExceptionData(object):
    """Public information for the code generators to help with exceptions."""

    standardexceptions = standardexceptions

    def __init__(self, rtyper):
        # (NB. rclass identifies 'Exception' and 'object')
        r_type = rtyper.rootclass_repr
        r_instance = getinstancerepr(rtyper, None)
        r_type.setup()
        r_instance.setup()
        self.r_exception_type = r_type
        self.r_exception_value = r_instance
        self.lltype_of_exception_type = r_type.lowleveltype
        self.lltype_of_exception_value = r_instance.lowleveltype
        self.rtyper = rtyper

    def finish(self, rtyper):
        bk = rtyper.annotator.bookkeeper
        for cls in self.standardexceptions:
            classdef = bk.getuniqueclassdef(cls)
            getclassrepr(rtyper, classdef).setup()

    def get_standard_ll_exc_instance(self, rtyper, clsdef):
        r_inst = getinstancerepr(rtyper, clsdef)
        example = r_inst.get_reusable_prebuilt_instance()
        example = ll_cast_to_object(example)
        return example

    def get_standard_ll_exc_instance_by_class(self, exceptionclass):
        if exceptionclass not in self.standardexceptions:
            raise UnknownException(exceptionclass)
        clsdef = self.rtyper.annotator.bookkeeper.getuniqueclassdef(
            exceptionclass)
        return self.get_standard_ll_exc_instance(self.rtyper, clsdef)

    def make_helpers(self, rtyper):
        # create helper functionptrs
        self.fn_exception_match  = self.make_exception_matcher(rtyper)
        self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper)

    def make_exception_matcher(self, rtyper):
        # ll_exception_matcher(real_exception_vtable, match_exception_vtable)
        s_typeptr = SomePtr(self.lltype_of_exception_type)
        helper_fn = rtyper.annotate_helper_fn(ll_issubclass, [s_typeptr, s_typeptr])
        return helper_fn

    def make_type_of_exc_inst(self, rtyper):
        # ll_type_of_exc_inst(exception_instance) -> exception_vtable
        s_excinst = SomePtr(self.lltype_of_exception_value)
        helper_fn = rtyper.annotate_helper_fn(ll_type, [s_excinst])
        return helper_fn

    def generate_exception_match(self, oplist, var_etype, const_etype):
        # generate the content of rclass.ll_issubclass(_const)
        from rpython.rtyper.rtyper import LowLevelOpList
        from rpython.rtyper.lltypesystem import lltype
        from rpython.flowspace.model import Constant, Variable, SpaceOperation
        llops = LowLevelOpList(None)
        field = llops.genop(
            'getfield', [var_etype, llops.genvoidconst('subclassrange_min')], lltype.Signed)
        res = llops.genop(
            'int_between', [
                llops.genconst(const_etype.value.subclassrange_min),
                field,
                llops.genconst(const_etype.value.subclassrange_max),
            ],
            lltype.Bool)
        oplist.extend(llops)
        return res