Deleted Added
sdiff udiff text old ( 7534:c76a14014c27 ) new ( 7673:b28bd1fa9a35 )
full compact
1# Copyright (c) 2004-2006 The Regents of The University of Michigan
2# Copyright (c) 2010 Advanced Micro Devices, Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met: redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer;

--- 15 unchanged lines hidden (view full) ---

24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#
28# Authors: Steve Reinhardt
29# Nathan Binkert
30
31import sys
32from types import FunctionType, MethodType
33
34try:
35 import pydot
36except:
37 pydot = False
38
39import m5
40from m5.util import *

--- 51 unchanged lines hidden (view full) ---

92#####################################################################
93
94# list of all SimObject classes
95allClasses = {}
96
97# dict to look up SimObjects based on path
98instanceDict = {}
99
100def default_cxx_predecls(cls, code):
101 '''A forward class declaration is sufficient since we are
102 just declaring a pointer.'''
103
104 class_path = cls._value_dict['cxx_class'].split('::')
105 for ns in class_path[:-1]:
106 code('namespace $ns {')
107 code('class $0;', class_path[-1])
108 for ns in reversed(class_path[:-1]):
109 code('/* namespace $ns */ }')
110
111def default_swig_objdecls(cls, code):
112 class_path = cls.cxx_class.split('::')
113 classname = class_path[-1]
114 namespaces = class_path[:-1]
115
116 for ns in namespaces:
117 code('namespace $ns {')
118
119 if namespaces:
120 code('// avoid name conflicts')
121 sep_string = '_COLONS_'
122 flat_name = sep_string.join(class_path)
123 code('%rename($flat_name) $classname;')
124
125 code()
126 code('// stop swig from creating/wrapping default ctor/dtor')
127 code('%nodefault $classname;')
128 code('class $classname')
129 if cls._base:
130 code(' : public ${{cls._base.cxx_class}}')
131 code('{};')
132
133 for ns in reversed(namespaces):
134 code('/* namespace $ns */ }')
135
136def public_value(key, value):
137 return key.startswith('_') or \
138 isinstance(value, (FunctionType, MethodType, classmethod, type))
139
140# The metaclass for SimObject. This class controls how new classes
141# that derive from SimObject are instantiated, and provides inherited
142# class behavior (just like a class controls how instances of that
143# class are instantiated, and provides inherited instance behavior).
144class MetaSimObject(type):
145 # Attributes that can be set only at initialization time
146 init_keywords = { 'abstract' : bool,
147 'cxx_class' : str,
148 'cxx_type' : str,
149 'cxx_predecls' : MethodType,
150 'swig_objdecls' : MethodType,
151 'swig_predecls' : MethodType,
152 'type' : str }
153 # Attributes that can be set any time
154 keywords = { 'check' : FunctionType }
155
156 # __new__ is called before __init__, and is where the statements
157 # in the body of the class definition get loaded into the class's
158 # __dict__. We intercept this to filter out parameter & port assignments
159 # and only allow "private" attributes to be passed to the base
160 # __new__ (starting with underscore).
161 def __new__(mcls, name, bases, dict):
162 assert name not in allClasses, "SimObject %s already present" % name
163
164 # Copy "private" attributes, functions, and classes to the
165 # official dict. Everything else goes in _init_dict to be
166 # filtered in __init__.
167 cls_dict = {}
168 value_dict = {}
169 for key,val in dict.items():
170 if public_value(key, val):
171 cls_dict[key] = val
172 else:
173 # must be a param/port setting
174 value_dict[key] = val
175 if 'abstract' not in value_dict:
176 value_dict['abstract'] = False
177 cls_dict['_value_dict'] = value_dict
178 cls = super(MetaSimObject, mcls).__new__(mcls, name, bases, cls_dict)

--- 44 unchanged lines hidden (view full) ---

223
224 # default keyword values
225 if 'type' in cls._value_dict:
226 if 'cxx_class' not in cls._value_dict:
227 cls._value_dict['cxx_class'] = cls._value_dict['type']
228
229 cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class']
230
231 if 'cxx_predecls' not in cls.__dict__:
232 m = MethodType(default_cxx_predecls, cls, MetaSimObject)
233 setattr(cls, 'cxx_predecls', m)
234
235 if 'swig_predecls' not in cls.__dict__:
236 setattr(cls, 'swig_predecls', getattr(cls, 'cxx_predecls'))
237
238 if 'swig_objdecls' not in cls.__dict__:
239 m = MethodType(default_swig_objdecls, cls, MetaSimObject)
240 setattr(cls, 'swig_objdecls', m)
241
242 # Now process the _value_dict items. They could be defining
243 # new (or overriding existing) parameters or ports, setting
244 # class keywords (e.g., 'abstract'), or setting parameter
245 # values or port bindings. The first 3 can only be set when
246 # the class is defined, so we handle them here. The others
247 # can be set later too, so just emulate that by calling
248 # setattr().

--- 58 unchanged lines hidden (view full) ---

307 ref = cls._ports[attr].makeRef(cls)
308 cls._port_refs[attr] = ref
309 return ref
310
311 # Set attribute (called on foo.attr = value when foo is an
312 # instance of class cls).
313 def __setattr__(cls, attr, value):
314 # normal processing for private attributes
315 if public_value(attr, value):
316 type.__setattr__(cls, attr, value)
317 return
318
319 if cls.keywords.has_key(attr):
320 cls._set_keyword(attr, value, cls.keywords[attr])
321 return
322
323 if cls._ports.has_key(attr):

--- 29 unchanged lines hidden (view full) ---

353 return cls._children[attr]
354
355 raise AttributeError, \
356 "object '%s' has no attribute '%s'" % (cls.__name__, attr)
357
358 def __str__(cls):
359 return cls.__name__
360
361 def cxx_decl(cls, code):
362 code('''\
363#ifndef __PARAMS__${cls}__
364#define __PARAMS__${cls}__
365
366''')
367
368 # The 'dict' attribute restricts us to the params declared in
369 # the object itself, not including inherited params (which
370 # will also be inherited from the base class's param struct
371 # here).
372 params = cls._params.local.values()
373 try:
374 ptypes = [p.ptype for p in params]
375 except:
376 print cls, p, p.ptype_str
377 print params
378 raise
379
380 # get all predeclarations
381 cls.cxx_predecls(code)
382 for param in params:
383 param.cxx_predecls(code)
384 code()
385
386 if cls._base:
387 code('#include "params/${{cls._base.type}}.hh"')
388 code()
389
390 for ptype in ptypes:
391 if issubclass(ptype, Enum):
392 code('#include "enums/${{ptype.__name__}}.hh"')
393 code()
394
395 cls.cxx_struct(code, cls._base, params)
396
397 # close #ifndef __PARAMS__* guard
398 code()
399 code('#endif // __PARAMS__${cls}__')
400 return code
401
402 def cxx_struct(cls, code, base, params):
403 if cls == SimObject:
404 code('#include "sim/sim_object_params.hh"')
405 return
406
407 # now generate the actual param struct
408 code("struct ${cls}Params")
409 if base:
410 code(" : public ${{base.type}}Params")
411 code("{")
412 if not hasattr(cls, 'abstract') or not cls.abstract:
413 if 'type' in cls.__dict__:
414 code(" ${{cls.cxx_type}} create();")
415
416 code.indent()
417 for param in params:
418 param.cxx_decl(code)
419 code.dedent()
420 code('};')
421
422 def swig_decl(cls, code):
423 code('''\
424%module $cls
425
426%{
427#include "params/$cls.hh"
428%}
429
430''')
431
432 # The 'dict' attribute restricts us to the params declared in
433 # the object itself, not including inherited params (which
434 # will also be inherited from the base class's param struct
435 # here).
436 params = cls._params.local.values()
437 ptypes = [p.ptype for p in params]
438
439 # get all predeclarations
440 for param in params:
441 param.swig_predecls(code)
442 code()
443
444 if cls._base:
445 code('%import "params/${{cls._base.type}}.i"')
446 code()
447
448 for ptype in ptypes:
449 if issubclass(ptype, Enum):
450 code('%import "enums/${{ptype.__name__}}.hh"')
451 code()
452
453 code('%import "params/${cls}_type.hh"')
454 code('%include "params/${cls}.hh"')
455
456# The SimObject class is the root of the special hierarchy. Most of
457# the code in this class deals with the configuration hierarchy itself
458# (parent/child node relationships).
459class SimObject(object):
460 # Specify metaclass. Any class inheriting from SimObject will
461 # get this metaclass.
462 __metaclass__ = MetaSimObject
463 type = 'SimObject'
464 abstract = True
465
466 @classmethod
467 def swig_objdecls(cls, code):
468 code('%include "python/swig/sim_object.i"')
469
470 # Initialize new instance. For objects with SimObject-valued
471 # children, we need to recursively clone the classes represented
472 # by those param values as well in a consistent "deep copy"-style
473 # fashion. That is, we want to make sure that each instance is
474 # cloned only once, and that if there are multiple references to
475 # the same original object, we end up with the corresponding
476 # cloned references all pointing to the same cloned instance.

--- 482 unchanged lines hidden ---