# Copyright (c) 2017-2020 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2004-2006 The Regents of The University of Michigan
# Copyright (c) 2010-20013 Advanced Micro Devices, Inc.
# Copyright (c) 2013 Mark D. Hill and David A. Wood
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from __future__ import print_function
from __future__ import absolute_import
from six import add_metaclass
import six
if six.PY3:
    long = int

import sys
from types import FunctionType, MethodType, ModuleType
from functools import wraps
import inspect

import m5
from m5.util import *
from m5.util.pybind import *
# Use the pyfdt and not the helper class, because the fdthelper
# relies on the SimObject definition
from m5.ext.pyfdt import pyfdt

# Have to import params up top since Param is referenced on initial
# load (when SimObject class references Param to create a class
# variable, the 'name' param)...
from m5.params import *
# There are a few things we need that aren't in params.__all__ since
# normal users don't need them
from m5.params import ParamDesc, VectorParamDesc, \
     isNullPointer, SimObjectVector, Port

from m5.proxy import *
from m5.proxy import isproxy

#####################################################################
#
# M5 Python Configuration Utility
#
# The basic idea is to write simple Python programs that build Python
# objects corresponding to M5 SimObjects for the desired simulation
# configuration.  For now, the Python emits a .ini file that can be
# parsed by M5.  In the future, some tighter integration between M5
# and the Python interpreter may allow bypassing the .ini file.
#
# Each SimObject class in M5 is represented by a Python class with the
# same name.  The Python inheritance tree mirrors the M5 C++ tree
# (e.g., SimpleCPU derives from BaseCPU in both cases, and all
# SimObjects inherit from a single SimObject base class).  To specify
# an instance of an M5 SimObject in a configuration, the user simply
# instantiates the corresponding Python object.  The parameters for
# that SimObject are given by assigning to attributes of the Python
# object, either using keyword assignment in the constructor or in
# separate assignment statements.  For example:
#
# cache = BaseCache(size='64KB')
# cache.hit_latency = 3
# cache.assoc = 8
#
# The magic lies in the mapping of the Python attributes for SimObject
# classes to the actual SimObject parameter specifications.  This
# allows parameter validity checking in the Python code.  Continuing
# the example above, the statements "cache.blurfl=3" or
# "cache.assoc='hello'" would both result in runtime errors in Python,
# since the BaseCache object has no 'blurfl' parameter and the 'assoc'
# parameter requires an integer, respectively.  This magic is done
# primarily by overriding the special __setattr__ method that controls
# assignment to object attributes.
#
# Once a set of Python objects have been instantiated in a hierarchy,
# calling 'instantiate(obj)' (where obj is the root of the hierarchy)
# will generate a .ini file.
#
#####################################################################

# list of all SimObject classes
allClasses = {}

# dict to look up SimObjects based on path
instanceDict = {}

# Did any of the SimObjects lack a header file?
noCxxHeader = False

def public_value(key, value):
    return key.startswith('_') or \
               isinstance(value, (FunctionType, MethodType, ModuleType,
                                  classmethod, type))

def createCxxConfigDirectoryEntryFile(code, name, simobj, is_header):
    entry_class = 'CxxConfigDirectoryEntry_%s' % name
    param_class = '%sCxxConfigParams' % name

    code('#include "params/%s.hh"' % name)

    if not is_header:
        for param in simobj._params.values():
            if isSimObjectClass(param.ptype):
                code('#include "%s"' % param.ptype._value_dict['cxx_header'])
                code('#include "params/%s.hh"' % param.ptype.__name__)
            else:
                param.ptype.cxx_ini_predecls(code)

    if is_header:
        member_prefix = ''
        end_of_decl = ';'
        code('#include "sim/cxx_config.hh"')
        code()
        code('class ${param_class} : public CxxConfigParams,'
            ' public ${name}Params')
        code('{')
        code('  private:')
        code.indent()
        code('class DirectoryEntry : public CxxConfigDirectoryEntry')
        code('{')
        code('  public:')
        code.indent()
        code('DirectoryEntry();');
        code()
        code('CxxConfigParams *makeParamsObject() const')
        code('{ return new ${param_class}; }')
        code.dedent()
        code('};')
        code()
        code.dedent()
        code('  public:')
        code.indent()
    else:
        member_prefix = '%s::' % param_class
        end_of_decl = ''
        code('#include "%s"' % simobj._value_dict['cxx_header'])
        code('#include "base/str.hh"')
        code('#include "cxx_config/${name}.hh"')

        code()
        code('${member_prefix}DirectoryEntry::DirectoryEntry()');
        code('{')

        def cxx_bool(b):
            return 'true' if b else 'false'

        code.indent()
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            code('parameters["%s"] = new ParamDesc("%s", %s, %s);' %
                (param.name, param.name, cxx_bool(is_vector),
                cxx_bool(is_simobj)));

        for port in simobj._ports.values():
            is_vector = isinstance(port, m5.params.VectorPort)
            is_master = port.role == 'MASTER'

            code('ports["%s"] = new PortDesc("%s", %s, %s);' %
                (port.name, port.name, cxx_bool(is_vector),
                cxx_bool(is_master)))

        code.dedent()
        code('}')
        code()

    code('bool ${member_prefix}setSimObject(const std::string &name,')
    code('    SimObject *simObject)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false) {')
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            if is_simobj and not is_vector:
                code('} else if (name == "${{param.name}}") {')
                code.indent()
                code('this->${{param.name}} = '
                    'dynamic_cast<${{param.ptype.cxx_type}}>(simObject);')
                code('if (simObject && !this->${{param.name}})')
                code('   ret = false;')
                code.dedent()
        code('} else {')
        code('    ret = false;')
        code('}')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('bool ${member_prefix}setSimObjectVector('
        'const std::string &name,')
    code('    const std::vector<SimObject *> &simObjects)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false) {')
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            if is_simobj and is_vector:
                code('} else if (name == "${{param.name}}") {')
                code.indent()
                code('this->${{param.name}}.clear();')
                code('for (auto i = simObjects.begin(); '
                    'ret && i != simObjects.end(); i ++)')
                code('{')
                code.indent()
                code('${{param.ptype.cxx_type}} object = '
                    'dynamic_cast<${{param.ptype.cxx_type}}>(*i);')
                code('if (*i && !object)')
                code('    ret = false;')
                code('else')
                code('    this->${{param.name}}.push_back(object);')
                code.dedent()
                code('}')
                code.dedent()
        code('} else {')
        code('    ret = false;')
        code('}')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('void ${member_prefix}setName(const std::string &name_)'
        '${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('this->name = name_;')
        code.dedent()
        code('}')

    if is_header:
        code('const std::string &${member_prefix}getName()')
        code('{ return this->name; }')

    code()
    code('bool ${member_prefix}setParam(const std::string &name,')
    code('    const std::string &value, const Flags flags)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false) {')
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            if not is_simobj and not is_vector:
                code('} else if (name == "${{param.name}}") {')
                code.indent()
                param.ptype.cxx_ini_parse(code,
                    'value', 'this->%s' % param.name, 'ret =')
                code.dedent()
        code('} else {')
        code('    ret = false;')
        code('}')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('bool ${member_prefix}setParamVector('
        'const std::string &name,')
    code('    const std::vector<std::string> &values,')
    code('    const Flags flags)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false) {')
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            if not is_simobj and is_vector:
                code('} else if (name == "${{param.name}}") {')
                code.indent()
                code('${{param.name}}.clear();')
                code('for (auto i = values.begin(); '
                    'ret && i != values.end(); i ++)')
                code('{')
                code.indent()
                code('${{param.ptype.cxx_type}} elem;')
                param.ptype.cxx_ini_parse(code,
                    '*i', 'elem', 'ret =')
                code('if (ret)')
                code('    this->${{param.name}}.push_back(elem);')
                code.dedent()
                code('}')
                code.dedent()
        code('} else {')
        code('    ret = false;')
        code('}')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('bool ${member_prefix}setPortConnectionCount('
        'const std::string &name,')
    code('    unsigned int count)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false)')
        code('    ;')
        for port in simobj._ports.values():
            code('else if (name == "${{port.name}}")')
            code('    this->port_${{port.name}}_connection_count = count;')
        code('else')
        code('    ret = false;')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('SimObject *${member_prefix}simObjectCreate()${end_of_decl}')

    if not is_header:
        code('{')
        if hasattr(simobj, 'abstract') and simobj.abstract:
            code('    return NULL;')
        else:
            code('    return this->create();')
        code('}')

    if is_header:
        code()
        code('static CxxConfigDirectoryEntry'
            ' *${member_prefix}makeDirectoryEntry()')
        code('{ return new DirectoryEntry; }')

    if is_header:
        code.dedent()
        code('};')

# The metaclass for SimObject.  This class controls how new classes
# that derive from SimObject are instantiated, and provides inherited
# class behavior (just like a class controls how instances of that
# class are instantiated, and provides inherited instance behavior).
class MetaSimObject(type):
    # Attributes that can be set only at initialization time
    init_keywords = {
        'abstract' : bool,
        'cxx_class' : str,
        'cxx_type' : str,
        'cxx_header' : str,
        'type' : str,
        'cxx_base' : (str, type(None)),
        'cxx_extra_bases' : list,
        'cxx_exports' : list,
        'cxx_param_exports' : list,
        'cxx_template_params' : list,
    }
    # Attributes that can be set any time
    keywords = { 'check' : FunctionType }

    # __new__ is called before __init__, and is where the statements
    # in the body of the class definition get loaded into the class's
    # __dict__.  We intercept this to filter out parameter & port assignments
    # and only allow "private" attributes to be passed to the base
    # __new__ (starting with underscore).
    def __new__(mcls, name, bases, dict):
        assert name not in allClasses, "SimObject %s already present" % name

        # Copy "private" attributes, functions, and classes to the
        # official dict.  Everything else goes in _init_dict to be
        # filtered in __init__.
        cls_dict = {}
        value_dict = {}
        cxx_exports = []
        for key,val in dict.items():
            try:
                cxx_exports.append(getattr(val, "__pybind"))
            except AttributeError:
                pass

            if public_value(key, val):
                cls_dict[key] = val
            else:
                # must be a param/port setting
                value_dict[key] = val
        if 'abstract' not in value_dict:
            value_dict['abstract'] = False
        if 'cxx_extra_bases' not in value_dict:
            value_dict['cxx_extra_bases'] = []
        if 'cxx_exports' not in value_dict:
            value_dict['cxx_exports'] = cxx_exports
        else:
            value_dict['cxx_exports'] += cxx_exports
        if 'cxx_param_exports' not in value_dict:
            value_dict['cxx_param_exports'] = []
        if 'cxx_template_params' not in value_dict:
            value_dict['cxx_template_params'] = []
        cls_dict['_value_dict'] = value_dict
        cls = super(MetaSimObject, mcls).__new__(mcls, name, bases, cls_dict)
        if 'type' in value_dict:
            allClasses[name] = cls
        return cls

    # subclass initialization
    def __init__(cls, name, bases, dict):
        # calls type.__init__()... I think that's a no-op, but leave
        # it here just in case it's not.
        super(MetaSimObject, cls).__init__(name, bases, dict)

        # initialize required attributes

        # class-only attributes
        cls._params = multidict() # param descriptions
        cls._ports = multidict()  # port descriptions

        # Parameter names that are deprecated. Dict[str, DeprecatedParam]
        # The key is the "old_name" so that when the old_name is used in
        # python config files, we will use the DeprecatedParam object to
        # translate to the new type.
        cls._deprecated_params = multidict()

        # class or instance attributes
        cls._values = multidict()   # param values
        cls._hr_values = multidict() # human readable param values
        cls._children = multidict() # SimObject children
        cls._port_refs = multidict() # port ref objects
        cls._instantiated = False # really instantiated, cloned, or subclassed

        # We don't support multiple inheritance of sim objects.  If you want
        # to, you must fix multidict to deal with it properly. Non sim-objects
        # are ok, though
        bTotal = 0
        for c in bases:
            if isinstance(c, MetaSimObject):
                bTotal += 1
            if bTotal > 1:
                raise TypeError(
                      "SimObjects do not support multiple inheritance")

        base = bases[0]

        # Set up general inheritance via multidicts.  A subclass will
        # inherit all its settings from the base class.  The only time
        # the following is not true is when we define the SimObject
        # class itself (in which case the multidicts have no parent).
        if isinstance(base, MetaSimObject):
            cls._base = base
            cls._params.parent = base._params
            cls._ports.parent = base._ports
            cls._deprecated_params.parent = base._deprecated_params
            cls._values.parent = base._values
            cls._hr_values.parent = base._hr_values
            cls._children.parent = base._children
            cls._port_refs.parent = base._port_refs
            # mark base as having been subclassed
            base._instantiated = True
        else:
            cls._base = None

        # default keyword values
        if 'type' in cls._value_dict:
            if 'cxx_class' not in cls._value_dict:
                cls._value_dict['cxx_class'] = cls._value_dict['type']

            cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class']

            if 'cxx_header' not in cls._value_dict:
                global noCxxHeader
                noCxxHeader = True
                warn("No header file specified for SimObject: %s", name)

        # Now process the _value_dict items.  They could be defining
        # new (or overriding existing) parameters or ports, setting
        # class keywords (e.g., 'abstract'), or setting parameter
        # values or port bindings.  The first 3 can only be set when
        # the class is defined, so we handle them here.  The others
        # can be set later too, so just emulate that by calling
        # setattr().
        for key,val in cls._value_dict.items():
            # param descriptions
            if isinstance(val, ParamDesc):
                cls._new_param(key, val)

            # port objects
            elif isinstance(val, Port):
                cls._new_port(key, val)

            # Deprecated variable names
            elif isinstance(val, DeprecatedParam):
                new_name, new_val = cls._get_param_by_value(val.newParam)
                # Note: We don't know the (string) name of this variable until
                # here, so now we can finish setting up the dep_param.
                val.oldName = key
                val.newName = new_name
                cls._deprecated_params[key] = val

            # init-time-only keywords
            elif key in cls.init_keywords:
                cls._set_keyword(key, val, cls.init_keywords[key])

            # default: use normal path (ends up in __setattr__)
            else:
                setattr(cls, key, val)

    def _set_keyword(cls, keyword, val, kwtype):
        if not isinstance(val, kwtype):
            raise TypeError('keyword %s has bad type %s (expecting %s)' % \
                  (keyword, type(val), kwtype))
        if isinstance(val, FunctionType):
            val = classmethod(val)
        type.__setattr__(cls, keyword, val)

    def _new_param(cls, name, pdesc):
        # each param desc should be uniquely assigned to one variable
        assert(not hasattr(pdesc, 'name'))
        pdesc.name = name
        cls._params[name] = pdesc
        if hasattr(pdesc, 'default'):
            cls._set_param(name, pdesc.default, pdesc)

    def _set_param(cls, name, value, param):
        assert(param.name == name)
        try:
            hr_value = value
            value = param.convert(value)
        except Exception as e:
            msg = "%s\nError setting param %s.%s to %s\n" % \
                  (e, cls.__name__, name, value)
            e.args = (msg, )
            raise
        cls._values[name] = value
        # if param value is a SimObject, make it a child too, so that
        # it gets cloned properly when the class is instantiated
        if isSimObjectOrVector(value) and not value.has_parent():
            cls._add_cls_child(name, value)
        # update human-readable values of the param if it has a literal
        # value and is not an object or proxy.
        if not (isSimObjectOrVector(value) or\
                isinstance(value, m5.proxy.BaseProxy)):
            cls._hr_values[name] = hr_value

    def _add_cls_child(cls, name, child):
        # It's a little funky to have a class as a parent, but these
        # objects should never be instantiated (only cloned, which
        # clears the parent pointer), and this makes it clear that the
        # object is not an orphan and can provide better error
        # messages.
        child.set_parent(cls, name)
        if not isNullPointer(child):
            cls._children[name] = child

    def _new_port(cls, name, port):
        # each port should be uniquely assigned to one variable
        assert(not hasattr(port, 'name'))
        port.name = name
        cls._ports[name] = port

    # same as _get_port_ref, effectively, but for classes
    def _cls_get_port_ref(cls, attr):
        # Return reference that can be assigned to another port
        # via __setattr__.  There is only ever one reference
        # object per port, but we create them lazily here.
        ref = cls._port_refs.get(attr)
        if not ref:
            ref = cls._ports[attr].makeRef(cls)
            cls._port_refs[attr] = ref
        return ref

    def _get_param_by_value(cls, value):
        """Given an object, value, return the name and the value from the
        internal list of parameter values. If this value can't be found, raise
        a runtime error. This will search both the current object and its
        parents.
        """
        for k,v in cls._value_dict.items():
            if v == value:
                return k,v
        raise RuntimeError("Cannot find parameter {} in parameter list"
                           .format(value))

    # Set attribute (called on foo.attr = value when foo is an
    # instance of class cls).
    def __setattr__(cls, attr, value):
        # normal processing for private attributes
        if public_value(attr, value):
            type.__setattr__(cls, attr, value)
            return

        if attr in cls.keywords:
            cls._set_keyword(attr, value, cls.keywords[attr])
            return

        if attr in cls._ports:
            cls._cls_get_port_ref(attr).connect(value)
            return

        if isSimObjectOrSequence(value) and cls._instantiated:
            raise RuntimeError(
                  "cannot set SimObject parameter '%s' after\n" \
                  "    class %s has been instantiated or subclassed" \
                  % (attr, cls.__name__))

        # check for param
        param = cls._params.get(attr)
        if param:
            cls._set_param(attr, value, param)
            return

        if isSimObjectOrSequence(value):
            # If RHS is a SimObject, it's an implicit child assignment.
            cls._add_cls_child(attr, coerceSimObjectOrVector(value))
            return

        # no valid assignment... raise exception
        raise AttributeError(
              "Class %s has no parameter \'%s\'" % (cls.__name__, attr))

    def __getattr__(cls, attr):
        if attr == 'cxx_class_path':
            return cls.cxx_class.split('::')

        if attr == 'cxx_class_name':
            return cls.cxx_class_path[-1]

        if attr == 'cxx_namespaces':
            return cls.cxx_class_path[:-1]

        if attr == 'pybind_class':
            return  '_COLONS_'.join(cls.cxx_class_path)

        if attr in cls._values:
            return cls._values[attr]

        if attr in cls._children:
            return cls._children[attr]

        try:
            return getattr(cls.getCCClass(), attr)
        except AttributeError:
            raise AttributeError(
                "object '%s' has no attribute '%s'" % (cls.__name__, attr))

    def __str__(cls):
        return cls.__name__

    def getCCClass(cls):
        return getattr(m5.internal.params, cls.pybind_class)

    # See ParamValue.cxx_predecls for description.
    def cxx_predecls(cls, code):
        code('#include "params/$cls.hh"')

    def pybind_predecls(cls, code):
        code('#include "${{cls.cxx_header}}"')

    def pybind_decl(cls, code):
        py_class_name = cls.pybind_class

        # The 'local' attribute restricts us to the params declared in
        # the object itself, not including inherited params (which
        # will also be inherited from the base class's param struct
        # here). Sort the params based on their key
        params = list(map(lambda k_v: k_v[1], sorted(cls._params.local.items())))
        ports = cls._ports.local

        code('''#include "pybind11/pybind11.h"
#include "pybind11/stl.h"

#include "params/$cls.hh"
#include "python/pybind11/core.hh"
#include "sim/init.hh"
#include "sim/sim_object.hh"

#include "${{cls.cxx_header}}"

''')

        for param in params:
            param.pybind_predecls(code)

        code('''namespace py = pybind11;

static void
module_init(py::module &m_internal)
{
    py::module m = m_internal.def_submodule("param_${cls}");
''')
        code.indent()
        if cls._base:
            code('py::class_<${cls}Params, ${{cls._base.type}}Params, ' \
                 'std::unique_ptr<${{cls}}Params, py::nodelete>>(' \
                 'm, "${cls}Params")')
        else:
            code('py::class_<${cls}Params, ' \
                 'std::unique_ptr<${cls}Params, py::nodelete>>(' \
                 'm, "${cls}Params")')

        code.indent()
        if not hasattr(cls, 'abstract') or not cls.abstract:
            code('.def(py::init<>())')
            code('.def("create", &${cls}Params::create)')

        param_exports = cls.cxx_param_exports + [
            PyBindProperty(k)
            for k, v in sorted(cls._params.local.items())
        ] + [
            PyBindProperty("port_%s_connection_count" % port.name)
            for port in ports.values()
        ]
        for exp in param_exports:
            exp.export(code, "%sParams" % cls)

        code(';')
        code()
        code.dedent()

        bases = []
        if 'cxx_base' in cls._value_dict:
            # If the c++ base class implied by python inheritance was
            # overridden, use that value.
            if cls.cxx_base:
                bases.append(cls.cxx_base)
        elif cls._base:
            # If not and if there was a SimObject base, use its c++ class
            # as this class' base.
            bases.append(cls._base.cxx_class)
        # Add in any extra bases that were requested.
        bases.extend(cls.cxx_extra_bases)

        if bases:
            base_str = ", ".join(bases)
            code('py::class_<${{cls.cxx_class}}, ${base_str}, ' \
                 'std::unique_ptr<${{cls.cxx_class}}, py::nodelete>>(' \
                 'm, "${py_class_name}")')
        else:
            code('py::class_<${{cls.cxx_class}}, ' \
                 'std::unique_ptr<${{cls.cxx_class}}, py::nodelete>>(' \
                 'm, "${py_class_name}")')
        code.indent()
        for exp in cls.cxx_exports:
            exp.export(code, cls.cxx_class)
        code(';')
        code.dedent()
        code()
        code.dedent()
        code('}')
        code()
        code('static EmbeddedPyBind embed_obj("${0}", module_init, "${1}");',
             cls, cls._base.type if cls._base else "")

    _warned_about_nested_templates = False

    # Generate the C++ declaration (.hh file) for this SimObject's
    # param struct.  Called from src/SConscript.
    def cxx_param_decl(cls, code):
        # The 'local' attribute restricts us to the params declared in
        # the object itself, not including inherited params (which
        # will also be inherited from the base class's param struct
        # here). Sort the params based on their key
        params = list(map(lambda k_v: k_v[1], sorted(cls._params.local.items())))
        ports = cls._ports.local
        try:
            ptypes = [p.ptype for p in params]
        except:
            print(cls, p, p.ptype_str)
            print(params)
            raise

        class CxxClass(object):
            def __init__(self, sig, template_params=[]):
                # Split the signature into its constituent parts. This could
                # potentially be done with regular expressions, but
                # it's simple enough to pick appart a class signature
                # manually.
                parts = sig.split('<', 1)
                base = parts[0]
                t_args = []
                if len(parts) > 1:
                    # The signature had template arguments.
                    text = parts[1].rstrip(' \t\n>')
                    arg = ''
                    # Keep track of nesting to avoid splitting on ","s embedded
                    # in the arguments themselves.
                    depth = 0
                    for c in text:
                        if c == '<':
                            depth = depth + 1
                            if depth > 0 and not \
                                    self._warned_about_nested_templates:
                                self._warned_about_nested_templates = True
                                print('Nested template argument in cxx_class.'
                                      ' This feature is largely untested and '
                                      ' may not work.')
                        elif c == '>':
                            depth = depth - 1
                        elif c == ',' and depth == 0:
                            t_args.append(arg.strip())
                            arg = ''
                        else:
                            arg = arg + c
                    if arg:
                        t_args.append(arg.strip())
                # Split the non-template part on :: boundaries.
                class_path = base.split('::')

                # The namespaces are everything except the last part of the
                # class path.
                self.namespaces = class_path[:-1]
                # And the class name is the last part.
                self.name = class_path[-1]

                self.template_params = template_params
                self.template_arguments = []
                # Iterate through the template arguments and their values. This
                # will likely break if parameter packs are used.
                for arg, param in zip(t_args, template_params):
                    type_keys = ('class', 'typename')
                    # If a parameter is a type, parse it recursively. Otherwise
                    # assume it's a constant, and store it verbatim.
                    if any(param.strip().startswith(kw) for kw in type_keys):
                        self.template_arguments.append(CxxClass(arg))
                    else:
                        self.template_arguments.append(arg)

            def declare(self, code):
                # First declare any template argument types.
                for arg in self.template_arguments:
                    if isinstance(arg, CxxClass):
                        arg.declare(code)
                # Re-open the target namespace.
                for ns in self.namespaces:
                    code('namespace $ns {')
                # If this is a class template...
                if self.template_params:
                    code('template <${{", ".join(self.template_params)}}>')
                # The actual class declaration.
                code('class ${{self.name}};')
                # Close the target namespaces.
                for ns in reversed(self.namespaces):
                    code('} // namespace $ns')

        code('''\
#ifndef __PARAMS__${cls}__
#define __PARAMS__${cls}__

''')


        # The base SimObject has a couple of params that get
        # automatically set from Python without being declared through
        # the normal Param mechanism; we slip them in here (needed
        # predecls now, actual declarations below)
        if cls == SimObject:
            code('''#include <string>''')

        cxx_class = CxxClass(cls._value_dict['cxx_class'],
                             cls._value_dict['cxx_template_params'])

        # A forward class declaration is sufficient since we are just
        # declaring a pointer.
        cxx_class.declare(code)

        for param in params:
            param.cxx_predecls(code)
        for port in ports.values():
            port.cxx_predecls(code)
        code()

        if cls._base:
            code('#include "params/${{cls._base.type}}.hh"')
            code()

        for ptype in ptypes:
            if issubclass(ptype, Enum):
                code('#include "enums/${{ptype.__name__}}.hh"')
                code()

        # now generate the actual param struct
        code("struct ${cls}Params")
        if cls._base:
            code("    : public ${{cls._base.type}}Params")
        code("{")
        if not hasattr(cls, 'abstract') or not cls.abstract:
            if 'type' in cls.__dict__:
                code("    ${{cls.cxx_type}} create();")

        code.indent()
        if cls == SimObject:
            code('''
    SimObjectParams() {}
    virtual ~SimObjectParams() {}

    std::string name;
            ''')

        for param in params:
            param.cxx_decl(code)
        for port in ports.values():
            port.cxx_decl(code)

        code.dedent()
        code('};')

        code()
        code('#endif // __PARAMS__${cls}__')
        return code

    # Generate the C++ declaration/definition files for this SimObject's
    # param struct to allow C++ initialisation
    def cxx_config_param_file(cls, code, is_header):
        createCxxConfigDirectoryEntryFile(code, cls.__name__, cls, is_header)
        return code

# This *temporary* definition is required to support calls from the
# SimObject class definition to the MetaSimObject methods (in
# particular _set_param, which gets called for parameters with default
# values defined on the SimObject class itself).  It will get
# overridden by the permanent definition (which requires that
# SimObject be defined) lower in this file.
def isSimObjectOrVector(value):
    return False

def cxxMethod(*args, **kwargs):
    """Decorator to export C++ functions to Python"""

    def decorate(func):
        name = func.__name__
        override = kwargs.get("override", False)
        cxx_name = kwargs.get("cxx_name", name)
        return_value_policy = kwargs.get("return_value_policy", None)
        static = kwargs.get("static", False)

        args, varargs, keywords, defaults = inspect.getargspec(func)
        if varargs or keywords:
            raise ValueError("Wrapped methods must not contain variable " \
                             "arguments")

        # Create tuples of (argument, default)
        if defaults:
            args = args[:-len(defaults)] + \
                   list(zip(args[-len(defaults):], defaults))
        # Don't include self in the argument list to PyBind
        args = args[1:]


        @wraps(func)
        def cxx_call(self, *args, **kwargs):
            ccobj = self.getCCClass() if static else self.getCCObject()
            return getattr(ccobj, name)(*args, **kwargs)

        @wraps(func)
        def py_call(self, *args, **kwargs):
            return func(self, *args, **kwargs)

        f = py_call if override else cxx_call
        f.__pybind = PyBindMethod(name, cxx_name=cxx_name, args=args,
                                  return_value_policy=return_value_policy,
                                  static=static)

        return f

    if len(args) == 0:
        return decorate
    elif len(args) == 1 and len(kwargs) == 0:
        return decorate(*args)
    else:
        raise TypeError("One argument and no kwargs, or only kwargs expected")

# This class holds information about each simobject parameter
# that should be displayed on the command line for use in the
# configuration system.
class ParamInfo(object):
  def __init__(self, type, desc, type_str, example, default_val, access_str):
    self.type = type
    self.desc = desc
    self.type_str = type_str
    self.example_str = example
    self.default_val = default_val
    # The string representation used to access this param through python.
    # The method to access this parameter presented on the command line may
    # be different, so this needs to be stored for later use.
    self.access_str = access_str
    self.created = True

  # Make it so we can only set attributes at initialization time
  # and effectively make this a const object.
  def __setattr__(self, name, value):
    if not "created" in self.__dict__:
      self.__dict__[name] = value

class SimObjectCliWrapperException(Exception):
    def __init__(self, message):
        super(Exception, self).__init__(message)

class SimObjectCliWrapper(object):
    """
    Wrapper class to restrict operations that may be done
    from the command line on SimObjects.

    Only parameters may be set, and only children may be accessed.

    Slicing allows for multiple simultaneous assignment of items in
    one statement.
    """

    def __init__(self, sim_objects):
        self.__dict__['_sim_objects'] = list(sim_objects)

    def __getattr__(self, key):
        return SimObjectCliWrapper(sim_object._children[key]
                for sim_object in self._sim_objects)

    def __setattr__(self, key, val):
        for sim_object in self._sim_objects:
            if key in sim_object._params:
                if sim_object._params[key].isCmdLineSettable():
                    setattr(sim_object, key, val)
                else:
                    raise SimObjectCliWrapperException(
                            'tried to set or unsettable' \
                            'object parameter: ' + key)
            else:
                raise SimObjectCliWrapperException(
                            'tried to set or access non-existent' \
                            'object parameter: ' + key)

    def __getitem__(self, idx):
        """
        Extends the list() semantics to also allow tuples,
        for example object[1, 3] selects items 1 and 3.
        """
        out = []
        if isinstance(idx, tuple):
            for t in idx:
                out.extend(self[t]._sim_objects)
        else:
            if isinstance(idx, int):
                _range = range(idx, idx + 1)
            elif not isinstance(idx, slice):
                raise SimObjectCliWrapperException( \
                        'invalid index type: ' + repr(idx))
            for sim_object in self._sim_objects:
                if isinstance(idx, slice):
                    _range = range(*idx.indices(len(sim_object)))
                out.extend(sim_object[i] for i in _range)
        return SimObjectCliWrapper(out)

    def __iter__(self):
        return iter(self._sim_objects)

# The SimObject class is the root of the special hierarchy.  Most of
# the code in this class deals with the configuration hierarchy itself
# (parent/child node relationships).
@add_metaclass(MetaSimObject)
class SimObject(object):
    # Specify metaclass.  Any class inheriting from SimObject will
    # get this metaclass.
    type = 'SimObject'
    abstract = True

    cxx_header = "sim/sim_object.hh"
    cxx_extra_bases = [ "Drainable", "Serializable", "Stats::Group" ]
    eventq_index = Param.UInt32(Parent.eventq_index, "Event Queue Index")

    cxx_exports = [
        PyBindMethod("init"),
        PyBindMethod("initState"),
        PyBindMethod("memInvalidate"),
        PyBindMethod("memWriteback"),
        PyBindMethod("regProbePoints"),
        PyBindMethod("regProbeListeners"),
        PyBindMethod("startup"),
    ]

    cxx_param_exports = [
        PyBindProperty("name"),
    ]

    @cxxMethod
    def loadState(self, cp):
        """Load SimObject state from a checkpoint"""
        pass

    # Returns a dict of all the option strings that can be
    # generated as command line options for this simobject instance
    # by tracing all reachable params in the top level instance and
    # any children it contains.
    def enumerateParams(self, flags_dict = {},
                        cmd_line_str = "", access_str = ""):
        if hasattr(self, "_paramEnumed"):
            print("Cycle detected enumerating params")
        else:
            self._paramEnumed = True
            # Scan the children first to pick up all the objects in this SimObj
            for keys in self._children:
                child = self._children[keys]
                next_cmdline_str = cmd_line_str + keys
                next_access_str = access_str + keys
                if not isSimObjectVector(child):
                    next_cmdline_str = next_cmdline_str + "."
                    next_access_str = next_access_str + "."
                flags_dict = child.enumerateParams(flags_dict,
                                                   next_cmdline_str,
                                                   next_access_str)

            # Go through the simple params in the simobject in this level
            # of the simobject hierarchy and save information about the
            # parameter to be used for generating and processing command line
            # options to the simulator to set these parameters.
            for keys,values in self._params.items():
                if values.isCmdLineSettable():
                    type_str = ''
                    ex_str = values.example_str()
                    ptype = None
                    if isinstance(values, VectorParamDesc):
                        type_str = 'Vector_%s' % values.ptype_str
                        ptype = values
                    else:
                        type_str = '%s' % values.ptype_str
                        ptype = values.ptype

                    if keys in self._hr_values\
                       and keys in self._values\
                       and not isinstance(self._values[keys],
                                          m5.proxy.BaseProxy):
                        cmd_str = cmd_line_str + keys
                        acc_str = access_str + keys
                        flags_dict[cmd_str] = ParamInfo(ptype,
                                    self._params[keys].desc, type_str, ex_str,
                                    values.pretty_print(self._hr_values[keys]),
                                    acc_str)
                    elif not keys in self._hr_values\
                         and not keys in self._values:
                        # Empty param
                        cmd_str = cmd_line_str + keys
                        acc_str = access_str + keys
                        flags_dict[cmd_str] = ParamInfo(ptype,
                                    self._params[keys].desc,
                                    type_str, ex_str, '', acc_str)

        return flags_dict

    # Initialize new instance.  For objects with SimObject-valued
    # children, we need to recursively clone the classes represented
    # by those param values as well in a consistent "deep copy"-style
    # fashion.  That is, we want to make sure that each instance is
    # cloned only once, and that if there are multiple references to
    # the same original object, we end up with the corresponding
    # cloned references all pointing to the same cloned instance.
    def __init__(self, **kwargs):
        ancestor = kwargs.get('_ancestor')
        memo_dict = kwargs.get('_memo')
        if memo_dict is None:
            # prepare to memoize any recursively instantiated objects
            memo_dict = {}
        elif ancestor:
            # memoize me now to avoid problems with recursive calls
            memo_dict[ancestor] = self

        if not ancestor:
            ancestor = self.__class__
        ancestor._instantiated = True

        # initialize required attributes
        self._parent = None
        self._name = None
        self._ccObject = None  # pointer to C++ object
        self._ccParams = None
        self._instantiated = False # really "cloned"

        # Clone children specified at class level.  No need for a
        # multidict here since we will be cloning everything.
        # Do children before parameter values so that children that
        # are also param values get cloned properly.
        self._children = {}
        for key,val in ancestor._children.items():
            self.add_child(key, val(_memo=memo_dict))

        # Inherit parameter values from class using multidict so
        # individual value settings can be overridden but we still
        # inherit late changes to non-overridden class values.
        self._values = multidict(ancestor._values)
        self._hr_values = multidict(ancestor._hr_values)
        # clone SimObject-valued parameters
        for key,val in ancestor._values.items():
            val = tryAsSimObjectOrVector(val)
            if val is not None:
                self._values[key] = val(_memo=memo_dict)

        # clone port references.  no need to use a multidict here
        # since we will be creating new references for all ports.
        self._port_refs = {}
        for key,val in ancestor._port_refs.items():
            self._port_refs[key] = val.clone(self, memo_dict)
        # apply attribute assignments from keyword args, if any
        for key,val in kwargs.items():
            setattr(self, key, val)

    # "Clone" the current instance by creating another instance of
    # this instance's class, but that inherits its parameter values
    # and port mappings from the current instance.  If we're in a
    # "deep copy" recursive clone, check the _memo dict to see if
    # we've already cloned this instance.
    def __call__(self, **kwargs):
        memo_dict = kwargs.get('_memo')
        if memo_dict is None:
            # no memo_dict: must be top-level clone operation.
            # this is only allowed at the root of a hierarchy
            if self._parent:
                raise RuntimeError("attempt to clone object %s " \
                      "not at the root of a tree (parent = %s)" \
                      % (self, self._parent))
            # create a new dict and use that.
            memo_dict = {}
            kwargs['_memo'] = memo_dict
        elif self in memo_dict:
            # clone already done & memoized
            return memo_dict[self]
        return self.__class__(_ancestor = self, **kwargs)

    def _get_port_ref(self, attr):
        # Return reference that can be assigned to another port
        # via __setattr__.  There is only ever one reference
        # object per port, but we create them lazily here.
        ref = self._port_refs.get(attr)
        if ref == None:
            ref = self._ports[attr].makeRef(self)
            self._port_refs[attr] = ref
        return ref

    def __getattr__(self, attr):
        if attr in self._deprecated_params:
            dep_param = self._deprecated_params[attr]
            dep_param.printWarning(self._name, self.__class__.__name__)
            return getattr(self, self._deprecated_params[attr].newName)

        if attr in self._ports:
            return self._get_port_ref(attr)

        if attr in self._values:
            return self._values[attr]

        if attr in self._children:
            return self._children[attr]

        # If the attribute exists on the C++ object, transparently
        # forward the reference there.  This is typically used for
        # methods exported to Python (e.g., init(), and startup())
        if self._ccObject and hasattr(self._ccObject, attr):
            return getattr(self._ccObject, attr)

        err_string = "object '%s' has no attribute '%s'" \
              % (self.__class__.__name__, attr)

        if not self._ccObject:
            err_string += "\n  (C++ object is not yet constructed," \
                          " so wrapped C++ methods are unavailable.)"

        raise AttributeError(err_string)

    # Set attribute (called on foo.attr = value when foo is an
    # instance of class cls).
    def __setattr__(self, attr, value):
        # normal processing for private attributes
        if attr.startswith('_'):
            object.__setattr__(self, attr, value)
            return

        if attr in self._deprecated_params:
            dep_param = self._deprecated_params[attr]
            dep_param.printWarning(self._name, self.__class__.__name__)
            return setattr(self, self._deprecated_params[attr].newName, value)

        if attr in self._ports:
            # set up port connection
            self._get_port_ref(attr).connect(value)
            return

        param = self._params.get(attr)
        if param:
            try:
                hr_value = value
                value = param.convert(value)
            except Exception as e:
                msg = "%s\nError setting param %s.%s to %s\n" % \
                      (e, self.__class__.__name__, attr, value)
                e.args = (msg, )
                raise
            self._values[attr] = value
            # implicitly parent unparented objects assigned as params
            if isSimObjectOrVector(value) and not value.has_parent():
                self.add_child(attr, value)
            # set the human-readable value dict if this is a param
            # with a literal value and is not being set as an object
            # or proxy.
            if not (isSimObjectOrVector(value) or\
                    isinstance(value, m5.proxy.BaseProxy)):
                self._hr_values[attr] = hr_value

            return

        # if RHS is a SimObject, it's an implicit child assignment
        if isSimObjectOrSequence(value):
            self.add_child(attr, value)
            return

        # no valid assignment... raise exception
        raise AttributeError("Class %s has no parameter %s" \
              % (self.__class__.__name__, attr))


    # this hack allows tacking a '[0]' onto parameters that may or may
    # not be vectors, and always getting the first element (e.g. cpus)
    def __getitem__(self, key):
        if key == 0:
            return self
        raise IndexError("Non-zero index '%s' to SimObject" % key)

    # this hack allows us to iterate over a SimObject that may
    # not be a vector, so we can call a loop over it and get just one
    # element.
    def __len__(self):
        return 1

    # Also implemented by SimObjectVector
    def clear_parent(self, old_parent):
        assert self._parent is old_parent
        self._parent = None

    # Also implemented by SimObjectVector
    def set_parent(self, parent, name):
        self._parent = parent
        self._name = name

    # Return parent object of this SimObject, not implemented by
    # SimObjectVector because the elements in a SimObjectVector may not share
    # the same parent
    def get_parent(self):
        return self._parent

    # Also implemented by SimObjectVector
    def get_name(self):
        return self._name

    # Also implemented by SimObjectVector
    def has_parent(self):
        return self._parent is not None

    # clear out child with given name. This code is not likely to be exercised.
    # See comment in add_child.
    def clear_child(self, name):
        child = self._children[name]
        child.clear_parent(self)
        del self._children[name]

    # Add a new child to this object.
    def add_child(self, name, child):
        child = coerceSimObjectOrVector(child)
        if child.has_parent():
            warn("add_child('%s'): child '%s' already has parent", name,
                child.get_name())
        if name in self._children:
            # This code path had an undiscovered bug that would make it fail
            # at runtime. It had been here for a long time and was only
            # exposed by a buggy script. Changes here will probably not be
            # exercised without specialized testing.
            self.clear_child(name)
        child.set_parent(self, name)
        if not isNullPointer(child):
            self._children[name] = child

    # Take SimObject-valued parameters that haven't been explicitly
    # assigned as children and make them children of the object that
    # they were assigned to as a parameter value.  This guarantees
    # that when we instantiate all the parameter objects we're still
    # inside the configuration hierarchy.
    def adoptOrphanParams(self):
        for key,val in self._values.items():
            if not isSimObjectVector(val) and isSimObjectSequence(val):
                # need to convert raw SimObject sequences to
                # SimObjectVector class so we can call has_parent()
                val = SimObjectVector(val)
                self._values[key] = val
            if isSimObjectOrVector(val) and not val.has_parent():
                warn("%s adopting orphan SimObject param '%s'", self, key)
                self.add_child(key, val)

    def path(self):
        if not self._parent:
            return '<orphan %s>' % self.__class__
        elif isinstance(self._parent, MetaSimObject):
            return str(self.__class__)

        ppath = self._parent.path()
        if ppath == 'root':
            return self._name
        return ppath + "." + self._name

    def path_list(self):
        if self._parent:
            return self._parent.path_list() + [ self._name, ]
        else:
            # Don't include the root node
            return []

    def __str__(self):
        return self.path()

    def config_value(self):
        return self.path()

    def ini_str(self):
        return self.path()

    def find_any(self, ptype):
        if isinstance(self, ptype):
            return self, True

        found_obj = None
        for child in self._children.values():
            visited = False
            if hasattr(child, '_visited'):
              visited = getattr(child, '_visited')

            if isinstance(child, ptype) and not visited:
                if found_obj != None and child != found_obj:
                    raise AttributeError(
                          'parent.any matched more than one: %s %s' % \
                          (found_obj.path, child.path))
                found_obj = child
        # search param space
        for pname,pdesc in self._params.items():
            if issubclass(pdesc.ptype, ptype):
                match_obj = self._values[pname]
                if found_obj != None and found_obj != match_obj:
                    raise AttributeError(
                          'parent.any matched more than one: %s and %s' % \
                          (found_obj.path, match_obj.path))
                found_obj = match_obj
        return found_obj, found_obj != None

    def find_all(self, ptype):
        all = {}
        # search children
        for child in self._children.values():
            # a child could be a list, so ensure we visit each item
            if isinstance(child, list):
                children = child
            else:
                children = [child]

            for child in children:
                if isinstance(child, ptype) and not isproxy(child) and \
                        not isNullPointer(child):
                    all[child] = True
                if isSimObject(child):
                    # also add results from the child itself
                    child_all, done = child.find_all(ptype)
                    all.update(dict(zip(child_all, [done] * len(child_all))))
        # search param space
        for pname,pdesc in self._params.items():
            if issubclass(pdesc.ptype, ptype):
                match_obj = self._values[pname]
                if not isproxy(match_obj) and not isNullPointer(match_obj):
                    all[match_obj] = True
        # Also make sure to sort the keys based on the objects' path to
        # ensure that the order is the same on all hosts
        return sorted(all.keys(), key = lambda o: o.path()), True

    def unproxy(self, base):
        return self

    def unproxyParams(self):
        for param in self._params.keys():
            value = self._values.get(param)
            if value != None and isproxy(value):
                try:
                    value = value.unproxy(self)
                except:
                    print("Error in unproxying param '%s' of %s" %
                          (param, self.path()))
                    raise
                setattr(self, param, value)

        # Unproxy ports in sorted order so that 'append' operations on
        # vector ports are done in a deterministic fashion.
        port_names = list(self._ports.keys())
        port_names.sort()
        for port_name in port_names:
            port = self._port_refs.get(port_name)
            if port != None:
                port.unproxy(self)

    def print_ini(self, ini_file):
        print('[' + self.path() + ']', file=ini_file)    # .ini section header

        instanceDict[self.path()] = self

        if hasattr(self, 'type'):
            print('type=%s' % self.type, file=ini_file)

        if len(self._children.keys()):
            print('children=%s' %
                  ' '.join(self._children[n].get_name()
                           for n in sorted(self._children.keys())),
                  file=ini_file)

        for param in sorted(self._params.keys()):
            value = self._values.get(param)
            if value != None:
                print('%s=%s' % (param, self._values[param].ini_str()),
                      file=ini_file)

        for port_name in sorted(self._ports.keys()):
            port = self._port_refs.get(port_name, None)
            if port != None:
                print('%s=%s' % (port_name, port.ini_str()), file=ini_file)

        print(file=ini_file)        # blank line between objects

    # generate a tree of dictionaries expressing all the parameters in the
    # instantiated system for use by scripts that want to do power, thermal
    # visualization, and other similar tasks
    def get_config_as_dict(self):
        d = attrdict()
        if hasattr(self, 'type'):
            d.type = self.type
        if hasattr(self, 'cxx_class'):
            d.cxx_class = self.cxx_class
        # Add the name and path of this object to be able to link to
        # the stats
        d.name = self.get_name()
        d.path = self.path()

        for param in sorted(self._params.keys()):
            value = self._values.get(param)
            if value != None:
                d[param] = value.config_value()

        for n in sorted(self._children.keys()):
            child = self._children[n]
            # Use the name of the attribute (and not get_name()) as
            # the key in the JSON dictionary to capture the hierarchy
            # in the Python code that assembled this system
            d[n] = child.get_config_as_dict()

        for port_name in sorted(self._ports.keys()):
            port = self._port_refs.get(port_name, None)
            if port != None:
                # Represent each port with a dictionary containing the
                # prominent attributes
                d[port_name] = port.get_config_as_dict()

        return d

    def getCCParams(self):
        if self._ccParams:
            return self._ccParams

        cc_params_struct = getattr(m5.internal.params, '%sParams' % self.type)
        cc_params = cc_params_struct()
        cc_params.name = str(self)

        param_names = list(self._params.keys())
        param_names.sort()
        for param in param_names:
            value = self._values.get(param)
            if value is None:
                fatal("%s.%s without default or user set value",
                      self.path(), param)

            value = value.getValue()
            if isinstance(self._params[param], VectorParamDesc):
                assert isinstance(value, list)
                vec = getattr(cc_params, param)
                assert not len(vec)
                # Some types are exposed as opaque types. They support
                # the append operation unlike the automatically
                # wrapped types.
                if isinstance(vec, list):
                    setattr(cc_params, param, list(value))
                else:
                    for v in value:
                        getattr(cc_params, param).append(v)
            else:
                setattr(cc_params, param, value)

        port_names = list(self._ports.keys())
        port_names.sort()
        for port_name in port_names:
            port = self._port_refs.get(port_name, None)
            if port != None:
                port_count = len(port)
            else:
                port_count = 0
            setattr(cc_params, 'port_' + port_name + '_connection_count',
                    port_count)
        self._ccParams = cc_params
        return self._ccParams

    # Get C++ object corresponding to this object, calling C++ if
    # necessary to construct it.  Does *not* recursively create
    # children.
    def getCCObject(self):
        if not self._ccObject:
            # Make sure this object is in the configuration hierarchy
            if not self._parent and not isRoot(self):
                raise RuntimeError("Attempt to instantiate orphan node")
            # Cycles in the configuration hierarchy are not supported. This
            # will catch the resulting recursion and stop.
            self._ccObject = -1
            if not self.abstract:
                params = self.getCCParams()
                self._ccObject = params.create()
        elif self._ccObject == -1:
            raise RuntimeError("%s: Cycle found in configuration hierarchy." \
                  % self.path())
        return self._ccObject

    def descendants(self):
        yield self
        # The order of the dict is implementation dependent, so sort
        # it based on the key (name) to ensure the order is the same
        # on all hosts
        for (name, child) in sorted(self._children.items()):
            for obj in child.descendants():
                yield obj

    # Call C++ to create C++ object corresponding to this object
    def createCCObject(self):
        self.getCCParams()
        self.getCCObject() # force creation

    def getValue(self):
        return self.getCCObject()

    @cxxMethod(return_value_policy="reference")
    def getPort(self, if_name, idx):
        pass

    # Create C++ port connections corresponding to the connections in
    # _port_refs
    def connectPorts(self):
        # Sort the ports based on their attribute name to ensure the
        # order is the same on all hosts
        for (attr, portRef) in sorted(self._port_refs.items()):
            portRef.ccConnect()

    # Default function for generating the device structure.
    # Can be overloaded by the inheriting class
    def generateDeviceTree(self, state):
        return # return without yielding anything
        yield  # make this function a (null) generator

    def recurseDeviceTree(self, state):
        for child in self._children.values():
            for item in child: # For looping over SimObjectVectors
                for dt in item.generateDeviceTree(state):
                    yield dt

    # On a separate method otherwise certain buggy Python versions
    # would fail with: SyntaxError: unqualified exec is not allowed
    # in function 'apply_config'
    def _apply_config_get_dict(self):
        return {
            child_name: SimObjectCliWrapper(
                iter(self._children[child_name]))
            for child_name in self._children
        }

    def apply_config(self, params):
        """
        exec a list of Python code strings contained in params.

        The only exposed globals to those strings are the child
        SimObjects of this node.

        This function is intended to allow users to modify SimObject
        parameters from the command line with Python statements.
        """
        d = self._apply_config_get_dict()
        for param in params:
            exec(param, d)

    def get_simobj(self, simobj_path):
        """
        Get all sim objects that match a given string.

        The format is the same as that supported by SimObjectCliWrapper.

        :param simobj_path: Current state to be in.
        :type simobj_path: str
        """
        d = self._apply_config_get_dict()
        return eval(simobj_path, d)

# Function to provide to C++ so it can look up instances based on paths
def resolveSimObject(name):
    obj = instanceDict[name]
    return obj.getCCObject()

def isSimObject(value):
    return isinstance(value, SimObject)

def isSimObjectClass(value):
    return issubclass(value, SimObject)

def isSimObjectVector(value):
    return isinstance(value, SimObjectVector)

def isSimObjectSequence(value):
    if not isinstance(value, (list, tuple)) or len(value) == 0:
        return False

    for val in value:
        if not isNullPointer(val) and not isSimObject(val):
            return False

    return True

def isSimObjectOrSequence(value):
    return isSimObject(value) or isSimObjectSequence(value)

def isRoot(obj):
    from m5.objects import Root
    return obj and obj is Root.getInstance()

def isSimObjectOrVector(value):
    return isSimObject(value) or isSimObjectVector(value)

def tryAsSimObjectOrVector(value):
    if isSimObjectOrVector(value):
        return value
    if isSimObjectSequence(value):
        return SimObjectVector(value)
    return None

def coerceSimObjectOrVector(value):
    value = tryAsSimObjectOrVector(value)
    if value is None:
        raise TypeError("SimObject or SimObjectVector expected")
    return value

baseClasses = allClasses.copy()
baseInstances = instanceDict.copy()

def clear():
    global allClasses, instanceDict, noCxxHeader

    allClasses = baseClasses.copy()
    instanceDict = baseInstances.copy()
    noCxxHeader = False

# __all__ defines the list of symbols that get exported when
# 'from config import *' is invoked.  Try to keep this reasonably
# short to avoid polluting other namespaces.
__all__ = [
    'SimObject',
    'cxxMethod',
    'PyBindMethod',
    'PyBindProperty',
]
