Exemplo n.º 1
0
    def __init__(self, config=None):
        "NOT_RPYTHON: Basic initialization of objects."
        self.fromcache = InternalSpaceCache(self).getorbuild
        self.threadlocals = ThreadLocals()
        # set recursion limit
        # sets all the internal descriptors
        if config is None:
            from pypy.config.pypyoption import get_pypy_config
            config = get_pypy_config(translating=False)
        self.config = config

        # import extra modules for side-effects
        import pypy.interpreter.nestedscope  # register *_DEREF bytecodes

        self.interned_strings = {}
        self.actionflag = ActionFlag()  # changed by the signal module
        self.user_del_action = UserDelAction(self)
        self.frame_trace_action = FrameTraceAction(self)
        self.actionflag.register_action(self.user_del_action)
        self.actionflag.register_action(self.frame_trace_action)

        from pypy.interpreter.pyframe import PyFrame
        self.FrameClass = PyFrame  # can be overridden to a subclass

        #        if self.config.objspace.logbytecodes:
        #            self.bytecodecounts = {}

        self.initialize()
Exemplo n.º 2
0
    def test_periodic_action(self):
        from pypy.interpreter.executioncontext import ActionFlag

        class DemoAction(executioncontext.PeriodicAsyncAction):
            counter = 0

            def perform(self, ec, frame):
                self.counter += 1
                print '->', self.counter
                if self.counter == 3:
                    raise Finished

        space = self.space
        a2 = DemoAction(space)
        try:
            space.actionflag.setcheckinterval(100)
            space.actionflag.register_periodic_action(a2, True)
            try:
                for i in range(500):
                    space.appexec([], """():
                        n = 5
                        return n + 2
                    """)
            except Finished:
                pass
        finally:
            space.actionflag = ActionFlag()  # reset to default
        assert 10 < i < 110
Exemplo n.º 3
0
    def __init__(self, config=None):
        "NOT_RPYTHON: Basic initialization of objects."
        self.fromcache = InternalSpaceCache(self).getorbuild
        self.threadlocals = ThreadLocals()
        # set recursion limit
        # sets all the internal descriptors
        if config is None:
            from pypy.config.pypyoption import get_pypy_config
            config = get_pypy_config(translating=False)
        self.config = config

        # import extra modules for side-effects
        import pypy.interpreter.nestedscope     # register *_DEREF bytecodes

        self.interned_strings = {}
        self.actionflag = ActionFlag()    # changed by the signal module
        self.user_del_action = UserDelAction(self)
        self.frame_trace_action = FrameTraceAction(self)
        self.actionflag.register_action(self.user_del_action)
        self.actionflag.register_action(self.frame_trace_action)

        from pypy.interpreter.pyframe import PyFrame
        self.FrameClass = PyFrame    # can be overridden to a subclass

        if self.config.objspace.logbytecodes:
            self.bytecodecounts = [0] * 256
            self.bytecodetransitioncount = {}

        if self.config.objspace.timing:
            self.timer = Timer()
        else:
            self.timer = DummyTimer()

        self.initialize()
Exemplo n.º 4
0
    def __init__(self, config=None):
        """NOT_RPYTHON"""
        self.fromcache = InternalSpaceCache(self).getorbuild
        self.w_Ellipsis = special.Ellipsis()
        self.w_NotImplemented = special.NotImplemented()

        if config is None:
            from pypy.config.pypyoption import get_pypy_config
            config = get_pypy_config(translating=False)
        self.config = config

        self.interned_strings = make_weak_value_dictionary(self, str, W_Root)
        self.builtin = DictObject({})
        self.FrameClass = PyFrame
        self.threadlocals = ThreadLocals()
        self.actionflag = ActionFlag()  # changed by the signal module
        self.check_signal_action = None  # changed by the signal module
Exemplo n.º 5
0
class ObjSpace(object):
    """Base class for the interpreter-level implementations of object spaces.
    http://codespeak.net/pypy/dist/pypy/doc/objspace.html"""

    full_exceptions = True  # full support for exceptions (normalization & more)
    
    namespace_table = {}

    def __init__(self, config=None):
        "NOT_RPYTHON: Basic initialization of objects."
        self.fromcache = InternalSpaceCache(self).getorbuild
        self.threadlocals = ThreadLocals()
        # set recursion limit
        # sets all the internal descriptors
        if config is None:
            from pypy.config.pypyoption import get_pypy_config
            config = get_pypy_config(translating=False)
        self.config = config

        # import extra modules for side-effects
        import pypy.interpreter.nestedscope     # register *_DEREF bytecodes

        self.interned_strings = {}
        self.actionflag = ActionFlag()    # changed by the signal module
        self.user_del_action = UserDelAction(self)
        self.frame_trace_action = FrameTraceAction(self)
        self.actionflag.register_action(self.user_del_action)
        self.actionflag.register_action(self.frame_trace_action)

        from pypy.interpreter.pyframe import PyFrame
        self.FrameClass = PyFrame    # can be overridden to a subclass

        if self.config.objspace.logbytecodes:
            self.bytecodecounts = [0] * 256
            self.bytecodetransitioncount = {}

        if self.config.objspace.timing:
            self.timer = Timer()
        else:
            self.timer = DummyTimer()

        self.initialize()

    def startup(self):
        # To be called before using the space

        # Initialize all builtin modules
        from pypy.interpreter.module import Module
        for w_modname in self.unpackiterable(
                                self.sys.get('builtin_module_names')):
            modname = self.str_w(w_modname)
            mod = self.interpclass_w(self.getbuiltinmodule(modname))
            if isinstance(mod, Module):
                import time
                self.timer.start("startup " + modname)
                mod.startup(self)
                self.timer.stop("startup " + modname)

    def finish(self):
        w_exitfunc = self.sys.getdictvalue_w(self, 'exitfunc')
        if w_exitfunc is not None:
            self.call_function(w_exitfunc)
        from pypy.interpreter.module import Module
        for w_modname in self.unpackiterable(
                                self.sys.get('builtin_module_names')):
            modname = self.str_w(w_modname)
            mod = self.interpclass_w(self.getbuiltinmodule(modname))
            if isinstance(mod, Module):
                mod.shutdown(self)
        if self.config.objspace.std.withdictmeasurement:
            from pypy.objspace.std.dictmultiobject import report
            report()
        if self.config.objspace.logbytecodes:
            self.reportbytecodecounts()
        if self.config.objspace.std.logspaceoptypes:
            for s in self.FrameClass._space_op_types:
                print s

    def reportbytecodecounts(self):
        os.write(2, "Starting bytecode report.\n")
        fd = os.open('bytecode.txt', os.O_CREAT|os.O_WRONLY|os.O_TRUNC, 0644)
        os.write(fd, "bytecodecounts = {\n")
        for opcode in range(len(self.bytecodecounts)):
            count = self.bytecodecounts[opcode]
            if not count:
                continue
            os.write(fd, "    %s: %s,\n" % (opcode, count))
        os.write(fd, "}\n")
        os.write(fd, "bytecodetransitioncount = {\n")
        for opcode, probs in self.bytecodetransitioncount.iteritems():
            os.write(fd, "    %s: {\n" % (opcode, ))
            for nextcode, count in probs.iteritems():
                os.write(fd, "        %s: %s,\n" % (nextcode, count))
            os.write(fd, "    },\n")
        os.write(fd, "}\n")
        os.close(fd)
        os.write(2, "Reporting done.\n")

    def __repr__(self):
        try:
            return self._this_space_repr_
        except AttributeError:
            return self.__class__.__name__

    def setbuiltinmodule(self, importname):
        """NOT_RPYTHON. load a lazy pypy/module and put it into sys.modules"""
        import sys

        fullname = "pypy.module.%s" % importname

        Module = __import__(fullname,
                            None, None, ["Module"]).Module
        if Module.applevel_name is not None:
            name = Module.applevel_name
        else:
            name = importname

        w_name = self.wrap(name)
        w_mod = self.wrap(Module(self, w_name))
        w_modules = self.sys.get('modules')
        self.setitem(w_modules, w_name, w_mod)
        return name

    def getbuiltinmodule(self, name):
        w_name = self.wrap(name)
        w_modules = self.sys.get('modules')
        return self.getitem(w_modules, w_name)

    def get_builtinmodule_to_install(self):
        """NOT_RPYTHON"""
        try:
            return self._builtinmodule_list
        except AttributeError:
            pass

        modules = []

        # You can enable more modules by specifying --usemodules=xxx,yyy
        for name, value in self.config.objspace.usemodules:
            if value and name not in modules:
                modules.append(name)

        # a bit of custom logic: time2 or rctime take precedence over time
        # XXX this could probably be done as a "requires" in the config
        if ('time2' in modules or 'rctime' in modules) and 'time' in modules:
            modules.remove('time')

        import pypy
        if not self.config.objspace.nofaking:
            for modname in self.ALL_BUILTIN_MODULES:
                if not (os.path.exists(
                        os.path.join(os.path.dirname(pypy.__file__),
                                     'lib', modname+'.py'))):
                    modules.append('faked+'+modname)

        self._builtinmodule_list = modules
        return self._builtinmodule_list

    ALL_BUILTIN_MODULES = [
        'posix', 'nt', 'os2', 'mac', 'ce', 'riscos',
        'math', 'array', 'select',
        '_random', '_sre', 'time', '_socket', 'errno',
        'unicodedata',
        'parser', 'fcntl', '_codecs', 'binascii'
    ]

    def make_builtins(self):
        "NOT_RPYTHON: only for initializing the space."

        from pypy.module.sys import Module
        w_name = self.wrap('sys')
        self.sys = Module(self, w_name)
        w_modules = self.sys.get('modules')
        self.setitem(w_modules, w_name, self.wrap(self.sys))

        from pypy.module.__builtin__ import Module
        w_name = self.wrap('__builtin__')
        self.builtin = Module(self, w_name)
        w_builtin = self.wrap(self.builtin)
        self.setitem(w_modules, w_name, w_builtin)
        self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin)

        bootstrap_modules = ['sys', '__builtin__', 'exceptions']
        installed_builtin_modules = bootstrap_modules[:]

        # initialize with "bootstrap types" from objspace  (e.g. w_None)
        for name, value in self.__dict__.items():
            if name.startswith('w_') and not name.endswith('Type'):
                name = name[2:]
                #print "setitem: space instance %-20s into builtins" % name
                self.setitem(self.builtin.w_dict, self.wrap(name), value)

        # install mixed and faked modules and set builtin_module_names on sys
        for mixedname in self.get_builtinmodule_to_install():
            if (mixedname not in bootstrap_modules
                and not mixedname.startswith('faked+')):
                self.install_mixedmodule(mixedname, installed_builtin_modules)
        for mixedname in self.get_builtinmodule_to_install():
            if mixedname.startswith('faked+'):
                modname = mixedname[6:]
                self.install_faked_module(modname, installed_builtin_modules)

        installed_builtin_modules.sort()
        w_builtin_module_names = self.newtuple(
            [self.wrap(fn) for fn in installed_builtin_modules])

        # force this value into the dict without unlazyfying everything
        self.setitem(self.sys.w_dict, self.wrap('builtin_module_names'),
                     w_builtin_module_names)

    def install_mixedmodule(self, mixedname, installed_builtin_modules):
        """NOT_RPYTHON"""
        modname = self.setbuiltinmodule(mixedname)
        if modname:
            assert modname not in installed_builtin_modules, (
                "duplicate interp-level module enabled for the "
                "app-level module %r" % (modname,))
            installed_builtin_modules.append(modname)

    def load_cpython_module(self, modname):
        "NOT_RPYTHON. Steal a module from CPython."
        cpy_module = __import__(modname, {}, {}, ['*'])
        return cpy_module

    def install_faked_module(self, modname, installed_builtin_modules):
        """NOT_RPYTHON"""
        if modname in installed_builtin_modules:
            return
        try:
            module = self.load_cpython_module(modname)
        except ImportError:
            return
        else:
            w_modules = self.sys.get('modules')
            self.setitem(w_modules, self.wrap(modname), self.wrap(module))
            installed_builtin_modules.append(modname)

    def setup_builtin_modules(self):
        "NOT_RPYTHON: only for initializing the space."
        from pypy.interpreter.module import Module
        for w_modname in self.unpackiterable(self.sys.get('builtin_module_names')):
            modname = self.unwrap(w_modname)
            mod = self.getbuiltinmodule(modname)
            if isinstance(mod, Module):
                mod.setup_after_space_initialization()

    def initialize(self):
        """NOT_RPYTHON: Abstract method that should put some minimal
        content into the w_builtins."""

    def enter_cache_building_mode(self):
        "hook for the flow object space"
    def leave_cache_building_mode(self, val):
        "hook for the flow object space"

    def getexecutioncontext(self):
        "Return what we consider to be the active execution context."
        # Important: the annotator must not see a prebuilt ExecutionContext
        # for reasons related to the specialization of the framestack attribute
        # so we make sure that the threadlocals never *have* an
        # ExecutionContext during translation.
        if self.config.translating and not we_are_translated():
            assert self.threadlocals.getvalue() is None, (
                "threadlocals got an ExecutionContext during translation!")
            try:
                return self._ec_during_translation
            except AttributeError:
                ec = self.createexecutioncontext()
                self._ec_during_translation = ec
                return ec
        # normal case follows.  The 'thread' module installs a real
        # thread-local object in self.threadlocals, so this builds
        # and caches a new ec in each thread.
        ec = self.threadlocals.getvalue()
        if ec is None:
            ec = self.createexecutioncontext()
            self.threadlocals.setvalue(ec)
        return ec

    def _freeze_(self):
        return True

    def createexecutioncontext(self):
        "Factory function for execution contexts."
        return ExecutionContext(self)

    def createcompiler(self):
        "Factory function creating a compiler object."
        # XXX simple selection logic for now
        try:
            return self.default_compiler
        except AttributeError:
            if self.config.objspace.compiler == 'cpython':
                compiler = CPythonCompiler(self)
            elif self.config.objspace.compiler == 'ast':
                compiler = PythonAstCompiler(self)
            else:
                raise ValueError('unknown --compiler option value: %r' % (
                    self.config.objspace.compiler,))
            self.default_compiler = compiler
            return compiler

    def createframe(self, code, w_globals, closure=None):
        "Create an empty PyFrame suitable for this code object."
        return self.FrameClass(self, code, w_globals, closure)

    def allocate_lock(self):
        """Return an interp-level Lock object if threads are enabled,
        and a dummy object if they are not."""
        if self.config.objspace.usemodules.thread:
            # we use a sub-function to avoid putting the 'import' statement
            # here, where the flow space would see it even if thread=False
            return self.__allocate_lock()
        else:
            return dummy_lock

    def __allocate_lock(self):
        from pypy.module.thread.ll_thread import allocate_lock, error
        try:
            return allocate_lock()
        except error:
            raise OperationError(self.w_RuntimeError,
                                 self.wrap("out of resources"))

    # Following is a friendly interface to common object space operations
    # that can be defined in term of more primitive ones.  Subclasses
    # may also override specific functions for performance.

    #def is_(self, w_x, w_y):   -- not really useful.  Must be subclassed
    #    "'x is y'."
    #    w_id_x = self.id(w_x)
    #    w_id_y = self.id(w_y)
    #    return self.eq(w_id_x, w_id_y)

    def not_(self, w_obj):
        return self.wrap(not self.is_true(w_obj))

    def eq_w(self, w_obj1, w_obj2):
        """shortcut for space.is_true(space.eq(w_obj1, w_obj2))"""
        return self.is_w(w_obj1, w_obj2) or self.is_true(self.eq(w_obj1, w_obj2))

    def is_w(self, w_obj1, w_obj2):
        """shortcut for space.is_true(space.is_(w_obj1, w_obj2))"""
        return self.is_true(self.is_(w_obj1, w_obj2))

    def hash_w(self, w_obj):
        """shortcut for space.int_w(space.hash(w_obj))"""
        return self.int_w(self.hash(w_obj))

    def set_str_keyed_item(self, w_obj, w_key, w_value, shadows_type=True):
        return self.setitem(w_obj, w_key, w_value)

    def finditem(self, w_obj, w_key):
        try:
            return self.getitem(w_obj, w_key)
        except OperationError, e:
            if e.match(self, self.w_KeyError):
                return None
            raise
Exemplo n.º 6
0
class ObjSpace(object):
    """Base class for the interpreter-level implementations of object spaces.
    http://codespeak.net/pypy/dist/pypy/doc/objspace.html"""

    full_exceptions = True  # full support for exceptions (normalization & more)

    def __init__(self, config=None):
        "NOT_RPYTHON: Basic initialization of objects."
        self.fromcache = InternalSpaceCache(self).getorbuild
        self.threadlocals = ThreadLocals()
        # set recursion limit
        # sets all the internal descriptors
        if config is None:
            from pypy.config.pypyoption import get_pypy_config
            config = get_pypy_config(translating=False)
        self.config = config

        # import extra modules for side-effects
        import pypy.interpreter.nestedscope  # register *_DEREF bytecodes

        self.interned_strings = {}
        self.actionflag = ActionFlag()  # changed by the signal module
        self.user_del_action = UserDelAction(self)
        self.frame_trace_action = FrameTraceAction(self)
        self.actionflag.register_action(self.user_del_action)
        self.actionflag.register_action(self.frame_trace_action)

        from pypy.interpreter.pyframe import PyFrame
        self.FrameClass = PyFrame  # can be overridden to a subclass

        #        if self.config.objspace.logbytecodes:
        #            self.bytecodecounts = {}

        self.initialize()

    def startup(self):
        # To be called before using the space

        # Initialize all builtin modules
        from pypy.interpreter.module import Module
        for w_modname in self.unpackiterable(
                self.sys.get('builtin_module_names')):
            modname = self.str_w(w_modname)
            mod = self.interpclass_w(self.getbuiltinmodule(modname))
            if isinstance(mod, Module):
                mod.startup(self)

    def finish(self):
        w_exitfunc = self.sys.getdictvalue_w(self, 'exitfunc')
        if w_exitfunc is not None:
            self.call_function(w_exitfunc)
        from pypy.interpreter.module import Module
        for w_modname in self.unpackiterable(
                self.sys.get('builtin_module_names')):
            modname = self.str_w(w_modname)
            mod = self.interpclass_w(self.getbuiltinmodule(modname))
            if isinstance(mod, Module):
                mod.shutdown(self)
        if self.config.objspace.std.withdictmeasurement:
            from pypy.objspace.std.dictmultiobject import report
            report()
        if self.config.objspace.logbytecodes:
            self.reportbytecodecounts()
        if self.config.objspace.std.logspaceoptypes:
            for s in self.FrameClass._space_op_types:
                print s

    def reportbytecodecounts(self):
        os.write(2, "Starting bytecode report.\n")
        fd = os.open('bytecode.txt', os.O_CREAT | os.O_WRONLY | os.O_TRUNC,
                     0644)
        for opcode, count in self.bytecodecounts.items():
            os.write(fd, str(opcode) + ", " + str(count) + "\n")
        os.close(fd)
        os.write(2, "Reporting done.\n")

    def __repr__(self):
        try:
            return self._this_space_repr_
        except AttributeError:
            return self.__class__.__name__

    def setbuiltinmodule(self, importname):
        """NOT_RPYTHON. load a lazy pypy/module and put it into sys.modules"""
        import sys

        fullname = "pypy.module.%s" % importname

        Module = __import__(fullname, None, None, ["Module"]).Module
        if Module.applevel_name is not None:
            name = Module.applevel_name
        else:
            name = importname

        w_name = self.wrap(name)
        w_mod = self.wrap(Module(self, w_name))
        w_modules = self.sys.get('modules')
        self.setitem(w_modules, w_name, w_mod)
        return name

    def getbuiltinmodule(self, name):
        w_name = self.wrap(name)
        w_modules = self.sys.get('modules')
        return self.getitem(w_modules, w_name)

    def get_builtinmodule_to_install(self):
        """NOT_RPYTHON"""
        try:
            return self._builtinmodule_list
        except AttributeError:
            pass

        modules = []

        # You can enable more modules by specifying --usemodules=xxx,yyy
        for name, value in self.config.objspace.usemodules:
            if value and name not in modules:
                modules.append(name)

        # a bit of custom logic: time2 or rctime take precedence over time
        # XXX this could probably be done as a "requires" in the config
        if ('time2' in modules or 'rctime' in modules) and 'time' in modules:
            modules.remove('time')

        import pypy
        if not self.config.objspace.nofaking:
            for modname in self.ALL_BUILTIN_MODULES:
                if not (os.path.exists(
                        os.path.join(os.path.dirname(pypy.__file__), 'lib',
                                     modname + '.py'))):
                    modules.append('faked+' + modname)

        self._builtinmodule_list = modules
        return self._builtinmodule_list

    ALL_BUILTIN_MODULES = [
        'posix', 'nt', 'os2', 'mac', 'ce', 'riscos', 'math', 'array', 'select',
        '_random', '_sre', 'time', '_socket', 'errno', 'unicodedata', 'parser',
        'fcntl', '_codecs', 'binascii'
    ]

    def make_builtins(self):
        "NOT_RPYTHON: only for initializing the space."

        from pypy.module.sys import Module
        w_name = self.wrap('sys')
        self.sys = Module(self, w_name)
        w_modules = self.sys.get('modules')
        self.setitem(w_modules, w_name, self.wrap(self.sys))

        from pypy.module.__builtin__ import Module
        w_name = self.wrap('__builtin__')
        self.builtin = Module(self, w_name)
        w_builtin = self.wrap(self.builtin)
        self.setitem(w_modules, w_name, w_builtin)
        self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin)

        bootstrap_modules = ['sys', '__builtin__', 'exceptions']
        installed_builtin_modules = bootstrap_modules[:]

        # initialize with "bootstrap types" from objspace  (e.g. w_None)
        for name, value in self.__dict__.items():
            if name.startswith('w_') and not name.endswith('Type'):
                name = name[2:]
                #print "setitem: space instance %-20s into builtins" % name
                self.setitem(self.builtin.w_dict, self.wrap(name), value)

        # install mixed and faked modules and set builtin_module_names on sys
        for mixedname in self.get_builtinmodule_to_install():
            if (mixedname not in bootstrap_modules
                    and not mixedname.startswith('faked+')):
                self.install_mixedmodule(mixedname, installed_builtin_modules)
        for mixedname in self.get_builtinmodule_to_install():
            if mixedname.startswith('faked+'):
                modname = mixedname[6:]
                self.install_faked_module(modname, installed_builtin_modules)

        installed_builtin_modules.sort()
        w_builtin_module_names = self.newtuple(
            [self.wrap(fn) for fn in installed_builtin_modules])

        # force this value into the dict without unlazyfying everything
        self.setitem(self.sys.w_dict, self.wrap('builtin_module_names'),
                     w_builtin_module_names)

    def install_mixedmodule(self, mixedname, installed_builtin_modules):
        """NOT_RPYTHON"""
        modname = self.setbuiltinmodule(mixedname)
        if modname:
            assert modname not in installed_builtin_modules, (
                "duplicate interp-level module enabled for the "
                "app-level module %r" % (modname, ))
            installed_builtin_modules.append(modname)

    def load_cpython_module(self, modname):
        "NOT_RPYTHON. Steal a module from CPython."
        cpy_module = __import__(modname, {}, {}, ['*'])
        return cpy_module

    def install_faked_module(self, modname, installed_builtin_modules):
        """NOT_RPYTHON"""
        if modname in installed_builtin_modules:
            return
        try:
            module = self.load_cpython_module(modname)
        except ImportError:
            return
        else:
            w_modules = self.sys.get('modules')
            self.setitem(w_modules, self.wrap(modname), self.wrap(module))
            installed_builtin_modules.append(modname)

    def setup_builtin_modules(self):
        "NOT_RPYTHON: only for initializing the space."
        from pypy.interpreter.module import Module
        for w_modname in self.unpackiterable(
                self.sys.get('builtin_module_names')):
            modname = self.unwrap(w_modname)
            mod = self.getbuiltinmodule(modname)
            if isinstance(mod, Module):
                mod.setup_after_space_initialization()

    def initialize(self):
        """NOT_RPYTHON: Abstract method that should put some minimal
        content into the w_builtins."""

    def enter_cache_building_mode(self):
        "hook for the flow object space"

    def leave_cache_building_mode(self, val):
        "hook for the flow object space"

    def getexecutioncontext(self):
        "Return what we consider to be the active execution context."
        # Important: the annotator must not see a prebuilt ExecutionContext
        # for reasons related to the specialization of the framestack attribute
        # so we make sure that the threadlocals never *have* an
        # ExecutionContext during translation.
        if self.config.translating and not we_are_translated():
            assert self.threadlocals.getvalue() is None, (
                "threadlocals got an ExecutionContext during translation!")
            try:
                return self._ec_during_translation
            except AttributeError:
                ec = self.createexecutioncontext()
                self._ec_during_translation = ec
                return ec
        # normal case follows.  The 'thread' module installs a real
        # thread-local object in self.threadlocals, so this builds
        # and caches a new ec in each thread.
        ec = self.threadlocals.getvalue()
        if ec is None:
            ec = self.createexecutioncontext()
            self.threadlocals.setvalue(ec)
        return ec

    def _freeze_(self):
        return True

    def createexecutioncontext(self):
        "Factory function for execution contexts."
        return ExecutionContext(self)

    def createcompiler(self):
        "Factory function creating a compiler object."
        # XXX simple selection logic for now
        try:
            return self.default_compiler
        except AttributeError:
            if self.config.objspace.compiler == 'cpython':
                compiler = CPythonCompiler(self)
            elif self.config.objspace.compiler == 'ast':
                compiler = PythonAstCompiler(self)
            else:
                raise ValueError('unknown --compiler option value: %r' %
                                 (self.config.objspace.compiler, ))
            self.default_compiler = compiler
            return compiler

    def createframe(self, code, w_globals, closure=None):
        "Create an empty PyFrame suitable for this code object."
        return self.FrameClass(self, code, w_globals, closure)

    def allocate_lock(self):
        """Return an interp-level Lock object if threads are enabled,
        and a dummy object if they are not."""
        if self.config.objspace.usemodules.thread:
            # we use a sub-function to avoid putting the 'import' statement
            # here, where the flow space would see it even if thread=False
            return self.__allocate_lock()
        else:
            return dummy_lock

    def __allocate_lock(self):
        from pypy.module.thread.ll_thread import allocate_lock, error
        try:
            return allocate_lock()
        except error:
            raise OperationError(self.w_RuntimeError,
                                 self.wrap("out of resources"))

    # Following is a friendly interface to common object space operations
    # that can be defined in term of more primitive ones.  Subclasses
    # may also override specific functions for performance.

    #def is_(self, w_x, w_y):   -- not really useful.  Must be subclassed
    #    "'x is y'."
    #    w_id_x = self.id(w_x)
    #    w_id_y = self.id(w_y)
    #    return self.eq(w_id_x, w_id_y)

    def not_(self, w_obj):
        return self.wrap(not self.is_true(w_obj))

    def eq_w(self, w_obj1, w_obj2):
        """shortcut for space.is_true(space.eq(w_obj1, w_obj2))"""
        return self.is_w(w_obj1, w_obj2) or self.is_true(
            self.eq(w_obj1, w_obj2))

    def is_w(self, w_obj1, w_obj2):
        """shortcut for space.is_true(space.is_(w_obj1, w_obj2))"""
        return self.is_true(self.is_(w_obj1, w_obj2))

    def hash_w(self, w_obj):
        """shortcut for space.int_w(space.hash(w_obj))"""
        return self.int_w(self.hash(w_obj))

    def set_str_keyed_item(self, w_obj, w_key, w_value, shadows_type=True):
        return self.setitem(w_obj, w_key, w_value)

    def finditem(self, w_obj, w_key):
        try:
            return self.getitem(w_obj, w_key)
        except OperationError, e:
            if e.match(self, self.w_KeyError):
                return None
            raise