summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2005-11-01 14:11:54 -0500
committerSteve Reinhardt <stever@eecs.umich.edu>2005-11-01 14:11:54 -0500
commitfb4f83809fd8a427503b109848ca7c8f3c179e8c (patch)
tree3b3719cd3529e704d3821e1e0edd5d623e77cbb0
parent76843fc2649a4081d2e8c4bfbd4f7b5929ff5886 (diff)
downloadgem5-fb4f83809fd8a427503b109848ca7c8f3c179e8c.tar.xz
Allow math on CheckedInt-derived ParamValue classes w/o
losing type information. python/m5/config.py: Allow math on CheckedInt-derived ParamValue classes w/o losing type information. - Make CheckedInt derive from NumericParamValue, and *not* multiply inherit from long - Move CheckedInt bounds check to _check() hook so we can call it when value is updated (not just in constructor) python/m5/convert.py: - make toInteger() return a long, making toLong() unnecessary - toMemorySize should return long rather than float --HG-- extra : convert_revision : c1cf5e15b9ff35d9b573dd545e076fe68afef989
-rw-r--r--python/m5/config.py102
-rw-r--r--python/m5/convert.py22
2 files changed, 69 insertions, 55 deletions
diff --git a/python/m5/config.py b/python/m5/config.py
index 3c49421d3..86acb75f8 100644
--- a/python/m5/config.py
+++ b/python/m5/config.py
@@ -825,6 +825,40 @@ VectorParam = ParamFactory(VectorParamDesc)
#
#####################################################################
+# superclass for "numeric" parameter values, to emulate math
+# operations in a type-safe way. e.g., a Latency times an int returns
+# a new Latency object.
+class NumericParamValue(ParamValue):
+ def __str__(self):
+ return str(self.value)
+
+ def __float__(self):
+ return float(self.value)
+
+ # hook for bounds checking
+ def _check(self):
+ return
+
+ def __mul__(self, other):
+ newobj = self.__class__(self)
+ newobj.value *= other
+ newobj._check()
+ return newobj
+
+ __rmul__ = __mul__
+
+ def __div__(self, other):
+ newobj = self.__class__(self)
+ newobj.value /= other
+ newobj._check()
+ return newobj
+
+ def __sub__(self, other):
+ newobj = self.__class__(self)
+ newobj.value -= other
+ newobj._check()
+ return newobj
+
class Range(ParamValue):
type = int # default; can be overridden in subclasses
def __init__(self, *args, **kwargs):
@@ -891,18 +925,20 @@ class CheckedIntType(type):
# class is subclassed to generate parameter classes with specific
# bounds. Initialization of the min and max bounds is done in the
# metaclass CheckedIntType.__init__.
-class CheckedInt(long,ParamValue):
+class CheckedInt(NumericParamValue):
__metaclass__ = CheckedIntType
- def __new__(cls, value):
- if isinstance(value, str):
- value = toInteger(value)
-
- self = long.__new__(cls, value)
-
- if not cls.min <= self <= cls.max:
+ def _check(self):
+ if not self.min <= self.value <= self.max:
raise TypeError, 'Integer param out of bounds %d < %d < %d' % \
- (cls.min, self, cls.max)
+ (self.min, self.value, self.max)
+
+ def __init__(self, value):
+ if isinstance(value, str):
+ self.value = toInteger(value)
+ elif isinstance(value, (int, long)):
+ self.value = long(value)
+ self._check()
return self
class Int(CheckedInt): size = 32; unsigned = False
@@ -930,19 +966,28 @@ class Float(ParamValue, float):
class MemorySize(CheckedInt):
size = 64
unsigned = True
- def __new__(cls, value):
- return super(MemorySize, cls).__new__(cls, toMemorySize(value))
+ def __init__(self, value):
+ if isinstance(value, MemorySize):
+ self.value = value.value
+ else:
+ self.value = toMemorySize(value)
+ self._check()
+ return self
class Addr(CheckedInt):
size = 64
unsigned = True
- def __new__(cls, value):
- try:
- value = long(toMemorySize(value))
- except TypeError:
- value = long(value)
- return super(Addr, cls).__new__(cls, value)
+ def __init__(self, value):
+ if isinstance(value, Addr):
+ self.value = value.value
+ else:
+ try:
+ self.value = toMemorySize(value)
+ except TypeError:
+ self.value = long(value)
+ self._check()
+ return self
class AddrRange(Range):
type = Addr
@@ -1123,29 +1168,6 @@ def tick_check(float_ticks):
#raise ValueError
return int_ticks
-# superclass for "numeric" parameter values, to emulate math
-# operations in a type-safe way. e.g., a Latency times an int returns
-# a new Latency object.
-class NumericParamValue(ParamValue):
- def __str__(self):
- return str(self.value)
-
- def __float__(self):
- return float(self.value)
-
- def __mul__(self, other):
- newobj = self.__class__(self)
- newobj.value *= other
- return newobj
-
- __rmul__ = __mul__
-
- def __div__(self, other):
- newobj = self.__class__(self)
- newobj.value /= other
- return newobj
-
-
def getLatency(value):
if isinstance(value, Latency) or isinstance(value, Clock):
return value.value
diff --git a/python/m5/convert.py b/python/m5/convert.py
index 9d9f4efa7..73181e985 100644
--- a/python/m5/convert.py
+++ b/python/m5/convert.py
@@ -89,17 +89,9 @@ def toFloat(value):
else:
return float(value)
-def toLong(value):
- value = toFloat(value)
- result = int(value)
- if value != result:
- raise ValueError, "cannot convert '%s' to long" % value
-
- return result
-
def toInteger(value):
value = toFloat(value)
- result = int(value)
+ result = long(value)
if value != result:
raise ValueError, "cannot convert '%s' to integer" % value
@@ -220,16 +212,16 @@ def toMemorySize(value):
raise TypeError, "wrong type '%s' should be str" % type(value)
if value.endswith('PB'):
- return float(value[:-2]) * pebi
+ return long(value[:-2]) * pebi
elif value.endswith('TB'):
- return float(value[:-2]) * tebi
+ return long(value[:-2]) * tebi
elif value.endswith('GB'):
- return float(value[:-2]) * gibi
+ return long(value[:-2]) * gibi
elif value.endswith('MB'):
- return float(value[:-2]) * mebi
+ return long(value[:-2]) * mebi
elif value.endswith('kB'):
- return float(value[:-2]) * kibi
+ return long(value[:-2]) * kibi
elif value.endswith('B'):
- return float(value[:-1])
+ return long(value[:-1])
raise ValueError, "cannot convert '%s' to memory size" % value