SimObject.py (8459:b8c3c20d0385) SimObject.py (8596:e6e22fa77883)
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;

--- 83 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
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;

--- 83 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 code('#include "params/$cls.hh"')
102
103def default_swig_predecls(cls, code):
104 code('%import "python/m5/internal/param_$cls.i"')
105
106def default_swig_objdecls(cls, code):
107 class_path = cls.cxx_class.split('::')
108 classname = class_path[-1]
109 namespaces = class_path[:-1]
110
111 for ns in namespaces:
112 code('namespace $ns {')
113
114 if namespaces:
115 code('// avoid name conflicts')
116 sep_string = '_COLONS_'
117 flat_name = sep_string.join(class_path)
118 code('%rename($flat_name) $classname;')
119
120 code()
121 code('// stop swig from creating/wrapping default ctor/dtor')
122 code('%nodefault $classname;')
123 code('class $classname')
124 if cls._base:
125 code(' : public ${{cls._base.cxx_class}}')
126 code('{};')
127
128 for ns in reversed(namespaces):
129 code('} // namespace $ns')
130
131def public_value(key, value):
132 return key.startswith('_') or \
133 isinstance(value, (FunctionType, MethodType, ModuleType,
134 classmethod, type))
135
136# The metaclass for SimObject. This class controls how new classes
137# that derive from SimObject are instantiated, and provides inherited
138# class behavior (just like a class controls how instances of that
139# class are instantiated, and provides inherited instance behavior).
140class MetaSimObject(type):
141 # Attributes that can be set only at initialization time
142 init_keywords = { 'abstract' : bool,
143 'cxx_class' : str,
144 'cxx_type' : str,
100def public_value(key, value):
101 return key.startswith('_') or \
102 isinstance(value, (FunctionType, MethodType, ModuleType,
103 classmethod, type))
104
105# The metaclass for SimObject. This class controls how new classes
106# that derive from SimObject are instantiated, and provides inherited
107# class behavior (just like a class controls how instances of that
108# class are instantiated, and provides inherited instance behavior).
109class MetaSimObject(type):
110 # Attributes that can be set only at initialization time
111 init_keywords = { 'abstract' : bool,
112 'cxx_class' : str,
113 'cxx_type' : str,
145 'cxx_predecls' : MethodType,
146 'swig_objdecls' : MethodType,
147 'swig_predecls' : MethodType,
148 'type' : str }
149 # Attributes that can be set any time
150 keywords = { 'check' : FunctionType }
151
152 # __new__ is called before __init__, and is where the statements
153 # in the body of the class definition get loaded into the class's
154 # __dict__. We intercept this to filter out parameter & port assignments
155 # and only allow "private" attributes to be passed to the base

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

218 cls._base = None
219
220 # default keyword values
221 if 'type' in cls._value_dict:
222 if 'cxx_class' not in cls._value_dict:
223 cls._value_dict['cxx_class'] = cls._value_dict['type']
224
225 cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class']
114 'type' : str }
115 # Attributes that can be set any time
116 keywords = { 'check' : FunctionType }
117
118 # __new__ is called before __init__, and is where the statements
119 # in the body of the class definition get loaded into the class's
120 # __dict__. We intercept this to filter out parameter & port assignments
121 # and only allow "private" attributes to be passed to the base

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

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

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

373 return cls._children[attr]
374
375 raise AttributeError, \
376 "object '%s' has no attribute '%s'" % (cls.__name__, attr)
377
378 def __str__(cls):
379 return cls.__name__
380
193 # Now process the _value_dict items. They could be defining
194 # new (or overriding existing) parameters or ports, setting
195 # class keywords (e.g., 'abstract'), or setting parameter
196 # values or port bindings. The first 3 can only be set when
197 # the class is defined, so we handle them here. The others
198 # can be set later too, so just emulate that by calling
199 # setattr().
200 for key,val in cls._value_dict.items():

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

327 return cls._children[attr]
328
329 raise AttributeError, \
330 "object '%s' has no attribute '%s'" % (cls.__name__, attr)
331
332 def __str__(cls):
333 return cls.__name__
334
381 def cxx_decl(cls, code):
382 # The 'dict' attribute restricts us to the params declared in
335 # See ParamValue.cxx_predecls for description.
336 def cxx_predecls(cls, code):
337 code('#include "params/$cls.hh"')
338
339 # See ParamValue.swig_predecls for description.
340 def swig_predecls(cls, code):
341 code('%import "python/m5/internal/param_$cls.i"')
342
343 # Generate the declaration for this object for wrapping with SWIG.
344 # Generates code that goes into a SWIG .i file. Called from
345 # src/SConscript.
346 def swig_decl(cls, code):
347 class_path = cls.cxx_class.split('::')
348 classname = class_path[-1]
349 namespaces = class_path[:-1]
350
351 # The 'local' attribute restricts us to the params declared in
383 # the object itself, not including inherited params (which
384 # will also be inherited from the base class's param struct
385 # here).
386 params = cls._params.local.values()
352 # the object itself, not including inherited params (which
353 # will also be inherited from the base class's param struct
354 # here).
355 params = cls._params.local.values()
356
357 code('%module(package="m5.internal") param_$cls')
358 code()
359 code('%{')
360 code('#include "params/$cls.hh"')
361 for param in params:
362 param.cxx_predecls(code)
363 code('%}')
364 code()
365
366 for param in params:
367 param.swig_predecls(code)
368
369 code()
370 if cls._base:
371 code('%import "python/m5/internal/param_${{cls._base}}.i"')
372 code()
373
374 for ns in namespaces:
375 code('namespace $ns {')
376
377 if namespaces:
378 code('// avoid name conflicts')
379 sep_string = '_COLONS_'
380 flat_name = sep_string.join(class_path)
381 code('%rename($flat_name) $classname;')
382
383 if cls == SimObject:
384 code('%include "python/swig/sim_object.i"')
385 else:
386 code()
387 code('// stop swig from creating/wrapping default ctor/dtor')
388 code('%nodefault $classname;')
389 code('class $classname')
390 if cls._base:
391 code(' : public ${{cls._base.cxx_class}}')
392 code('{};')
393
394 for ns in reversed(namespaces):
395 code('} // namespace $ns')
396
397 code()
398 code('%include "params/$cls.hh"')
399
400
401 # Generate the C++ declaration (.hh file) for this SimObject's
402 # param struct. Called from src/SConscript.
403 def cxx_param_decl(cls, code):
404 # The 'local' attribute restricts us to the params declared in
405 # the object itself, not including inherited params (which
406 # will also be inherited from the base class's param struct
407 # here).
408 params = cls._params.local.values()
387 try:
388 ptypes = [p.ptype for p in params]
389 except:
390 print cls, p, p.ptype_str
391 print params
392 raise
393
394 class_path = cls._value_dict['cxx_class'].split('::')

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

416 code('#include "params/${{cls._base.type}}.hh"')
417 code()
418
419 for ptype in ptypes:
420 if issubclass(ptype, Enum):
421 code('#include "enums/${{ptype.__name__}}.hh"')
422 code()
423
409 try:
410 ptypes = [p.ptype for p in params]
411 except:
412 print cls, p, p.ptype_str
413 print params
414 raise
415
416 class_path = cls._value_dict['cxx_class'].split('::')

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

438 code('#include "params/${{cls._base.type}}.hh"')
439 code()
440
441 for ptype in ptypes:
442 if issubclass(ptype, Enum):
443 code('#include "enums/${{ptype.__name__}}.hh"')
444 code()
445
424 cls.cxx_struct(code, cls._base, params)
425
426 code()
427 code('#endif // __PARAMS__${cls}__')
428 return code
429
430 def cxx_struct(cls, code, base, params):
446 # now generate the actual param struct
431 if cls == SimObject:
432 code('#include "sim/sim_object_params.hh"')
447 if cls == SimObject:
448 code('#include "sim/sim_object_params.hh"')
433 return
449 else:
450 code("struct ${cls}Params")
451 if cls._base:
452 code(" : public ${{cls._base.type}}Params")
453 code("{")
454 if not hasattr(cls, 'abstract') or not cls.abstract:
455 if 'type' in cls.__dict__:
456 code(" ${{cls.cxx_type}} create();")
434
457
435 # now generate the actual param struct
436 code("struct ${cls}Params")
437 if base:
438 code(" : public ${{base.type}}Params")
439 code("{")
440 if not hasattr(cls, 'abstract') or not cls.abstract:
441 if 'type' in cls.__dict__:
442 code(" ${{cls.cxx_type}} create();")
458 code.indent()
459 for param in params:
460 param.cxx_decl(code)
461 code.dedent()
462 code('};')
443
463
444 code.indent()
445 for param in params:
446 param.cxx_decl(code)
447 code.dedent()
448 code('};')
449
450 def swig_decl(cls, code):
451 code('''\
452%module $cls
453
454%{
455#include "params/$cls.hh"
456%}
457
458''')
459
460 # The 'dict' attribute restricts us to the params declared in
461 # the object itself, not including inherited params (which
462 # will also be inherited from the base class's param struct
463 # here).
464 params = cls._params.local.values()
465 ptypes = [p.ptype for p in params]
466
467 # get all predeclarations
468 for param in params:
469 param.swig_predecls(code)
470 code()
464 code()
465 code('#endif // __PARAMS__${cls}__')
466 return code
471
467
472 if cls._base:
473 code('%import "python/m5/internal/param_${{cls._base.type}}.i"')
474 code()
475
468
476 for ptype in ptypes:
477 if issubclass(ptype, Enum):
478 code('%import "enums/${{ptype.__name__}}.hh"')
479 code()
480
469
481 code('%import "params/${cls}_type.hh"')
482 code('%include "params/${cls}.hh"')
483
484# The SimObject class is the root of the special hierarchy. Most of
485# the code in this class deals with the configuration hierarchy itself
486# (parent/child node relationships).
487class SimObject(object):
488 # Specify metaclass. Any class inheriting from SimObject will
489 # get this metaclass.
490 __metaclass__ = MetaSimObject
491 type = 'SimObject'
492 abstract = True
493
470# The SimObject class is the root of the special hierarchy. Most of
471# the code in this class deals with the configuration hierarchy itself
472# (parent/child node relationships).
473class SimObject(object):
474 # Specify metaclass. Any class inheriting from SimObject will
475 # get this metaclass.
476 __metaclass__ = MetaSimObject
477 type = 'SimObject'
478 abstract = True
479
494 @classmethod
495 def swig_objdecls(cls, code):
496 code('%include "python/swig/sim_object.i"')
497
498 # Initialize new instance. For objects with SimObject-valued
499 # children, we need to recursively clone the classes represented
500 # by those param values as well in a consistent "deep copy"-style
501 # fashion. That is, we want to make sure that each instance is
502 # cloned only once, and that if there are multiple references to
503 # the same original object, we end up with the corresponding
504 # cloned references all pointing to the same cloned instance.
505 def __init__(self, **kwargs):

--- 506 unchanged lines hidden ---
480 # Initialize new instance. For objects with SimObject-valued
481 # children, we need to recursively clone the classes represented
482 # by those param values as well in a consistent "deep copy"-style
483 # fashion. That is, we want to make sure that each instance is
484 # cloned only once, and that if there are multiple references to
485 # the same original object, we end up with the corresponding
486 # cloned references all pointing to the same cloned instance.
487 def __init__(self, **kwargs):

--- 506 unchanged lines hidden ---