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; --- 176 unchanged lines hidden (view full) --- 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'] 192 |
193 # Export methods are automatically inherited via C++, so we 194 # don't want the method declarations to get inherited on the 195 # python side (and thus end up getting repeated in the wrapped 196 # versions of derived classes). The code below basicallly 197 # suppresses inheritance by substituting in the base (null) 198 # versions of these methods unless a different version is 199 # explicitly supplied. 200 for method_name in ('export_methods', 'export_method_cxx_predecls', 201 'export_method_swig_predecls'): 202 if method_name not in cls.__dict__: 203 base_method = getattr(MetaSimObject, method_name) 204 m = MethodType(base_method, cls, MetaSimObject) 205 setattr(cls, method_name, m) 206 |
207 # Now process the _value_dict items. They could be defining 208 # new (or overriding existing) parameters or ports, setting 209 # class keywords (e.g., 'abstract'), or setting parameter 210 # values or port bindings. The first 3 can only be set when 211 # the class is defined, so we handle them here. The others 212 # can be set later too, so just emulate that by calling 213 # setattr(). 214 for key,val in cls._value_dict.items(): --- 134 unchanged lines hidden (view full) --- 349 # See ParamValue.cxx_predecls for description. 350 def cxx_predecls(cls, code): 351 code('#include "params/$cls.hh"') 352 353 # See ParamValue.swig_predecls for description. 354 def swig_predecls(cls, code): 355 code('%import "python/m5/internal/param_$cls.i"') 356 |
357 # Hook for exporting additional C++ methods to Python via SWIG. 358 # Default is none, override using @classmethod in class definition. 359 def export_methods(cls, code): 360 pass 361 362 # Generate the code needed as a prerequisite for the C++ methods 363 # exported via export_methods() to be compiled in the _wrap.cc 364 # file. Typically generates one or more #include statements. If 365 # any methods are exported, typically at least the C++ header 366 # declaring the relevant SimObject class must be included. 367 def export_method_cxx_predecls(cls, code): 368 pass 369 370 # Generate the code needed as a prerequisite for the C++ methods 371 # exported via export_methods() to be processed by SWIG. 372 # Typically generates one or more %include or %import statements. 373 # If any methods are exported, typically at least the C++ header 374 # declaring the relevant SimObject class must be included. 375 def export_method_swig_predecls(cls, code): 376 pass 377 |
378 # Generate the declaration for this object for wrapping with SWIG. 379 # Generates code that goes into a SWIG .i file. Called from 380 # src/SConscript. 381 def swig_decl(cls, code): 382 class_path = cls.cxx_class.split('::') 383 classname = class_path[-1] 384 namespaces = class_path[:-1] 385 --- 4 unchanged lines hidden (view full) --- 390 params = cls._params.local.values() 391 392 code('%module(package="m5.internal") param_$cls') 393 code() 394 code('%{') 395 code('#include "params/$cls.hh"') 396 for param in params: 397 param.cxx_predecls(code) |
398 cls.export_method_cxx_predecls(code) |
399 code('%}') 400 code() 401 402 for param in params: 403 param.swig_predecls(code) |
404 cls.export_method_swig_predecls(code) |
405 406 code() 407 if cls._base: 408 code('%import "python/m5/internal/param_${{cls._base}}.i"') 409 code() 410 411 for ns in namespaces: 412 code('namespace $ns {') 413 414 if namespaces: 415 code('// avoid name conflicts') 416 sep_string = '_COLONS_' 417 flat_name = sep_string.join(class_path) 418 code('%rename($flat_name) $classname;') 419 |
420 code() 421 code('// stop swig from creating/wrapping default ctor/dtor') 422 code('%nodefault $classname;') 423 code('class $classname') 424 if cls._base: 425 code(' : public ${{cls._base.cxx_class}}') 426 code('{') 427 code(' public:') 428 cls.export_methods(code) 429 code('};') |
430 431 for ns in reversed(namespaces): 432 code('} // namespace $ns') 433 434 code() 435 code('%include "params/$cls.hh"') 436 437 --- 24 unchanged lines hidden (view full) --- 462 # declaring a pointer. 463 for ns in class_path[:-1]: 464 code('namespace $ns {') 465 code('class $0;', class_path[-1]) 466 for ns in reversed(class_path[:-1]): 467 code('} // namespace $ns') 468 code() 469 |
470 # The base SimObject has a couple of params that get 471 # automatically set from Python without being declared through 472 # the normal Param mechanism; we slip them in here (needed 473 # predecls now, actual declarations below) 474 if cls == SimObject: 475 code(''' 476#ifndef PY_VERSION 477struct PyObject; 478#endif 479 480#include <string> 481 482struct EventQueue; 483''') |
484 for param in params: 485 param.cxx_predecls(code) 486 code() 487 488 if cls._base: 489 code('#include "params/${{cls._base.type}}.hh"') 490 code() 491 492 for ptype in ptypes: 493 if issubclass(ptype, Enum): 494 code('#include "enums/${{ptype.__name__}}.hh"') 495 code() 496 497 # now generate the actual param struct |
498 code("struct ${cls}Params") 499 if cls._base: 500 code(" : public ${{cls._base.type}}Params") 501 code("{") 502 if not hasattr(cls, 'abstract') or not cls.abstract: 503 if 'type' in cls.__dict__: 504 code(" ${{cls.cxx_type}} create();") 505 506 code.indent() |
507 if cls == SimObject: |
508 code(''' 509 SimObjectParams() 510 { 511 extern EventQueue mainEventQueue; 512 eventq = &mainEventQueue; 513 } 514 virtual ~SimObjectParams() {} |
515 |
516 std::string name; 517 PyObject *pyobj; 518 EventQueue *eventq; 519 ''') 520 for param in params: 521 param.cxx_decl(code) 522 code.dedent() 523 code('};') |
524 525 code() 526 code('#endif // __PARAMS__${cls}__') 527 return code 528 529 530 531# The SimObject class is the root of the special hierarchy. Most of 532# the code in this class deals with the configuration hierarchy itself 533# (parent/child node relationships). 534class SimObject(object): 535 # Specify metaclass. Any class inheriting from SimObject will 536 # get this metaclass. 537 __metaclass__ = MetaSimObject 538 type = 'SimObject' 539 abstract = True 540 |
541 @classmethod 542 def export_method_cxx_predecls(cls, code): 543 code(''' 544#include <Python.h> 545 546#include "sim/serialize.hh" 547#include "sim/sim_object.hh" 548''') 549 550 @classmethod 551 def export_method_swig_predecls(cls, code): 552 code(''' 553%include <std_string.i> 554''') 555 556 @classmethod 557 def export_methods(cls, code): 558 code(''' 559 enum State { 560 Running, 561 Draining, 562 Drained 563 }; 564 565 void init(); 566 void loadState(Checkpoint *cp); 567 void initState(); 568 void regStats(); 569 void regFormulas(); 570 void resetStats(); 571 void startup(); 572 573 unsigned int drain(Event *drain_event); 574 void resume(); 575 void switchOut(); 576 void takeOverFrom(BaseCPU *cpu); 577''') 578 |
579 # Initialize new instance. For objects with SimObject-valued 580 # children, we need to recursively clone the classes represented 581 # by those param values as well in a consistent "deep copy"-style 582 # fashion. That is, we want to make sure that each instance is 583 # cloned only once, and that if there are multiple references to 584 # the same original object, we end up with the corresponding 585 # cloned references all pointing to the same cloned instance. 586 def __init__(self, **kwargs): --- 506 unchanged lines hidden --- |