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
|
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
|
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
|
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()) |
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 --- |