File: objspace.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 (53 lines) | stat: -rw-r--r-- 1,931 bytes parent folder | download | duplicates (5)
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
"""Implements the main interface for flow graph creation: build_flow().
"""

from inspect import CO_NEWLOCALS, isgeneratorfunction

from rpython.flowspace.model import checkgraph
from rpython.flowspace.bytecode import HostCode
from rpython.flowspace.flowcontext import (FlowContext, fixeggblocks)
from rpython.flowspace.generator import (tweak_generator_graph,
        make_generator_entry_graph)
from rpython.flowspace.pygraph import PyGraph


def _assert_rpythonic(func):
    """Raise ValueError if ``func`` is obviously not RPython"""
    try:
        func.__code__.co_cellvars
    except AttributeError:
        raise ValueError("%r is not RPython: it is likely an unexpected "
                         "built-in function or type" % (func,))
    if getattr(func, "_not_rpython_", False):
        raise ValueError("%r is tagged as @not_rpython" % (func,))
    if func.__doc__ and func.__doc__.lstrip().startswith('NOT_RPYTHON'):
        raise ValueError("%r is tagged as NOT_RPYTHON" % (func,))
    if func.__code__.co_cellvars:
        raise ValueError(
"""RPython functions cannot create closures
Possible causes:
    Function is inner function
    Function uses generator expressions
    Lambda expressions
in %r""" % (func,))
    if not (func.__code__.co_flags & CO_NEWLOCALS):
        raise ValueError("The code object for a RPython function should have "
                         "the flag CO_NEWLOCALS set.")


def build_flow(func):
    """
    Create the flow graph (in SSA form) for the function.
    """
    _assert_rpythonic(func)
    if (isgeneratorfunction(func) and
            not hasattr(func, '_generator_next_method_of_')):
        return make_generator_entry_graph(func)
    code = HostCode._from_code(func.__code__)
    graph = PyGraph(func, code)
    ctx = FlowContext(graph, code)
    ctx.build_flow()
    fixeggblocks(graph)
    if code.is_generator:
        tweak_generator_graph(graph)
    return graph