misc: Run pre-commit run on all files in repo
The following command was run: ``` pre-commit run --all-files ``` This ensures all the files in the repository are formatted to pass our checks. Change-Id: Ia2fe3529a50ad925d1076a612d60a4280adc40de Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/62572 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
committed by
Bobby Bruce
parent
64add0e04d
commit
2bc5a8b71a
@@ -26,16 +26,17 @@
|
||||
import array
|
||||
import functools
|
||||
|
||||
|
||||
def bytesToCppArray(code, symbol, data):
|
||||
'''
|
||||
"""
|
||||
Output an array of bytes to a code formatter as a c++ array declaration.
|
||||
'''
|
||||
code('const std::uint8_t ${symbol}[] = {')
|
||||
"""
|
||||
code("const std::uint8_t ${symbol}[] = {")
|
||||
code.indent()
|
||||
step = 16
|
||||
for i in range(0, len(data), step):
|
||||
x = array.array('B', data[i:i+step])
|
||||
strs = map(lambda i: f'{i},', x)
|
||||
x = array.array("B", data[i : i + step])
|
||||
strs = map(lambda i: f"{i},", x)
|
||||
code(functools.reduce(lambda x, y: x + y, strs))
|
||||
code.dedent()
|
||||
code('};')
|
||||
code("};")
|
||||
|
||||
@@ -45,6 +45,7 @@ import inspect
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
class lookup(object):
|
||||
def __init__(self, formatter, frame, *args, **kwargs):
|
||||
self.frame = frame
|
||||
@@ -64,10 +65,10 @@ class lookup(object):
|
||||
if item in self.kwargs:
|
||||
return self.kwargs[item]
|
||||
|
||||
if item == '__file__':
|
||||
if item == "__file__":
|
||||
return self.frame.f_code.co_filename
|
||||
|
||||
if item == '__line__':
|
||||
if item == "__line__":
|
||||
return self.frame.f_lineno
|
||||
|
||||
if self.formatter.locals and item in self.frame.f_locals:
|
||||
@@ -89,6 +90,7 @@ class lookup(object):
|
||||
pass
|
||||
raise IndexError("Could not find '%s'" % item)
|
||||
|
||||
|
||||
class code_formatter_meta(type):
|
||||
pattern = r"""
|
||||
(?:
|
||||
@@ -102,44 +104,48 @@ class code_formatter_meta(type):
|
||||
%(delim)s(?P<invalid>) # ill-formed delimiter exprs
|
||||
)
|
||||
"""
|
||||
|
||||
def __init__(cls, name, bases, dct):
|
||||
super(code_formatter_meta, cls).__init__(name, bases, dct)
|
||||
if 'pattern' in dct:
|
||||
if "pattern" in dct:
|
||||
pat = cls.pattern
|
||||
else:
|
||||
# tuple expansion to ensure strings are proper length
|
||||
lb,rb = cls.braced
|
||||
lb1,lb2,rb2,rb1 = cls.double_braced
|
||||
lb, rb = cls.braced
|
||||
lb1, lb2, rb2, rb1 = cls.double_braced
|
||||
pat = code_formatter_meta.pattern % {
|
||||
'delim' : re.escape(cls.delim),
|
||||
'ident' : cls.ident,
|
||||
'pos' : cls.pos,
|
||||
'lb' : re.escape(lb),
|
||||
'rb' : re.escape(rb),
|
||||
'ldb' : re.escape(lb1+lb2),
|
||||
'rdb' : re.escape(rb2+rb1),
|
||||
}
|
||||
"delim": re.escape(cls.delim),
|
||||
"ident": cls.ident,
|
||||
"pos": cls.pos,
|
||||
"lb": re.escape(lb),
|
||||
"rb": re.escape(rb),
|
||||
"ldb": re.escape(lb1 + lb2),
|
||||
"rdb": re.escape(rb2 + rb1),
|
||||
}
|
||||
cls.pattern = re.compile(pat, re.VERBOSE | re.DOTALL | re.MULTILINE)
|
||||
|
||||
|
||||
class code_formatter(object, metaclass=code_formatter_meta):
|
||||
delim = r'$'
|
||||
ident = r'[_A-z]\w*'
|
||||
pos = r'[0-9]+'
|
||||
braced = r'{}'
|
||||
double_braced = r'{{}}'
|
||||
delim = r"$"
|
||||
ident = r"[_A-z]\w*"
|
||||
pos = r"[0-9]+"
|
||||
braced = r"{}"
|
||||
double_braced = r"{{}}"
|
||||
|
||||
globals = True
|
||||
locals = True
|
||||
fix_newlines = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._data = []
|
||||
self._dict = {}
|
||||
self._indent_level = 0
|
||||
self._indent_spaces = 4
|
||||
self.globals = kwargs.pop('globals', type(self).globals)
|
||||
self.locals = kwargs.pop('locals', type(self).locals)
|
||||
self._fix_newlines = \
|
||||
kwargs.pop('fix_newlines', type(self).fix_newlines)
|
||||
self.globals = kwargs.pop("globals", type(self).globals)
|
||||
self.locals = kwargs.pop("locals", type(self).locals)
|
||||
self._fix_newlines = kwargs.pop(
|
||||
"fix_newlines", type(self).fix_newlines
|
||||
)
|
||||
|
||||
if args:
|
||||
self.__call__(args)
|
||||
@@ -171,38 +177,44 @@ class code_formatter(object, metaclass=code_formatter_meta):
|
||||
# Add a comment to inform which file generated the generated file
|
||||
# to make it easier to backtrack and modify generated code
|
||||
frame = inspect.currentframe().f_back
|
||||
if re.match(r'^\.(cc|hh|c|h)$', extension) is not None:
|
||||
f.write(f'''/**
|
||||
if re.match(r"^\.(cc|hh|c|h)$", extension) is not None:
|
||||
f.write(
|
||||
f"""/**
|
||||
* DO NOT EDIT THIS FILE!
|
||||
* File automatically generated by
|
||||
* {frame.f_code.co_filename}:{frame.f_lineno}
|
||||
*/
|
||||
|
||||
''')
|
||||
elif re.match(r'^\.py$', extension) is not None:
|
||||
f.write(f'''#
|
||||
"""
|
||||
)
|
||||
elif re.match(r"^\.py$", extension) is not None:
|
||||
f.write(
|
||||
f"""#
|
||||
# DO NOT EDIT THIS FILE!
|
||||
# File automatically generated by
|
||||
# {frame.f_code.co_filename}:{frame.f_lineno}
|
||||
#
|
||||
|
||||
''')
|
||||
elif re.match(r'^\.html$', extension) is not None:
|
||||
f.write(f'''<!--
|
||||
"""
|
||||
)
|
||||
elif re.match(r"^\.html$", extension) is not None:
|
||||
f.write(
|
||||
f"""<!--
|
||||
DO NOT EDIT THIS FILE!
|
||||
File automatically generated by
|
||||
{frame.f_code.co_filename}:{frame.f_lineno}
|
||||
-->
|
||||
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
for data in self._data:
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
def __str__(self):
|
||||
data = ''.join(self._data)
|
||||
self._data = [ data ]
|
||||
data = "".join(self._data)
|
||||
self._data = [data]
|
||||
return data
|
||||
|
||||
def __getitem__(self, item):
|
||||
@@ -231,21 +243,21 @@ class code_formatter(object, metaclass=code_formatter_meta):
|
||||
self._data.append(data)
|
||||
return
|
||||
|
||||
initial_newline = not self._data or self._data[-1] == '\n'
|
||||
initial_newline = not self._data or self._data[-1] == "\n"
|
||||
for line in data.splitlines():
|
||||
if line:
|
||||
if self._indent_level:
|
||||
self._data.append(' ' * self._indent_level)
|
||||
self._data.append(" " * self._indent_level)
|
||||
self._data.append(line)
|
||||
|
||||
if line or not initial_newline:
|
||||
self._data.append('\n')
|
||||
self._data.append("\n")
|
||||
|
||||
initial_newline = False
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
if not args:
|
||||
self._data.append('\n')
|
||||
self._data.append("\n")
|
||||
return
|
||||
|
||||
format = args[0]
|
||||
@@ -254,51 +266,56 @@ class code_formatter(object, metaclass=code_formatter_meta):
|
||||
frame = inspect.currentframe().f_back
|
||||
|
||||
l = lookup(self, frame, *args, **kwargs)
|
||||
|
||||
def convert(match):
|
||||
ident = match.group('lone')
|
||||
ident = match.group("lone")
|
||||
# check for a lone identifier
|
||||
if ident:
|
||||
indent = match.group('indent') # must be spaces
|
||||
lone = '%s' % (l[ident], )
|
||||
indent = match.group("indent") # must be spaces
|
||||
lone = "%s" % (l[ident],)
|
||||
|
||||
def indent_lines(gen):
|
||||
for line in gen:
|
||||
yield indent
|
||||
yield line
|
||||
return ''.join(indent_lines(lone.splitlines(True)))
|
||||
|
||||
return "".join(indent_lines(lone.splitlines(True)))
|
||||
|
||||
# check for an identifier, braced or not
|
||||
ident = match.group('ident') or match.group('b_ident')
|
||||
ident = match.group("ident") or match.group("b_ident")
|
||||
if ident is not None:
|
||||
return '%s' % (l[ident], )
|
||||
return "%s" % (l[ident],)
|
||||
|
||||
# check for a positional parameter, braced or not
|
||||
pos = match.group('pos') or match.group('b_pos')
|
||||
pos = match.group("pos") or match.group("b_pos")
|
||||
if pos is not None:
|
||||
pos = int(pos)
|
||||
if pos > len(args):
|
||||
raise ValueError \
|
||||
('Positional parameter #%d not found in pattern' % pos,
|
||||
code_formatter.pattern)
|
||||
return '%s' % (args[int(pos)], )
|
||||
raise ValueError(
|
||||
"Positional parameter #%d not found in pattern" % pos,
|
||||
code_formatter.pattern,
|
||||
)
|
||||
return "%s" % (args[int(pos)],)
|
||||
|
||||
# check for a double braced expression
|
||||
eval_expr = match.group('eval')
|
||||
eval_expr = match.group("eval")
|
||||
if eval_expr is not None:
|
||||
result = eval(eval_expr, {}, l)
|
||||
return '%s' % (result, )
|
||||
return "%s" % (result,)
|
||||
|
||||
# check for an escaped delimiter
|
||||
if match.group('escaped') is not None:
|
||||
return '$'
|
||||
if match.group("escaped") is not None:
|
||||
return "$"
|
||||
|
||||
# At this point, we have to match invalid
|
||||
if match.group('invalid') is None:
|
||||
if match.group("invalid") is None:
|
||||
# didn't match invalid!
|
||||
raise ValueError('Unrecognized named group in pattern',
|
||||
code_formatter.pattern)
|
||||
raise ValueError(
|
||||
"Unrecognized named group in pattern",
|
||||
code_formatter.pattern,
|
||||
)
|
||||
|
||||
i = match.start('invalid')
|
||||
i = match.start("invalid")
|
||||
if i == 0:
|
||||
colno = 1
|
||||
lineno = 1
|
||||
@@ -307,52 +324,64 @@ class code_formatter(object, metaclass=code_formatter_meta):
|
||||
colno = i - sum(len(z) for z in lines)
|
||||
lineno = len(lines)
|
||||
|
||||
raise ValueError('Invalid format string: line %d, col %d' %
|
||||
(lineno, colno))
|
||||
raise ValueError(
|
||||
"Invalid format string: line %d, col %d" % (lineno, colno)
|
||||
)
|
||||
|
||||
d = code_formatter.pattern.sub(convert, format)
|
||||
self._append(d)
|
||||
|
||||
__all__ = [ "code_formatter" ]
|
||||
|
||||
if __name__ == '__main__':
|
||||
__all__ = ["code_formatter"]
|
||||
|
||||
if __name__ == "__main__":
|
||||
from .code_formatter import code_formatter
|
||||
|
||||
f = code_formatter()
|
||||
|
||||
class Foo(dict):
|
||||
def __init__(self, **kwargs):
|
||||
self.update(kwargs)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return self[attr]
|
||||
|
||||
x = "this is a test"
|
||||
l = [ [Foo(x=[Foo(y=9)])] ]
|
||||
l = [[Foo(x=[Foo(y=9)])]]
|
||||
|
||||
y = code_formatter()
|
||||
y('''
|
||||
y(
|
||||
"""
|
||||
{
|
||||
this_is_a_test();
|
||||
}
|
||||
''')
|
||||
f(' $y')
|
||||
f('''$__file__:$__line__
|
||||
{''')
|
||||
"""
|
||||
)
|
||||
f(" $y")
|
||||
f(
|
||||
"""$__file__:$__line__
|
||||
{"""
|
||||
)
|
||||
f("${{', '.join(str(x) for x in range(4))}}")
|
||||
f('${x}')
|
||||
f('$x')
|
||||
f("${x}")
|
||||
f("$x")
|
||||
f.indent()
|
||||
for i in range(5):
|
||||
f('$x')
|
||||
f('$i')
|
||||
f('$0', "zero")
|
||||
f('$1 $0', "zero", "one")
|
||||
f('${0}', "he went")
|
||||
f('${0}asdf', "he went")
|
||||
f("$x")
|
||||
f("$i")
|
||||
f("$0", "zero")
|
||||
f("$1 $0", "zero", "one")
|
||||
f("${0}", "he went")
|
||||
f("${0}asdf", "he went")
|
||||
f.dedent()
|
||||
|
||||
f('''
|
||||
f(
|
||||
"""
|
||||
${{l[0][0]["x"][0].y}}
|
||||
}
|
||||
''', 1, 9)
|
||||
""",
|
||||
1,
|
||||
9,
|
||||
)
|
||||
|
||||
print(f, end=' ')
|
||||
print(f, end=" ")
|
||||
|
||||
@@ -46,8 +46,8 @@ import importer
|
||||
from code_formatter import code_formatter
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('modpath', help='module the simobject belongs to')
|
||||
parser.add_argument('cxx_config_cc', help='cxx config cc file to generate')
|
||||
parser.add_argument("modpath", help="module the simobject belongs to")
|
||||
parser.add_argument("cxx_config_cc", help="cxx config cc file to generate")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -63,22 +63,25 @@ import m5.params
|
||||
|
||||
code = code_formatter()
|
||||
|
||||
entry_class = 'CxxConfigDirectoryEntry_%s' % sim_object_name
|
||||
param_class = '%sCxxConfigParams' % sim_object_name
|
||||
entry_class = "CxxConfigDirectoryEntry_%s" % sim_object_name
|
||||
param_class = "%sCxxConfigParams" % sim_object_name
|
||||
|
||||
|
||||
def cxx_bool(b):
|
||||
return 'true' if b else 'false'
|
||||
return "true" if b else "false"
|
||||
|
||||
|
||||
code('#include "params/%s.hh"' % sim_object_name)
|
||||
|
||||
for param in sim_object._params.values():
|
||||
if isSimObjectClass(param.ptype):
|
||||
code('#include "%s"' % param.ptype._value_dict['cxx_header'])
|
||||
code('#include "%s"' % param.ptype._value_dict["cxx_header"])
|
||||
code('#include "params/%s.hh"' % param.ptype.__name__)
|
||||
else:
|
||||
param.ptype.cxx_ini_predecls(code)
|
||||
|
||||
code('''#include "${{sim_object._value_dict['cxx_header']}}"
|
||||
code(
|
||||
"""#include "${{sim_object._value_dict['cxx_header']}}"
|
||||
#include "base/str.hh"
|
||||
#include "cxx_config/${sim_object_name}.hh"
|
||||
|
||||
@@ -87,34 +90,39 @@ namespace gem5
|
||||
|
||||
${param_class}::DirectoryEntry::DirectoryEntry()
|
||||
{
|
||||
''')
|
||||
"""
|
||||
)
|
||||
code.indent()
|
||||
for param in sim_object._params.values():
|
||||
is_vector = isinstance(param, m5.params.VectorParamDesc)
|
||||
is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
|
||||
|
||||
code('parameters["%s"] = new ParamDesc("%s", %s, %s);' %
|
||||
(param.name, param.name, cxx_bool(is_vector),
|
||||
cxx_bool(is_simobj)));
|
||||
code(
|
||||
'parameters["%s"] = new ParamDesc("%s", %s, %s);'
|
||||
% (param.name, param.name, cxx_bool(is_vector), cxx_bool(is_simobj))
|
||||
)
|
||||
|
||||
for port in sim_object._ports.values():
|
||||
is_vector = isinstance(port, m5.params.VectorPort)
|
||||
is_requestor = port.role == 'GEM5 REQUESTOR'
|
||||
is_requestor = port.role == "GEM5 REQUESTOR"
|
||||
|
||||
code('ports["%s"] = new PortDesc("%s", %s, %s);' %
|
||||
(port.name, port.name, cxx_bool(is_vector),
|
||||
cxx_bool(is_requestor)))
|
||||
code(
|
||||
'ports["%s"] = new PortDesc("%s", %s, %s);'
|
||||
% (port.name, port.name, cxx_bool(is_vector), cxx_bool(is_requestor))
|
||||
)
|
||||
|
||||
code.dedent()
|
||||
|
||||
code('''}
|
||||
code(
|
||||
"""}
|
||||
|
||||
bool
|
||||
${param_class}::setSimObject(const std::string &name, SimObject *simObject)
|
||||
{
|
||||
bool ret = true;
|
||||
if (false) {
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.indent()
|
||||
for param in sim_object._params.values():
|
||||
@@ -124,14 +132,17 @@ for param in sim_object._params.values():
|
||||
if is_simobj and not is_vector:
|
||||
code('} else if (name == "${{param.name}}") {')
|
||||
code.indent()
|
||||
code('this->${{param.name}} = '
|
||||
'dynamic_cast<${{param.ptype.cxx_type}}>(simObject);')
|
||||
code('if (simObject && !this->${{param.name}})')
|
||||
code(' ret = false;')
|
||||
code(
|
||||
"this->${{param.name}} = "
|
||||
"dynamic_cast<${{param.ptype.cxx_type}}>(simObject);"
|
||||
)
|
||||
code("if (simObject && !this->${{param.name}})")
|
||||
code(" ret = false;")
|
||||
code.dedent()
|
||||
code.dedent()
|
||||
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
@@ -146,7 +157,8 @@ ${param_class}::setSimObjectVector(const std::string &name,
|
||||
bool ret = true;
|
||||
|
||||
if (false) {
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.indent()
|
||||
for param in sim_object._params.values():
|
||||
@@ -156,23 +168,28 @@ for param in sim_object._params.values():
|
||||
if is_simobj and is_vector:
|
||||
code('} else if (name == "${{param.name}}") {')
|
||||
code.indent()
|
||||
code('this->${{param.name}}.clear();')
|
||||
code('for (auto i = simObjects.begin(); '
|
||||
'ret && i != simObjects.end(); i ++)')
|
||||
code('{')
|
||||
code("this->${{param.name}}.clear();")
|
||||
code(
|
||||
"for (auto i = simObjects.begin(); "
|
||||
"ret && i != simObjects.end(); i ++)"
|
||||
)
|
||||
code("{")
|
||||
code.indent()
|
||||
code('${{param.ptype.cxx_type}} object = '
|
||||
'dynamic_cast<${{param.ptype.cxx_type}}>(*i);')
|
||||
code('if (*i && !object)')
|
||||
code(' ret = false;')
|
||||
code('else')
|
||||
code(' this->${{param.name}}.push_back(object);')
|
||||
code(
|
||||
"${{param.ptype.cxx_type}} object = "
|
||||
"dynamic_cast<${{param.ptype.cxx_type}}>(*i);"
|
||||
)
|
||||
code("if (*i && !object)")
|
||||
code(" ret = false;")
|
||||
code("else")
|
||||
code(" this->${{param.name}}.push_back(object);")
|
||||
code.dedent()
|
||||
code('}')
|
||||
code("}")
|
||||
code.dedent()
|
||||
code.dedent()
|
||||
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
@@ -193,7 +210,8 @@ ${param_class}::setParam(const std::string &name,
|
||||
bool ret = true;
|
||||
|
||||
if (false) {
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.indent()
|
||||
for param in sim_object._params.values():
|
||||
@@ -203,12 +221,14 @@ for param in sim_object._params.values():
|
||||
if not is_simobj and not is_vector:
|
||||
code('} else if (name == "${{param.name}}") {')
|
||||
code.indent()
|
||||
param.ptype.cxx_ini_parse(code,
|
||||
'value', 'this->%s' % param.name, 'ret =')
|
||||
param.ptype.cxx_ini_parse(
|
||||
code, "value", "this->%s" % param.name, "ret ="
|
||||
)
|
||||
code.dedent()
|
||||
code.dedent()
|
||||
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
@@ -223,7 +243,8 @@ ${param_class}::setParamVector(const std::string &name,
|
||||
bool ret = true;
|
||||
|
||||
if (false) {
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.indent()
|
||||
for param in sim_object._params.values():
|
||||
@@ -233,22 +254,23 @@ for param in sim_object._params.values():
|
||||
if not is_simobj and is_vector:
|
||||
code('} else if (name == "${{param.name}}") {')
|
||||
code.indent()
|
||||
code('${{param.name}}.clear();')
|
||||
code('for (auto i = values.begin(); '
|
||||
'ret && i != values.end(); i ++)')
|
||||
code('{')
|
||||
code("${{param.name}}.clear();")
|
||||
code(
|
||||
"for (auto i = values.begin(); " "ret && i != values.end(); i ++)"
|
||||
)
|
||||
code("{")
|
||||
code.indent()
|
||||
code('${{param.ptype.cxx_type}} elem;')
|
||||
param.ptype.cxx_ini_parse(code,
|
||||
'*i', 'elem', 'ret =')
|
||||
code('if (ret)')
|
||||
code(' this->${{param.name}}.push_back(elem);')
|
||||
code("${{param.ptype.cxx_type}} elem;")
|
||||
param.ptype.cxx_ini_parse(code, "*i", "elem", "ret =")
|
||||
code("if (ret)")
|
||||
code(" this->${{param.name}}.push_back(elem);")
|
||||
code.dedent()
|
||||
code('}')
|
||||
code("}")
|
||||
code.dedent()
|
||||
code.dedent()
|
||||
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
@@ -263,15 +285,17 @@ ${param_class}::setPortConnectionCount(const std::string &name,
|
||||
bool ret = true;
|
||||
|
||||
if (false) {
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.indent()
|
||||
for port in sim_object._ports.values():
|
||||
code('} else if (name == "${{port.name}}") {')
|
||||
code(' this->port_${{port.name}}_connection_count = count;')
|
||||
code(" this->port_${{port.name}}_connection_count = count;")
|
||||
code.dedent()
|
||||
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
@@ -282,18 +306,21 @@ code('''
|
||||
SimObject *
|
||||
${param_class}::simObjectCreate()
|
||||
{
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.indent()
|
||||
if hasattr(sim_object, 'abstract') and sim_object.abstract:
|
||||
code('return nullptr;')
|
||||
if hasattr(sim_object, "abstract") and sim_object.abstract:
|
||||
code("return nullptr;")
|
||||
else:
|
||||
code('return this->create();')
|
||||
code("return this->create();")
|
||||
code.dedent()
|
||||
|
||||
code('''}
|
||||
code(
|
||||
"""}
|
||||
|
||||
} // namespace gem5
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.write(args.cxx_config_cc)
|
||||
|
||||
@@ -46,8 +46,8 @@ import importer
|
||||
from code_formatter import code_formatter
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('modpath', help='module the simobject belongs to')
|
||||
parser.add_argument('cxx_config_hh', help='cxx config header file to generate')
|
||||
parser.add_argument("modpath", help="module the simobject belongs to")
|
||||
parser.add_argument("cxx_config_hh", help="cxx config header file to generate")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -60,10 +60,11 @@ sim_object = getattr(module, sim_object_name)
|
||||
|
||||
code = code_formatter()
|
||||
|
||||
entry_class = 'CxxConfigDirectoryEntry_%s' % sim_object_name
|
||||
param_class = '%sCxxConfigParams' % sim_object_name
|
||||
entry_class = "CxxConfigDirectoryEntry_%s" % sim_object_name
|
||||
param_class = "%sCxxConfigParams" % sim_object_name
|
||||
|
||||
code('''#include "params/${sim_object_name}.hh"
|
||||
code(
|
||||
"""#include "params/${sim_object_name}.hh"
|
||||
|
||||
#include "sim/cxx_config.hh"
|
||||
|
||||
@@ -110,6 +111,7 @@ class ${param_class} : public CxxConfigParams, public ${sim_object_name}Params
|
||||
};
|
||||
|
||||
} // namespace gem5
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.write(args.cxx_config_hh)
|
||||
|
||||
@@ -44,35 +44,41 @@ parser = argparse.ArgumentParser()
|
||||
parser.add_argument("hh", help="the path of the debug flag header file")
|
||||
parser.add_argument("name", help="the name of the debug flag")
|
||||
parser.add_argument("desc", help="a description of the debug flag")
|
||||
parser.add_argument("fmt",
|
||||
help="whether the flag is a format flag (True or False)")
|
||||
parser.add_argument("components",
|
||||
help="components of a compound flag, if applicable, joined with :")
|
||||
parser.add_argument(
|
||||
"fmt", help="whether the flag is a format flag (True or False)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"components",
|
||||
help="components of a compound flag, if applicable, joined with :",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
fmt = args.fmt.lower()
|
||||
if fmt == 'true':
|
||||
if fmt == "true":
|
||||
fmt = True
|
||||
elif fmt == 'false':
|
||||
elif fmt == "false":
|
||||
fmt = False
|
||||
else:
|
||||
print(f'Unrecognized "FMT" value {fmt}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
components = args.components.split(':') if args.components else []
|
||||
components = args.components.split(":") if args.components else []
|
||||
|
||||
code = code_formatter()
|
||||
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
#ifndef __DEBUG_${{args.name}}_HH__
|
||||
#define __DEBUG_${{args.name}}_HH__
|
||||
|
||||
#include "base/compiler.hh" // For namespace deprecation
|
||||
#include "base/debug.hh"
|
||||
''')
|
||||
"""
|
||||
)
|
||||
for flag in components:
|
||||
code('#include "debug/${flag}.hh"')
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
@@ -82,14 +88,16 @@ namespace debug
|
||||
|
||||
namespace unions
|
||||
{
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
# Use unions to prevent debug flags from being destructed. It's the
|
||||
# responsibility of the programmer to handle object destruction for members
|
||||
# of the union. We purposefully leave that destructor empty so that we can
|
||||
# use debug flags even in the destructors of other objects.
|
||||
if components:
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
inline union ${{args.name}}
|
||||
{
|
||||
~${{args.name}}() {}
|
||||
@@ -100,9 +108,11 @@ inline union ${{args.name}}
|
||||
}
|
||||
};
|
||||
} ${{args.name}};
|
||||
''')
|
||||
"""
|
||||
)
|
||||
else:
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
inline union ${{args.name}}
|
||||
{
|
||||
~${{args.name}}() {}
|
||||
@@ -110,18 +120,21 @@ inline union ${{args.name}}
|
||||
"${{args.name}}", "${{args.desc}}", ${{"true" if fmt else "false"}}
|
||||
};
|
||||
} ${{args.name}};
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
} // namespace unions
|
||||
|
||||
inline constexpr const auto& ${{args.name}} =
|
||||
inline constexpr const auto& ${{args.name}} =
|
||||
::gem5::debug::unions::${{args.name}}.${{args.name}};
|
||||
|
||||
} // namespace debug
|
||||
} // namespace gem5
|
||||
|
||||
#endif // __DEBUG_${{args.name}}_HH__
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.write(args.hh)
|
||||
|
||||
@@ -46,17 +46,18 @@ import importer
|
||||
from code_formatter import code_formatter
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('modpath', help='module the enum belongs to')
|
||||
parser.add_argument('enum_cc', help='enum cc file to generate')
|
||||
parser.add_argument('use_python',
|
||||
help='whether python is enabled in gem5 (True or False)')
|
||||
parser.add_argument("modpath", help="module the enum belongs to")
|
||||
parser.add_argument("enum_cc", help="enum cc file to generate")
|
||||
parser.add_argument(
|
||||
"use_python", help="whether python is enabled in gem5 (True or False)"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
use_python = args.use_python.lower()
|
||||
if use_python == 'true':
|
||||
if use_python == "true":
|
||||
use_python = True
|
||||
elif use_python == 'false':
|
||||
elif use_python == "false":
|
||||
use_python = False
|
||||
else:
|
||||
print(f'Unrecognized "use_python" value {use_python}', file=sys.stderr)
|
||||
@@ -75,41 +76,46 @@ wrapper_name = enum.wrapper_name
|
||||
file_name = enum.__name__
|
||||
name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
||||
|
||||
code('''#include "base/compiler.hh"
|
||||
code(
|
||||
"""#include "base/compiler.hh"
|
||||
#include "enums/$file_name.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
if enum.wrapper_is_struct:
|
||||
code('const char *${wrapper_name}::${name}Strings'
|
||||
'[Num_${name}] =')
|
||||
code("const char *${wrapper_name}::${name}Strings" "[Num_${name}] =")
|
||||
else:
|
||||
if enum.is_class:
|
||||
code('''\
|
||||
code(
|
||||
"""\
|
||||
const char *${name}Strings[static_cast<int>(${name}::Num_${name})] =
|
||||
''')
|
||||
"""
|
||||
)
|
||||
else:
|
||||
code('''GEM5_DEPRECATED_NAMESPACE(Enums, enums);
|
||||
code(
|
||||
"""GEM5_DEPRECATED_NAMESPACE(Enums, enums);
|
||||
namespace enums
|
||||
{''')
|
||||
{"""
|
||||
)
|
||||
code.indent(1)
|
||||
code('const char *${name}Strings[Num_${name}] =')
|
||||
code("const char *${name}Strings[Num_${name}] =")
|
||||
|
||||
code('{')
|
||||
code("{")
|
||||
code.indent(1)
|
||||
for val in enum.vals:
|
||||
code('"$val",')
|
||||
code.dedent(1)
|
||||
code('};')
|
||||
code("};")
|
||||
|
||||
if not enum.wrapper_is_struct and not enum.is_class:
|
||||
code.dedent(1)
|
||||
code('} // namespace enums')
|
||||
code("} // namespace enums")
|
||||
|
||||
code('} // namespace gem5')
|
||||
code("} // namespace gem5")
|
||||
|
||||
|
||||
if use_python:
|
||||
@@ -118,7 +124,8 @@ if use_python:
|
||||
enum_name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
||||
wrapper_name = enum_name if enum.is_class else enum.wrapper_name
|
||||
|
||||
code('''#include "pybind11/pybind11.h"
|
||||
code(
|
||||
"""#include "pybind11/pybind11.h"
|
||||
#include "pybind11/stl.h"
|
||||
|
||||
#include <sim/init.hh>
|
||||
@@ -133,7 +140,8 @@ module_init(py::module_ &m_internal)
|
||||
{
|
||||
py::module_ m = m_internal.def_submodule("enum_${name}");
|
||||
|
||||
''')
|
||||
"""
|
||||
)
|
||||
if enum.is_class:
|
||||
code('py::enum_<${enum_name}>(m, "enum_${name}")')
|
||||
else:
|
||||
@@ -145,16 +153,18 @@ module_init(py::module_ &m_internal)
|
||||
code('.value("${val}", ${wrapper_name}::${val})')
|
||||
code('.value("Num_${name}", ${wrapper_name}::Num_${enum_name})')
|
||||
if not enum.is_class:
|
||||
code('.export_values()')
|
||||
code(';')
|
||||
code(".export_values()")
|
||||
code(";")
|
||||
code.dedent()
|
||||
|
||||
code('}')
|
||||
code("}")
|
||||
code.dedent()
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
static EmbeddedPyBind embed_enum("enum_${name}", module_init);
|
||||
|
||||
} // namespace gem5
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.write(args.enum_cc)
|
||||
|
||||
@@ -46,8 +46,8 @@ import importer
|
||||
from code_formatter import code_formatter
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('modpath', help='module the enum belongs to')
|
||||
parser.add_argument('enum_hh', help='enum header file to generate')
|
||||
parser.add_argument("modpath", help="module the enum belongs to")
|
||||
parser.add_argument("enum_hh", help="enum header file to generate")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -64,53 +64,61 @@ code = code_formatter()
|
||||
# Note that we wrap the enum in a class/struct to act as a namespace,
|
||||
# so that the enum strings can be brief w/o worrying about collisions.
|
||||
wrapper_name = enum.wrapper_name
|
||||
wrapper = 'struct' if enum.wrapper_is_struct else 'namespace'
|
||||
wrapper = "struct" if enum.wrapper_is_struct else "namespace"
|
||||
name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
||||
idem_macro = '__ENUM__%s__%s__' % (wrapper_name, name)
|
||||
idem_macro = "__ENUM__%s__%s__" % (wrapper_name, name)
|
||||
|
||||
code('''\
|
||||
code(
|
||||
"""\
|
||||
#ifndef $idem_macro
|
||||
#define $idem_macro
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
''')
|
||||
"""
|
||||
)
|
||||
if enum.is_class:
|
||||
code('''\
|
||||
code(
|
||||
"""\
|
||||
enum class $name
|
||||
{
|
||||
''')
|
||||
"""
|
||||
)
|
||||
else:
|
||||
code('''\
|
||||
code(
|
||||
"""\
|
||||
$wrapper $wrapper_name {
|
||||
enum $name
|
||||
{
|
||||
''')
|
||||
"""
|
||||
)
|
||||
code.indent(1)
|
||||
code.indent(1)
|
||||
for val in enum.vals:
|
||||
code('$val = ${{enum.map[val]}},')
|
||||
code('Num_$name = ${{len(enum.vals)}}')
|
||||
code("$val = ${{enum.map[val]}},")
|
||||
code("Num_$name = ${{len(enum.vals)}}")
|
||||
code.dedent(1)
|
||||
code('};')
|
||||
code("};")
|
||||
|
||||
if enum.is_class:
|
||||
code('''\
|
||||
code(
|
||||
"""\
|
||||
extern const char *${name}Strings[static_cast<int>(${name}::Num_${name})];
|
||||
''')
|
||||
"""
|
||||
)
|
||||
elif enum.wrapper_is_struct:
|
||||
code('static const char *${name}Strings[Num_${name}];')
|
||||
code("static const char *${name}Strings[Num_${name}];")
|
||||
else:
|
||||
code('extern const char *${name}Strings[Num_${name}];')
|
||||
code("extern const char *${name}Strings[Num_${name}];")
|
||||
|
||||
if not enum.is_class:
|
||||
code.dedent(1)
|
||||
code('}; // $wrapper_name')
|
||||
code("}; // $wrapper_name")
|
||||
|
||||
code()
|
||||
code('} // namespace gem5')
|
||||
code("} // namespace gem5")
|
||||
|
||||
code()
|
||||
code('#endif // $idem_macro')
|
||||
code("#endif // $idem_macro")
|
||||
|
||||
code.write(args.enum_hh)
|
||||
|
||||
@@ -29,73 +29,77 @@ import os
|
||||
import ply.lex
|
||||
import ply.yacc
|
||||
|
||||
|
||||
class ParseError(Exception):
|
||||
def __init__(self, message, token=None):
|
||||
Exception.__init__(self, message)
|
||||
self.token = token
|
||||
|
||||
|
||||
class Grammar(object):
|
||||
def setupLexerFactory(self, **kwargs):
|
||||
if 'module' in kwargs:
|
||||
if "module" in kwargs:
|
||||
raise AttributeError("module is an illegal attribute")
|
||||
self.lex_kwargs = kwargs
|
||||
|
||||
def setupParserFactory(self, **kwargs):
|
||||
if 'module' in kwargs:
|
||||
if "module" in kwargs:
|
||||
raise AttributeError("module is an illegal attribute")
|
||||
|
||||
if 'output' in kwargs:
|
||||
dir,tab = os.path.split(output)
|
||||
if not tab.endswith('.py'):
|
||||
raise AttributeError('The output file must end with .py')
|
||||
kwargs['outputdir'] = dir
|
||||
kwargs['tabmodule'] = tab[:-3]
|
||||
if "output" in kwargs:
|
||||
dir, tab = os.path.split(output)
|
||||
if not tab.endswith(".py"):
|
||||
raise AttributeError("The output file must end with .py")
|
||||
kwargs["outputdir"] = dir
|
||||
kwargs["tabmodule"] = tab[:-3]
|
||||
|
||||
self.yacc_kwargs = kwargs
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr == 'lexers':
|
||||
if attr == "lexers":
|
||||
self.lexers = []
|
||||
return self.lexers
|
||||
|
||||
if attr == 'lex_kwargs':
|
||||
if attr == "lex_kwargs":
|
||||
self.setupLexerFactory()
|
||||
return self.lex_kwargs
|
||||
|
||||
if attr == 'yacc_kwargs':
|
||||
if attr == "yacc_kwargs":
|
||||
self.setupParserFactory()
|
||||
return self.yacc_kwargs
|
||||
|
||||
if attr == 'lex':
|
||||
if attr == "lex":
|
||||
self.lex = ply.lex.lex(module=self, **self.lex_kwargs)
|
||||
return self.lex
|
||||
|
||||
if attr == 'yacc':
|
||||
if attr == "yacc":
|
||||
self.yacc = ply.yacc.yacc(module=self, **self.yacc_kwargs)
|
||||
return self.yacc
|
||||
|
||||
if attr == 'current_lexer':
|
||||
if attr == "current_lexer":
|
||||
if not self.lexers:
|
||||
return None
|
||||
return self.lexers[-1][0]
|
||||
|
||||
if attr == 'current_source':
|
||||
if attr == "current_source":
|
||||
if not self.lexers:
|
||||
return '<none>'
|
||||
return "<none>"
|
||||
return self.lexers[-1][1]
|
||||
|
||||
if attr == 'current_line':
|
||||
if attr == "current_line":
|
||||
if not self.lexers:
|
||||
return -1
|
||||
return self.current_lexer.lineno
|
||||
|
||||
raise AttributeError(
|
||||
"'%s' object has no attribute '%s'" % (type(self), attr))
|
||||
"'%s' object has no attribute '%s'" % (type(self), attr)
|
||||
)
|
||||
|
||||
def parse_string(self, data, source='<string>', debug=None, tracking=0):
|
||||
def parse_string(self, data, source="<string>", debug=None, tracking=0):
|
||||
if not isinstance(data, str):
|
||||
raise AttributeError(
|
||||
"argument must be a string, was '%s'" % type(f))
|
||||
"argument must be a string, was '%s'" % type(f)
|
||||
)
|
||||
|
||||
lexer = self.lex.clone()
|
||||
lexer.input(data)
|
||||
@@ -114,24 +118,32 @@ class Grammar(object):
|
||||
def parse_file(self, f, **kwargs):
|
||||
if isinstance(f, str):
|
||||
source = f
|
||||
f = open(f, 'r')
|
||||
f = open(f, "r")
|
||||
elif isinstance(f, file):
|
||||
source = f.name
|
||||
else:
|
||||
raise AttributeError(
|
||||
"argument must be either a string or file, was '%s'" % type(f))
|
||||
"argument must be either a string or file, was '%s'" % type(f)
|
||||
)
|
||||
|
||||
return self.parse_string(f.read(), source, **kwargs)
|
||||
|
||||
def p_error(self, t):
|
||||
if t:
|
||||
msg = "Syntax error at %s:%d:%d\n>>%s<<" % \
|
||||
(self.current_source, t.lineno, t.lexpos + 1, t.value)
|
||||
msg = "Syntax error at %s:%d:%d\n>>%s<<" % (
|
||||
self.current_source,
|
||||
t.lineno,
|
||||
t.lexpos + 1,
|
||||
t.value,
|
||||
)
|
||||
else:
|
||||
msg = "Syntax error at end of %s" % (self.current_source, )
|
||||
msg = "Syntax error at end of %s" % (self.current_source,)
|
||||
raise ParseError(msg, t)
|
||||
|
||||
def t_error(self, t):
|
||||
msg = "Illegal character %s @ %d:%d" % \
|
||||
(repr(t.value[0]), t.lineno, t.lexpos)
|
||||
msg = "Illegal character %s @ %d:%d" % (
|
||||
repr(t.value[0]),
|
||||
t.lineno,
|
||||
t.lexpos,
|
||||
)
|
||||
raise ParseError(msg, t)
|
||||
|
||||
@@ -42,8 +42,8 @@ import sys
|
||||
from code_formatter import code_formatter
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('info_py', help='info.py file path')
|
||||
parser.add_argument('files', help='file to include in info.py', nargs='*')
|
||||
parser.add_argument("info_py", help="info.py file path")
|
||||
parser.add_argument("files", help="file to include in info.py", nargs="*")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -52,8 +52,8 @@ code = code_formatter()
|
||||
|
||||
for source in args.files:
|
||||
src = os.path.basename(source)
|
||||
with open(source, 'r') as f:
|
||||
data = ''.join(f)
|
||||
code('${src} = ${{repr(data)}}')
|
||||
with open(source, "r") as f:
|
||||
data = "".join(f)
|
||||
code("${src} = ${{repr(data)}}")
|
||||
|
||||
code.write(args.info_py)
|
||||
|
||||
@@ -67,16 +67,17 @@ if len(sys.argv) < 4:
|
||||
|
||||
_, cpp, python, modpath, abspath = sys.argv
|
||||
|
||||
with open(python, 'r') as f:
|
||||
with open(python, "r") as f:
|
||||
src = f.read()
|
||||
|
||||
compiled = compile(src, python, 'exec')
|
||||
compiled = compile(src, python, "exec")
|
||||
marshalled = marshal.dumps(compiled)
|
||||
|
||||
compressed = zlib.compress(marshalled)
|
||||
|
||||
code = code_formatter()
|
||||
code('''\
|
||||
code(
|
||||
"""\
|
||||
#include "python/embedded.hh"
|
||||
|
||||
namespace gem5
|
||||
@@ -84,14 +85,16 @@ namespace gem5
|
||||
namespace
|
||||
{
|
||||
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
bytesToCppArray(code, 'embedded_module_data', compressed)
|
||||
bytesToCppArray(code, "embedded_module_data", compressed)
|
||||
|
||||
# The name of the EmbeddedPython object doesn't matter since it's in an
|
||||
# anonymous namespace, and it's constructor takes care of installing it into a
|
||||
# global list.
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
EmbeddedPython embedded_module_info(
|
||||
"${abspath}",
|
||||
"${modpath}",
|
||||
@@ -101,6 +104,7 @@ EmbeddedPython embedded_module_info(
|
||||
|
||||
} // anonymous namespace
|
||||
} // namespace gem5
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.write(cpp)
|
||||
|
||||
@@ -46,17 +46,18 @@ import importer
|
||||
from code_formatter import code_formatter
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('modpath', help='module the simobject belongs to')
|
||||
parser.add_argument('param_cc', help='parameter cc file to generate')
|
||||
parser.add_argument('use_python',
|
||||
help='whether python is enabled in gem5 (True or False)')
|
||||
parser.add_argument("modpath", help="module the simobject belongs to")
|
||||
parser.add_argument("param_cc", help="parameter cc file to generate")
|
||||
parser.add_argument(
|
||||
"use_python", help="whether python is enabled in gem5 (True or False)"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
use_python = args.use_python.lower()
|
||||
if use_python == 'true':
|
||||
if use_python == "true":
|
||||
use_python = True
|
||||
elif use_python == 'false':
|
||||
elif use_python == "false":
|
||||
use_python = False
|
||||
else:
|
||||
print(f'Unrecognized "use_python" value {use_python}', file=sys.stderr)
|
||||
@@ -64,7 +65,7 @@ else:
|
||||
|
||||
basename = os.path.basename(args.param_cc)
|
||||
no_ext = os.path.splitext(basename)[0]
|
||||
sim_object_name = '_'.join(no_ext.split('_')[1:])
|
||||
sim_object_name = "_".join(no_ext.split("_")[1:])
|
||||
|
||||
importer.install()
|
||||
module = importlib.import_module(args.modpath)
|
||||
@@ -80,14 +81,16 @@ py_class_name = sim_object.pybind_class
|
||||
# the object itself, not including inherited params (which
|
||||
# will also be inherited from the base class's param struct
|
||||
# here). Sort the params based on their key
|
||||
params = list(map(lambda k_v: k_v[1],
|
||||
sorted(sim_object._params.local.items())))
|
||||
params = list(
|
||||
map(lambda k_v: k_v[1], sorted(sim_object._params.local.items()))
|
||||
)
|
||||
ports = sim_object._ports.local
|
||||
|
||||
# only include pybind if python is enabled in the build
|
||||
if use_python:
|
||||
|
||||
code('''#include "pybind11/pybind11.h"
|
||||
code(
|
||||
"""#include "pybind11/pybind11.h"
|
||||
#include "pybind11/stl.h"
|
||||
|
||||
#include <type_traits>
|
||||
@@ -99,9 +102,11 @@ if use_python:
|
||||
|
||||
#include "${{sim_object.cxx_header}}"
|
||||
|
||||
''')
|
||||
"""
|
||||
)
|
||||
else:
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
#include <type_traits>
|
||||
|
||||
#include "base/compiler.hh"
|
||||
@@ -109,13 +114,15 @@ else:
|
||||
|
||||
#include "${{sim_object.cxx_header}}"
|
||||
|
||||
''')
|
||||
"""
|
||||
)
|
||||
# only include the python params code if python is enabled.
|
||||
if use_python:
|
||||
for param in params:
|
||||
param.pybind_predecls(code)
|
||||
|
||||
code('''namespace py = pybind11;
|
||||
code(
|
||||
"""namespace py = pybind11;
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
@@ -124,39 +131,48 @@ static void
|
||||
module_init(py::module_ &m_internal)
|
||||
{
|
||||
py::module_ m = m_internal.def_submodule("param_${sim_object}");
|
||||
''')
|
||||
"""
|
||||
)
|
||||
code.indent()
|
||||
if sim_object._base:
|
||||
code('py::class_<${sim_object}Params, ' \
|
||||
'${{sim_object._base.type}}Params, ' \
|
||||
'std::unique_ptr<${{sim_object}}Params, py::nodelete>>(' \
|
||||
'm, "${sim_object}Params")')
|
||||
code(
|
||||
"py::class_<${sim_object}Params, "
|
||||
"${{sim_object._base.type}}Params, "
|
||||
"std::unique_ptr<${{sim_object}}Params, py::nodelete>>("
|
||||
'm, "${sim_object}Params")'
|
||||
)
|
||||
else:
|
||||
code('py::class_<${sim_object}Params, ' \
|
||||
'std::unique_ptr<${sim_object}Params, py::nodelete>>(' \
|
||||
'm, "${sim_object}Params")')
|
||||
code(
|
||||
"py::class_<${sim_object}Params, "
|
||||
"std::unique_ptr<${sim_object}Params, py::nodelete>>("
|
||||
'm, "${sim_object}Params")'
|
||||
)
|
||||
|
||||
code.indent()
|
||||
if not hasattr(sim_object, 'abstract') or not sim_object.abstract:
|
||||
code('.def(py::init<>())')
|
||||
if not hasattr(sim_object, "abstract") or not sim_object.abstract:
|
||||
code(".def(py::init<>())")
|
||||
code('.def("create", &${sim_object}Params::create)')
|
||||
|
||||
param_exports = sim_object.cxx_param_exports + [
|
||||
PyBindProperty(k)
|
||||
for k, v in sorted(sim_object._params.local.items())
|
||||
] + [
|
||||
PyBindProperty(f"port_{port.name}_connection_count")
|
||||
for port in ports.values()
|
||||
]
|
||||
param_exports = (
|
||||
sim_object.cxx_param_exports
|
||||
+ [
|
||||
PyBindProperty(k)
|
||||
for k, v in sorted(sim_object._params.local.items())
|
||||
]
|
||||
+ [
|
||||
PyBindProperty(f"port_{port.name}_connection_count")
|
||||
for port in ports.values()
|
||||
]
|
||||
)
|
||||
for exp in param_exports:
|
||||
exp.export(code, f"{sim_object}Params")
|
||||
|
||||
code(';')
|
||||
code(";")
|
||||
code()
|
||||
code.dedent()
|
||||
|
||||
bases = []
|
||||
if 'cxx_base' in sim_object._value_dict:
|
||||
if "cxx_base" in sim_object._value_dict:
|
||||
# If the c++ base class implied by python inheritance was
|
||||
# overridden, use that value.
|
||||
if sim_object.cxx_base:
|
||||
@@ -170,32 +186,39 @@ py::module_ m = m_internal.def_submodule("param_${sim_object}");
|
||||
|
||||
if bases:
|
||||
base_str = ", ".join(bases)
|
||||
code('py::class_<${{sim_object.cxx_class}}, ${base_str}, ' \
|
||||
'std::unique_ptr<${{sim_object.cxx_class}}, py::nodelete>>(' \
|
||||
'm, "${py_class_name}")')
|
||||
code(
|
||||
"py::class_<${{sim_object.cxx_class}}, ${base_str}, "
|
||||
"std::unique_ptr<${{sim_object.cxx_class}}, py::nodelete>>("
|
||||
'm, "${py_class_name}")'
|
||||
)
|
||||
else:
|
||||
code('py::class_<${{sim_object.cxx_class}}, ' \
|
||||
'std::unique_ptr<${{sim_object.cxx_class}}, py::nodelete>>(' \
|
||||
'm, "${py_class_name}")')
|
||||
code(
|
||||
"py::class_<${{sim_object.cxx_class}}, "
|
||||
"std::unique_ptr<${{sim_object.cxx_class}}, py::nodelete>>("
|
||||
'm, "${py_class_name}")'
|
||||
)
|
||||
code.indent()
|
||||
for exp in sim_object.cxx_exports:
|
||||
exp.export(code, sim_object.cxx_class)
|
||||
code(';')
|
||||
code(";")
|
||||
code.dedent()
|
||||
code()
|
||||
code.dedent()
|
||||
code('}')
|
||||
code("}")
|
||||
code()
|
||||
code('static EmbeddedPyBind '
|
||||
'embed_obj("${0}", module_init, "${1}");',
|
||||
sim_object, sim_object._base.type if sim_object._base else "")
|
||||
code(
|
||||
"static EmbeddedPyBind " 'embed_obj("${0}", module_init, "${1}");',
|
||||
sim_object,
|
||||
sim_object._base.type if sim_object._base else "",
|
||||
)
|
||||
code()
|
||||
code('} // namespace gem5')
|
||||
code("} // namespace gem5")
|
||||
|
||||
# include the create() methods whether or not python is enabled.
|
||||
if not hasattr(sim_object, 'abstract') or not sim_object.abstract:
|
||||
if 'type' in sim_object.__dict__:
|
||||
code('''
|
||||
if not hasattr(sim_object, "abstract") or not sim_object.abstract:
|
||||
if "type" in sim_object.__dict__:
|
||||
code(
|
||||
"""
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
@@ -268,6 +291,7 @@ Dummy${sim_object}Shunt<${{sim_object.cxx_class}}>::Params::create() const
|
||||
}
|
||||
|
||||
} // namespace gem5
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
code.write(args.param_cc)
|
||||
|
||||
@@ -46,8 +46,8 @@ import importer
|
||||
from code_formatter import code_formatter
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('modpath', help='module the simobject belongs to')
|
||||
parser.add_argument('param_hh', help='parameter header file to generate')
|
||||
parser.add_argument("modpath", help="module the simobject belongs to")
|
||||
parser.add_argument("param_hh", help="parameter header file to generate")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -67,8 +67,9 @@ code = code_formatter()
|
||||
# the object itself, not including inherited params (which
|
||||
# will also be inherited from the base class's param struct
|
||||
# here). Sort the params based on their key
|
||||
params = list(map(lambda k_v: k_v[1],
|
||||
sorted(sim_object._params.local.items())))
|
||||
params = list(
|
||||
map(lambda k_v: k_v[1], sorted(sim_object._params.local.items()))
|
||||
)
|
||||
ports = sim_object._ports.local
|
||||
try:
|
||||
ptypes = [p.ptype for p in params]
|
||||
@@ -79,41 +80,44 @@ except:
|
||||
|
||||
warned_about_nested_templates = False
|
||||
|
||||
|
||||
class CxxClass(object):
|
||||
def __init__(self, sig, template_params=[]):
|
||||
# Split the signature into its constituent parts. This could
|
||||
# potentially be done with regular expressions, but
|
||||
# it's simple enough to pick appart a class signature
|
||||
# manually.
|
||||
parts = sig.split('<', 1)
|
||||
parts = sig.split("<", 1)
|
||||
base = parts[0]
|
||||
t_args = []
|
||||
if len(parts) > 1:
|
||||
# The signature had template arguments.
|
||||
text = parts[1].rstrip(' \t\n>')
|
||||
arg = ''
|
||||
text = parts[1].rstrip(" \t\n>")
|
||||
arg = ""
|
||||
# Keep track of nesting to avoid splitting on ","s embedded
|
||||
# in the arguments themselves.
|
||||
depth = 0
|
||||
for c in text:
|
||||
if c == '<':
|
||||
if c == "<":
|
||||
depth = depth + 1
|
||||
if depth > 0 and not warned_about_nested_templates:
|
||||
warned_about_nested_templates = True
|
||||
print('Nested template argument in cxx_class.'
|
||||
' This feature is largely untested and '
|
||||
' may not work.')
|
||||
elif c == '>':
|
||||
print(
|
||||
"Nested template argument in cxx_class."
|
||||
" This feature is largely untested and "
|
||||
" may not work."
|
||||
)
|
||||
elif c == ">":
|
||||
depth = depth - 1
|
||||
elif c == ',' and depth == 0:
|
||||
elif c == "," and depth == 0:
|
||||
t_args.append(arg.strip())
|
||||
arg = ''
|
||||
arg = ""
|
||||
else:
|
||||
arg = arg + c
|
||||
if arg:
|
||||
t_args.append(arg.strip())
|
||||
# Split the non-template part on :: boundaries.
|
||||
class_path = base.split('::')
|
||||
class_path = base.split("::")
|
||||
|
||||
# The namespaces are everything except the last part of the class path.
|
||||
self.namespaces = class_path[:-1]
|
||||
@@ -125,7 +129,7 @@ class CxxClass(object):
|
||||
# Iterate through the template arguments and their values. This
|
||||
# will likely break if parameter packs are used.
|
||||
for arg, param in zip(t_args, template_params):
|
||||
type_keys = ('class', 'typename')
|
||||
type_keys = ("class", "typename")
|
||||
# If a parameter is a type, parse it recursively. Otherwise
|
||||
# assume it's a constant, and store it verbatim.
|
||||
if any(param.strip().startswith(kw) for kw in type_keys):
|
||||
@@ -140,21 +144,24 @@ class CxxClass(object):
|
||||
arg.declare(code)
|
||||
# Re-open the target namespace.
|
||||
for ns in self.namespaces:
|
||||
code('namespace $ns {')
|
||||
code("namespace $ns {")
|
||||
# If this is a class template...
|
||||
if self.template_params:
|
||||
code('template <${{", ".join(self.template_params)}}>')
|
||||
# The actual class declaration.
|
||||
code('class ${{self.name}};')
|
||||
code("class ${{self.name}};")
|
||||
# Close the target namespaces.
|
||||
for ns in reversed(self.namespaces):
|
||||
code('} // namespace $ns')
|
||||
code("} // namespace $ns")
|
||||
|
||||
code('''\
|
||||
|
||||
code(
|
||||
"""\
|
||||
#ifndef __PARAMS__${sim_object}__
|
||||
#define __PARAMS__${sim_object}__
|
||||
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
# The base SimObject has a couple of params that get
|
||||
@@ -162,10 +169,12 @@ code('''\
|
||||
# the normal Param mechanism; we slip them in here (needed
|
||||
# predecls now, actual declarations below)
|
||||
if sim_object == SimObject:
|
||||
code('''#include <string>''')
|
||||
code("""#include <string>""")
|
||||
|
||||
cxx_class = CxxClass(sim_object._value_dict['cxx_class'],
|
||||
sim_object._value_dict['cxx_template_params'])
|
||||
cxx_class = CxxClass(
|
||||
sim_object._value_dict["cxx_class"],
|
||||
sim_object._value_dict["cxx_template_params"],
|
||||
)
|
||||
|
||||
# A forward class declaration is sufficient since we are just
|
||||
# declaring a pointer.
|
||||
@@ -186,27 +195,29 @@ for ptype in ptypes:
|
||||
code('#include "enums/${{ptype.__name__}}.hh"')
|
||||
code()
|
||||
|
||||
code('namespace gem5')
|
||||
code('{')
|
||||
code('')
|
||||
code("namespace gem5")
|
||||
code("{")
|
||||
code("")
|
||||
|
||||
# now generate the actual param struct
|
||||
code("struct ${sim_object}Params")
|
||||
if sim_object._base:
|
||||
code(" : public ${{sim_object._base.type}}Params")
|
||||
code("{")
|
||||
if not hasattr(sim_object, 'abstract') or not sim_object.abstract:
|
||||
if 'type' in sim_object.__dict__:
|
||||
if not hasattr(sim_object, "abstract") or not sim_object.abstract:
|
||||
if "type" in sim_object.__dict__:
|
||||
code(" ${{sim_object.cxx_type}} create() const;")
|
||||
|
||||
code.indent()
|
||||
if sim_object == SimObject:
|
||||
code('''
|
||||
code(
|
||||
"""
|
||||
SimObjectParams() {}
|
||||
virtual ~SimObjectParams() {}
|
||||
|
||||
std::string name;
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
for param in params:
|
||||
param.cxx_decl(code)
|
||||
@@ -214,11 +225,11 @@ for port in ports.values():
|
||||
port.cxx_decl(code)
|
||||
|
||||
code.dedent()
|
||||
code('};')
|
||||
code("};")
|
||||
code()
|
||||
code('} // namespace gem5')
|
||||
code("} // namespace gem5")
|
||||
|
||||
code()
|
||||
code('#endif // __PARAMS__${sim_object}__')
|
||||
code("#endif // __PARAMS__${sim_object}__")
|
||||
|
||||
code.write(args.param_hh)
|
||||
|
||||
Reference in New Issue
Block a user