15522Snate@binkert.org# Copyright (c) 2008 The Hewlett-Packard Development Company
25522Snate@binkert.org# All rights reserved.
35522Snate@binkert.org#
45522Snate@binkert.org# Redistribution and use in source and binary forms, with or without
55522Snate@binkert.org# modification, are permitted provided that the following conditions are
65522Snate@binkert.org# met: redistributions of source code must retain the above copyright
75522Snate@binkert.org# notice, this list of conditions and the following disclaimer;
85522Snate@binkert.org# redistributions in binary form must reproduce the above copyright
95522Snate@binkert.org# notice, this list of conditions and the following disclaimer in the
105522Snate@binkert.org# documentation and/or other materials provided with the distribution;
115522Snate@binkert.org# neither the name of the copyright holders nor the names of its
125522Snate@binkert.org# contributors may be used to endorse or promote products derived from
135522Snate@binkert.org# this software without specific prior written permission.
145522Snate@binkert.org#
155522Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
165522Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
175522Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
185522Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
195522Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205522Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
215522Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
225522Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
235522Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
245522Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
255522Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265522Snate@binkert.org#
275522Snate@binkert.org# Authors: Nathan Binkert
285522Snate@binkert.org
2913714Sandreas.sandberg@arm.comfrom __future__ import print_function
3013714Sandreas.sandberg@arm.comfrom __future__ import absolute_import
3113714Sandreas.sandberg@arm.com
325522Snate@binkert.org# Simple importer that allows python to import data from a dict of
335522Snate@binkert.org# code objects.  The keys are the module path, and the items are the
345522Snate@binkert.org# filename and bytecode of the file.
355522Snate@binkert.orgclass CodeImporter(object):
365522Snate@binkert.org    def __init__(self):
375522Snate@binkert.org        self.modules = {}
385522Snate@binkert.org
397502Snate@binkert.org    def add_module(self, filename, abspath, modpath, code):
405522Snate@binkert.org        if modpath in self.modules:
4113663Sandreas.sandberg@arm.com            raise AttributeError("%s already found in importer" % modpath)
425522Snate@binkert.org
437502Snate@binkert.org        self.modules[modpath] = (filename, abspath, code)
445522Snate@binkert.org
455522Snate@binkert.org    def find_module(self, fullname, path):
465522Snate@binkert.org        if fullname in self.modules:
475522Snate@binkert.org            return self
485522Snate@binkert.org
495522Snate@binkert.org        return None
505522Snate@binkert.org
515522Snate@binkert.org    def load_module(self, fullname):
525522Snate@binkert.org        # Because the importer is created and initialized in its own
535522Snate@binkert.org        # little sandbox (in init.cc), the globals that were available
545522Snate@binkert.org        # when the importer module was loaded and CodeImporter was
555522Snate@binkert.org        # defined are not available when load_module is actually
565522Snate@binkert.org        # called. Soooo, the imports must live here.
575522Snate@binkert.org        import imp
585522Snate@binkert.org        import os
595522Snate@binkert.org        import sys
609737Sandreas@sandberg.pp.se
619737Sandreas@sandberg.pp.se        try:
629737Sandreas@sandberg.pp.se            mod = sys.modules[fullname]
639737Sandreas@sandberg.pp.se        except KeyError:
649737Sandreas@sandberg.pp.se            mod = imp.new_module(fullname)
659737Sandreas@sandberg.pp.se            sys.modules[fullname] = mod
665522Snate@binkert.org
675522Snate@binkert.org        try:
685522Snate@binkert.org            mod.__loader__ = self
697502Snate@binkert.org            srcfile,abspath,code = self.modules[fullname]
707502Snate@binkert.org
717502Snate@binkert.org            override = os.environ.get('M5_OVERRIDE_PY_SOURCE', 'false').lower()
727502Snate@binkert.org            if override in ('true', 'yes') and  os.path.exists(abspath):
7313670Sandreas.sandberg@arm.com                src = open(abspath, 'r').read()
747502Snate@binkert.org                code = compile(src, abspath, 'exec')
757502Snate@binkert.org
765522Snate@binkert.org            if os.path.basename(srcfile) == '__init__.py':
775522Snate@binkert.org                mod.__path__ = fullname.split('.')
789737Sandreas@sandberg.pp.se                mod.__package__ = fullname
799737Sandreas@sandberg.pp.se            else:
809737Sandreas@sandberg.pp.se                mod.__package__ = fullname.rpartition('.')[0]
815522Snate@binkert.org            mod.__file__ = srcfile
825522Snate@binkert.org
8313671Sandreas.sandberg@arm.com            exec(code, mod.__dict__)
845522Snate@binkert.org        except Exception:
855522Snate@binkert.org            del sys.modules[fullname]
865522Snate@binkert.org            raise
875522Snate@binkert.org
885522Snate@binkert.org        return mod
895522Snate@binkert.org
905522Snate@binkert.org# Create an importer and add it to the meta_path so future imports can
915522Snate@binkert.org# use it.  There's currently nothing in the importer, but calls to
925522Snate@binkert.org# add_module can be used to add code.
935522Snate@binkert.orgimport sys
945522Snate@binkert.orgimporter = CodeImporter()
955522Snate@binkert.orgadd_module = importer.add_module
965522Snate@binkert.orgsys.meta_path.append(importer)
97