summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/SConscript36
-rw-r--r--python/m5/__init__.py30
-rw-r--r--python/m5/config.py10
-rw-r--r--python/m5/objects/BaseCPU.mpy2
-rw-r--r--python/m5/smartdict.py23
5 files changed, 63 insertions, 38 deletions
diff --git a/python/SConscript b/python/SConscript
index 81bc52286..a50903964 100644
--- a/python/SConscript
+++ b/python/SConscript
@@ -26,7 +26,14 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import os, os.path, re
+import os, os.path, re, sys
+
+Import('env')
+
+# tell python where to find m5 python code
+sys.path.append(os.path.join(env['SRCDIR'], 'python'))
+
+import m5scons
def WriteEmbeddedPyFile(target, source, path, name, ext, filename):
if isinstance(source, str):
@@ -89,7 +96,6 @@ def splitpath(path):
path.insert(0, base)
return path, file
-Import('env')
def MakeEmbeddedPyFile(target, source, env):
target = file(str(target[0]), 'w')
@@ -145,27 +151,11 @@ def MakeEmbeddedPyFile(target, source, env):
WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename)
def MakeDefinesPyFile(target, source, env):
- target = file(str(target[0]), 'w')
-
- print >>target, "import os"
- defines = env['CPPDEFINES']
- if isinstance(defines, list):
- for var in defines:
- if isinstance(var, tuple):
- key,val = var
- else:
- key,val = var,'True'
-
- if not isinstance(key, basestring):
- panic("invalid type for define: %s" % type(key))
-
- print >>target, "os.environ['%s'] = '%s'" % (key, val)
-
- elif isinstance(defines, dict):
- for key,val in defines.iteritems():
- print >>target, "os.environ['%s'] = '%s'" % (key, val)
- else:
- panic("invalid type for defines: %s" % type(defines))
+ f = file(str(target[0]), 'w')
+ print >>f, "import __main__"
+ print >>f, "__main__.m5_build_env = ",
+ print >>f, m5scons.flatten_defines(env['CPPDEFINES'])
+ f.close()
CFileCounter = 0
def MakePythonCFile(target, source, env):
diff --git a/python/m5/__init__.py b/python/m5/__init__.py
index 3d54a83da..16f48dba3 100644
--- a/python/m5/__init__.py
+++ b/python/m5/__init__.py
@@ -1,10 +1,36 @@
+import sys, os
+
+# the mpy import code is added to the global import meta_path as a
+# side effect of this import
from mpy_importer import AddToPath, LoadMpyFile
+# define this here so we can use it right away if necessary
+def panic(string):
+ print >>sys.stderr, 'panic:', string
+ sys.exit(1)
+
+# find the m5 compile options: must be specified as a dict in
+# __main__.m5_build_env.
+import __main__
+if not hasattr(__main__, 'm5_build_env'):
+ panic("__main__ must define m5_build_env")
+
+# make a SmartDict out of the build options for our local use
+import smartdict
+build_env = smartdict.SmartDict()
+build_env.update(__main__.m5_build_env)
+
+# make a SmartDict out of the OS environment too
+env = smartdict.SmartDict()
+env.update(os.environ)
+
+# import the main m5 config code
from config import *
-config.add_param_types(config.__dict__)
+config.add_param_types(config)
+# import the built-in object definitions
from objects import *
-config.add_param_types(objects.__dict__)
+config.add_param_types(objects)
cpp_classes = config.MetaSimObject.cpp_classes
cpp_classes.sort()
diff --git a/python/m5/config.py b/python/m5/config.py
index 7dfc4fb04..a9d7a2f41 100644
--- a/python/m5/config.py
+++ b/python/m5/config.py
@@ -27,7 +27,6 @@
from __future__ import generators
import os, re, sys, types, inspect
-from smartdict import SmartDict
from convert import *
noDot = False
@@ -36,13 +35,6 @@ try:
except:
noDot = True
-env = SmartDict()
-env.update(os.environ)
-
-def panic(string):
- print >>sys.stderr, 'panic:', string
- sys.exit(1)
-
def issequence(value):
return isinstance(value, tuple) or isinstance(value, list)
@@ -1347,7 +1339,7 @@ class SimObject(ConfigNode, ParamType):
# __all__ defines the list of symbols that get exported when
# 'from config import *' is invoked. Try to keep this reasonably
# short to avoid polluting other namespaces.
-__all__ = ['env', 'issequence', 'panic',
+__all__ = ['issequence',
'ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam',
'Super', 'Enum',
'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
diff --git a/python/m5/objects/BaseCPU.mpy b/python/m5/objects/BaseCPU.mpy
index be93e8ad1..5d8305d88 100644
--- a/python/m5/objects/BaseCPU.mpy
+++ b/python/m5/objects/BaseCPU.mpy
@@ -4,7 +4,7 @@ simobj BaseCPU(SimObject):
icache = Param.BaseMem(NULL, "L1 instruction cache object")
dcache = Param.BaseMem(NULL, "L1 data cache object")
- if env.get('FULL_SYSTEM', 'False'):
+ if build_env['FULL_SYSTEM']:
dtb = Param.AlphaDTB("Data TLB")
itb = Param.AlphaITB("Instruction TLB")
mem = Param.FunctionalMemory("memory")
diff --git a/python/m5/smartdict.py b/python/m5/smartdict.py
index e282bc07b..4ea8210d3 100644
--- a/python/m5/smartdict.py
+++ b/python/m5/smartdict.py
@@ -1,6 +1,23 @@
+# The SmartDict class fixes a couple of issues with using the content
+# of os.environ or similar dicts of strings as Python variables:
+#
+# 1) Undefined variables should return False rather than raising KeyError.
+#
+# 2) String values of 'False', '0', etc., should evaluate to False
+# (not just the empty string).
+#
+# #1 is solved by overriding __getitem__, and #2 is solved by using a
+# proxy class for values and overriding __nonzero__ on the proxy.
+# Everything else is just to (a) make proxies behave like normal
+# values otherwise, (b) make sure any dict operation returns a proxy
+# rather than a normal value, and (c) coerce values written to the
+# dict to be strings.
+
+
from convert import *
class SmartDict(dict):
+
class Proxy(str):
def __int__(self):
return int(to_integer(str(self)))
@@ -58,7 +75,7 @@ class SmartDict(dict):
def __getitem__(self, key):
- return self.Proxy(dict.__getitem__(self, key))
+ return self.Proxy(dict.get(self, key, 'False'))
def __setitem__(self, key, item):
dict.__setitem__(self, key, str(item))
@@ -77,9 +94,9 @@ class SmartDict(dict):
for key,value in dict.iteritems(self):
yield key, self.Proxy(value)
- def get(self, key, default=''):
+ def get(self, key, default='False'):
return self.Proxy(dict.get(self, key, str(default)))
- def setdefault(self, key, default=''):
+ def setdefault(self, key, default='False'):
return self.Proxy(dict.setdefault(self, key, str(default)))