simobject.py

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· Python 代码 · 共 911 行 · 第 1/3 页

PY
911
字号
        if attr.startswith('_'):            type.__setattr__(cls, attr, value)            return        if cls.keywords.has_key(attr):            cls._set_keyword(attr, value, cls.keywords[attr])            return        if cls._ports.has_key(attr):            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.            # Classes don't have children, so we just put this object            # in _values; later, each instance will do a 'setattr(self,            # attr, _values[attr])' in SimObject.__init__ which will            # add this object as a child.            cls._values[attr] = value            return        # no valid assignment... raise exception        raise AttributeError, \              "Class %s has no parameter \'%s\'" % (cls.__name__, attr)    def __getattr__(cls, attr):        if cls._values.has_key(attr):            return cls._values[attr]        raise AttributeError, \              "object '%s' has no attribute '%s'" % (cls.__name__, attr)    def __str__(cls):        return cls.__name__    def get_base(cls):        if str(cls) == 'SimObject':            return None        return  cls.__bases__[0].type    def cxx_decl(cls):        code = "#ifndef __PARAMS__%s\n" % cls        code += "#define __PARAMS__%s\n\n" % cls        # The 'dict' 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).        params = cls._params.local.values()        try:            ptypes = [p.ptype for p in params]        except:            print cls, p, p.ptype_str            print params            raise        # get a list of lists of predeclaration lines        predecls = []        predecls.extend(cls.cxx_predecls)        for p in params:            predecls.extend(p.cxx_predecls())        # remove redundant lines        predecls2 = []        for pd in predecls:            if pd not in predecls2:                predecls2.append(pd)        predecls2.sort()        code += "\n".join(predecls2)        code += "\n\n";        base = cls.get_base()        if base:            code += '#include "params/%s.hh"\n\n' % base        for ptype in ptypes:            if issubclass(ptype, Enum):                code += '#include "enums/%s.hh"\n' % ptype.__name__                code += "\n\n"        # now generate the actual param struct        code += "struct %sParams" % cls        if base:            code += " : public %sParams" % base        code += "\n{\n"        if cls == SimObject:            code += "    virtual ~%sParams() {}\n" % cls        if not hasattr(cls, 'abstract') or not cls.abstract:            if 'type' in cls.__dict__:                code += "    %s create();\n" % cls.cxx_type        decls = [p.cxx_decl() for p in params]        decls.sort()        code += "".join(["    %s\n" % d for d in decls])        code += "};\n"        # close #ifndef __PARAMS__* guard        code += "\n#endif\n"        return code    def cxx_type_decl(cls):        base = cls.get_base()        code = ''        if base:            code += '#include "%s_type.h"\n' % base        # now generate dummy code for inheritance        code += "struct %s" % cls.cxx_class        if base:            code += " : public %s" % base.cxx_class        code += "\n{};\n"        return code    def swig_decl(cls):        base = cls.get_base()                code = '%%module %s\n' % cls        code += '%{\n'        code += '#include "params/%s.hh"\n' % cls        code += '%}\n\n'        # The 'dict' 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).        params = cls._params.local.values()        ptypes = [p.ptype for p in params]        # get a list of lists of predeclaration lines        predecls = []        predecls.extend([ p.swig_predecls() for p in params ])        # flatten        predecls = reduce(lambda x,y:x+y, predecls, [])        # remove redundant lines        predecls2 = []        for pd in predecls:            if pd not in predecls2:                predecls2.append(pd)        predecls2.sort()        code += "\n".join(predecls2)        code += "\n\n";        if base:            code += '%%import "params/%s.i"\n\n' % base        for ptype in ptypes:            if issubclass(ptype, Enum):                code += '%%import "enums/%s.hh"\n' % ptype.__name__                code += "\n\n"        code += '%%import "params/%s_type.hh"\n\n' % cls        code += '%%include "params/%s.hh"\n\n' % cls        return code# 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).class SimObject(object):    # Specify metaclass.  Any class inheriting from SimObject will    # get this metaclass.    __metaclass__ = MetaSimObject    type = 'SimObject'    abstract = True    name = Param.String("Object name")    swig_objdecls = [ '%include "python/swig/sim_object.i"' ]    # 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._children = {}        self._ccObject = None  # pointer to C++ object        self._ccParams = None        self._instantiated = False # really "cloned"        # Inherit parameter values from class using multidict so        # individual value settings can be overridden.        self._values = multidict(ancestor._values)        # clone SimObject-valued parameters        for key,val in ancestor._values.iteritems():            if isSimObject(val):                setattr(self, key, val(_memo=memo_dict))            elif isSimObjectSequence(val) and len(val):                setattr(self, key, [ v(_memo=memo_dict) for v in val ])        # 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.iteritems():            self._port_refs[key] = val.clone(self, memo_dict)        # apply attribute assignments from keyword args, if any        for key,val in kwargs.iteritems():            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 memo_dict.has_key(self):            # 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 not ref:            ref = self._ports[attr].makeRef(self)            self._port_refs[attr] = ref        return ref    def __getattr__(self, attr):        if self._ports.has_key(attr):            return self._get_port_ref(attr)        if self._values.has_key(attr):            return self._values[attr]        raise AttributeError, "object '%s' has no attribute '%s'" \              % (self.__class__.__name__, attr)    # 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 self._ports.has_key(attr):            # set up port connection            self._get_port_ref(attr).connect(value)            return        if isSimObjectOrSequence(value) and self._instantiated:            raise RuntimeError, \                  "cannot set SimObject parameter '%s' after\n" \                  "    instance been cloned %s" % (attr, `self`)        # must be SimObject param        param = self._params.get(attr)        if param:            try:                value = param.convert(value)            except Exception, e:                msg = "%s\nError setting param %s.%s to %s\n" % \                      (e, self.__class__.__name__, attr, value)                e.args = (msg, )                raise            self._set_child(attr, value)            return        if isSimObjectOrSequence(value):            self._set_child(attr, value)            return

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?