SimObject.py (11988:665cd5f8b52b) SimObject.py (11991:d3f19484145f)
1# Copyright (c) 2017 ARM Limited
2# All rights reserved.
3#
4# The license below extends only to copyright in the software and shall
5# not be construed as granting a license to any other intellectual
6# property including but not limited to intellectual property relating
7# to a hardware implementation of the functionality of the software
8# licensed hereunder. You may use the software subject to the license

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

505
506 cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class']
507
508 if 'cxx_header' not in cls._value_dict:
509 global noCxxHeader
510 noCxxHeader = True
511 warn("No header file specified for SimObject: %s", name)
512
1# Copyright (c) 2017 ARM Limited
2# All rights reserved.
3#
4# The license below extends only to copyright in the software and shall
5# not be construed as granting a license to any other intellectual
6# property including but not limited to intellectual property relating
7# to a hardware implementation of the functionality of the software
8# licensed hereunder. You may use the software subject to the license

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

505
506 cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class']
507
508 if 'cxx_header' not in cls._value_dict:
509 global noCxxHeader
510 noCxxHeader = True
511 warn("No header file specified for SimObject: %s", name)
512
513 # Export methods are automatically inherited via C++, so we
514 # don't want the method declarations to get inherited on the
515 # python side (and thus end up getting repeated in the wrapped
516 # versions of derived classes). The code below basicallly
517 # suppresses inheritance by substituting in the base (null)
518 # versions of these methods unless a different version is
519 # explicitly supplied.
520 for method_name in ('export_methods', 'export_method_swig_predecls'):
521 if method_name not in cls.__dict__:
522 base_method = getattr(MetaSimObject, method_name)
523 m = MethodType(base_method, cls, MetaSimObject)
524 setattr(cls, method_name, m)
525
526 # Now process the _value_dict items. They could be defining
527 # new (or overriding existing) parameters or ports, setting
528 # class keywords (e.g., 'abstract'), or setting parameter
529 # values or port bindings. The first 3 can only be set when
530 # the class is defined, so we handle them here. The others
531 # can be set later too, so just emulate that by calling
532 # setattr().
533 for key,val in cls._value_dict.items():

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

671
672 # See ParamValue.cxx_predecls for description.
673 def cxx_predecls(cls, code):
674 code('#include "params/$cls.hh"')
675
676 def pybind_predecls(cls, code):
677 code('#include "${{cls.cxx_header}}"')
678
513 # Now process the _value_dict items. They could be defining
514 # new (or overriding existing) parameters or ports, setting
515 # class keywords (e.g., 'abstract'), or setting parameter
516 # values or port bindings. The first 3 can only be set when
517 # the class is defined, so we handle them here. The others
518 # can be set later too, so just emulate that by calling
519 # setattr().
520 for key,val in cls._value_dict.items():

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

658
659 # See ParamValue.cxx_predecls for description.
660 def cxx_predecls(cls, code):
661 code('#include "params/$cls.hh"')
662
663 def pybind_predecls(cls, code):
664 code('#include "${{cls.cxx_header}}"')
665
679 # See ParamValue.swig_predecls for description.
680 def swig_predecls(cls, code):
681 code('%import "python/_m5/param_$cls.i"')
682
683 # Hook for exporting additional C++ methods to Python via SWIG.
684 # Default is none, override using @classmethod in class definition.
685 def export_methods(cls, code):
686 pass
687
688 # Generate the code needed as a prerequisite for the C++ methods
689 # exported via export_methods() to be processed by SWIG.
690 # Typically generates one or more %include or %import statements.
691 # If any methods are exported, typically at least the C++ header
692 # declaring the relevant SimObject class must be included.
693 def export_method_swig_predecls(cls, code):
694 pass
695
696 # Generate the declaration for this object for wrapping with SWIG.
697 # Generates code that goes into a SWIG .i file. Called from
698 # src/SConscript.
699 def swig_decl(cls, code):
700 class_path = cls.cxx_class.split('::')
701 classname = class_path[-1]
702 namespaces = class_path[:-1]
703
704 # The 'local' attribute restricts us to the params declared in
705 # the object itself, not including inherited params (which
706 # will also be inherited from the base class's param struct
707 # here). Sort the params based on their key
708 params = map(lambda (k, v): v, sorted(cls._params.local.items()))
709 ports = cls._ports.local
710
711 code('%module(package="_m5") param_$cls')
712 code()
713 code('%{')
714 code('#include "sim/sim_object.hh"')
715 code('#include "params/$cls.hh"')
716 for param in params:
717 param.cxx_predecls(code)
718 code('#include "${{cls.cxx_header}}"')
719 code('''\
720/**
721 * This is a workaround for bug in swig. Prior to gcc 4.6.1 the STL
722 * headers like vector, string, etc. used to automatically pull in
723 * the cstddef header but starting with gcc 4.6.1 they no longer do.
724 * This leads to swig generated a file that does not compile so we
725 * explicitly include cstddef. Additionally, including version 2.0.4,
726 * swig uses ptrdiff_t without the std:: namespace prefix which is
727 * required with gcc 4.6.1. We explicitly provide access to it.
728 */
729#include <cstddef>
730using std::ptrdiff_t;
731''')
732 code('%}')
733 code()
734
735 for param in params:
736 param.swig_predecls(code)
737 cls.export_method_swig_predecls(code)
738
739 code()
740 if cls._base:
741 code('%import "python/_m5/param_${{cls._base}}.i"')
742 code()
743
744 for ns in namespaces:
745 code('namespace $ns {')
746
747 if namespaces:
748 code('// avoid name conflicts')
749 sep_string = '_COLONS_'
750 flat_name = sep_string.join(class_path)
751 code('%rename($flat_name) $classname;')
752
753 code()
754 code('// stop swig from creating/wrapping default ctor/dtor')
755 code('%nodefault $classname;')
756 code('class $classname')
757 if cls._base:
758 bases = [ cls._base.cxx_class ] + cls.cxx_bases
759 else:
760 bases = cls.cxx_bases
761 base_first = True
762 for base in bases:
763 if base_first:
764 code(' : public ${{base}}')
765 base_first = False
766 else:
767 code(' , public ${{base}}')
768
769 code('{')
770 code(' public:')
771 cls.export_methods(code)
772 code('};')
773
774 for ns in reversed(namespaces):
775 code('} // namespace $ns')
776
777 code()
778 code('%include "params/$cls.hh"')
779
780 def pybind_decl(cls, code):
781 class_path = cls.cxx_class.split('::')
782 namespaces, classname = class_path[:-1], class_path[-1]
783 py_class_name = '_COLONS_'.join(class_path) if namespaces else \
784 classname;
785
786 # The 'local' attribute restricts us to the params declared in
787 # the object itself, not including inherited params (which

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

1030 __metaclass__ = MetaSimObject
1031 type = 'SimObject'
1032 abstract = True
1033
1034 cxx_header = "sim/sim_object.hh"
1035 cxx_bases = [ "Drainable", "Serializable" ]
1036 eventq_index = Param.UInt32(Parent.eventq_index, "Event Queue Index")
1037
666 def pybind_decl(cls, code):
667 class_path = cls.cxx_class.split('::')
668 namespaces, classname = class_path[:-1], class_path[-1]
669 py_class_name = '_COLONS_'.join(class_path) if namespaces else \
670 classname;
671
672 # The 'local' attribute restricts us to the params declared in
673 # the object itself, not including inherited params (which

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

916 __metaclass__ = MetaSimObject
917 type = 'SimObject'
918 abstract = True
919
920 cxx_header = "sim/sim_object.hh"
921 cxx_bases = [ "Drainable", "Serializable" ]
922 eventq_index = Param.UInt32(Parent.eventq_index, "Event Queue Index")
923
1038 @classmethod
1039 def export_method_swig_predecls(cls, code):
1040 code('''
1041%include <std_string.i>
1042
1043%import "python/swig/drain.i"
1044%import "python/swig/serialize.i"
1045''')
1046
1047 @classmethod
1048 def export_methods(cls, code):
1049 code('''
1050 void init();
1051 void loadState(CheckpointIn &cp);
1052 void initState();
1053 void memInvalidate();
1054 void memWriteback();
1055 void regStats();
1056 void resetStats();
1057 void regProbePoints();
1058 void regProbeListeners();
1059 void startup();
1060''')
1061
1062 cxx_exports = [
1063 PyBindMethod("init"),
1064 PyBindMethod("initState"),
1065 PyBindMethod("memInvalidate"),
1066 PyBindMethod("memWriteback"),
1067 PyBindMethod("regStats"),
1068 PyBindMethod("resetStats"),
1069 PyBindMethod("regProbePoints"),

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

1233 if self._values.has_key(attr):
1234 return self._values[attr]
1235
1236 if self._children.has_key(attr):
1237 return self._children[attr]
1238
1239 # If the attribute exists on the C++ object, transparently
1240 # forward the reference there. This is typically used for
924 cxx_exports = [
925 PyBindMethod("init"),
926 PyBindMethod("initState"),
927 PyBindMethod("memInvalidate"),
928 PyBindMethod("memWriteback"),
929 PyBindMethod("regStats"),
930 PyBindMethod("resetStats"),
931 PyBindMethod("regProbePoints"),

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

1095 if self._values.has_key(attr):
1096 return self._values[attr]
1097
1098 if self._children.has_key(attr):
1099 return self._children[attr]
1100
1101 # If the attribute exists on the C++ object, transparently
1102 # forward the reference there. This is typically used for
1241 # SWIG-wrapped methods such as init(), regStats(),
1242 # resetStats(), startup(), drain(), and
1243 # resume().
1103 # methods exported to Python (e.g., init(), and startup())
1244 if self._ccObject and hasattr(self._ccObject, attr):
1245 return getattr(self._ccObject, attr)
1246
1247 err_string = "object '%s' has no attribute '%s'" \
1248 % (self.__class__.__name__, attr)
1249
1250 if not self._ccObject:
1251 err_string += "\n (C++ object is not yet constructed," \

--- 431 unchanged lines hidden ---
1104 if self._ccObject and hasattr(self._ccObject, attr):
1105 return getattr(self._ccObject, attr)
1106
1107 err_string = "object '%s' has no attribute '%s'" \
1108 % (self.__class__.__name__, attr)
1109
1110 if not self._ccObject:
1111 err_string += "\n (C++ object is not yet constructed," \

--- 431 unchanged lines hidden ---