pypy / pypy / interpreter /

This module defines the abstract base classes that support execution:
Code and Frame.
from pypy.interpreter.error import OperationError
from pypy.interpreter.baseobjspace import Wrappable

class Code(Wrappable):
    """A code is a compiled version of some source code.
    Abstract base class."""
    _immutable_ = True
    hidden_applevel = False

    # n >= 0 : arity
    # FLATPYCALL = 0x100
    # n|FLATPYCALL: pycode flat case
    # FLATPYCALL<<x (x>=1): special cases
    # HOPELESS: hopeless
    FLATPYCALL = 0x100
    HOPELESS = 0x400
    fast_natural_arity = HOPELESS

    def __init__(self, co_name):
        self.co_name = co_name

    def exec_code(self, space, w_globals, w_locals):
        "Implements the 'exec' statement."
        # this should be on PyCode?
        frame = space.createframe(self, w_globals, None)

    def signature(self):
        raise NotImplementedError

    def getvarnames(self):
        """List of names including the arguments, vararg and kwarg,
        and possibly more locals."""
        return self.signature().getallvarnames()

    def getformalargcount(self):
        return self.signature().scope_length()

    def getdocstring(self, space):
        return space.w_None

    def funcrun(self, func, args):
        raise NotImplementedError("purely abstract")

    def funcrun_obj(self, func, w_obj, args):
        return self.funcrun(func, args.prepend(w_obj))

class Frame(Wrappable):
    """A frame is an environment supporting the execution of a code object.
    Abstract base class."""

    def __init__(self, space, w_globals=None):      = space
        self.w_globals  = w_globals  # wrapped dict of globals
        self.w_locals   = None       # wrapped dict of locals

    def run(self):
        "Abstract method to override. Runs the frame"
        raise TypeError, "abstract"
    def getdictscope(self):
        "Get the locals as a dictionary."
        return self.w_locals

    def getcode(self):
        return None

    def fget_code(self, space):
        return space.wrap(self.getcode())

    def fget_getdictscope(self, space):
        return self.getdictscope()

    def setdictscope(self, w_locals):
        "Initialize the locals from a dictionary."
        self.w_locals = w_locals

    def getfastscope(self):
        "Abstract. Get the fast locals as a list."
        raise TypeError, "abstract"

    def setfastscope(self, scope_w):
        """Abstract. Initialize the fast locals from a list of values,
        where the order is according to self.getcode().signature()."""
        raise TypeError, "abstract"

    def getfastscopelength(self):
        "Abstract. Get the expected number of locals."
        raise TypeError, "abstract"

    def fast2locals(self):
        # Copy values from the fastlocals to self.w_locals
        if self.w_locals is None:
            self.w_locals =
        varnames = self.getcode().getvarnames()
        fastscope_w = self.getfastscope()
        for i in range(min(len(varnames), self.getfastscopelength())):
            name = varnames[i]
            w_value = fastscope_w[i]
            if w_value is not None:
                w_name =
      , w_name, w_value)

    def locals2fast(self):
        # Copy values from self.w_locals to the fastlocals
        assert self.w_locals is not None
        varnames = self.getcode().getvarnames()
        numlocals = self.getfastscopelength()

        new_fastlocals_w = [None] * numlocals

        for i in range(min(len(varnames), numlocals)):
            w_name =[i])
                w_value =, w_name)
            except OperationError, e:
                if not e.match(,
                new_fastlocals_w[i] = w_value