Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions py/dml/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2150,7 +2150,19 @@ def __init__(self, dmlfile):
DMLWarning.__init__(self, SimpleSite(dmlfile + ":0"),
dmlfile + "ast")

class WDMLAST(DMLWarning):
"""Some files in the DML standard library are preparsed into files
with the `.dmlast` suffix. If such files are encountered
elsewhere, then they are ignored to avoid potential coherency
problems, and this warning is printed.
"""
fmt = "AST file for file outside the standard library: %s"
def __init__(self, dmlfile):
DMLWarning.__init__(self, SimpleSite(dmlfile + ":0"),
dmlfile + "ast")

class WWRNSTMT(DMLWarning):

"""
The source code contained a statement "`warning;`", which
causes a warning to be printed.
Expand Down
24 changes: 21 additions & 3 deletions py/dml/toplevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,22 @@ def parse_file(dml_filename):
ast = parse(contents, file_info, dml_filename, version)
return ast

class ASTUnpickler(pickle.Unpickler):
_safe_classes = {
('dml.ast', 'AST'),
('dml.logging', 'DumpableSite'),
('dml.logging', 'FileInfo')}

def find_class(self, module, name):
if (module, name) not in self._safe_classes:
raise pickle.UnpicklingError('broken dmlast data')
return super().find_class(module, name)

def load_dmlast(ast_filename):
'''Return a previously compiled AST, or None'''
try:
return pickle.loads(bz2.BZ2File(ast_filename).read()) # nosec
with bz2.BZ2File(ast_filename) as f:
return ASTUnpickler(f).load()
except Exception as e:
raise ICE(SimpleSite(ast_filename),
"Failed to load AST from %r: %s"
Expand Down Expand Up @@ -319,6 +331,13 @@ def parse_dmlast_or_dml(dml_filename):
# error in dml-builtins.dml, one accidentally edits the
# copy in [host]/bin/dml/, instead of the one in the repo.
report(WOLDAST(dml_filename))
elif (Path(__file__).parent.parent.parent.parent
not in Path(ast_filename).parents):
# The .dmlast file mechanism is meant only to speed up the
# parsing of the standard library. Using it elsewhere would
# mean that parser updates can cause confusing errors, and the
# speed gains are small, so refuse to do that.
report(WDMLAST(dml_filename))
else:
file_info, pragmas, parsedata = load_dmlast(ast_filename)
if file_info.name is None:
Expand Down Expand Up @@ -427,8 +446,7 @@ def parse_main_file(inputfilename, explicit_import_path):

deps.setdefault(path, set()).add(importfile)

path = str(Path(path).resolve())
normalized = os.path.normcase(path)
normalized = os.path.normcase(str(Path(path).resolve()))
if normalized in imported:
# Already imported
if importfile not in imported[normalized]:
Expand Down
10 changes: 10 additions & 0 deletions test/1.4/errors/T_WDMLAST.dml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
© 2024 Intel Corporation
SPDX-License-Identifier: MPL-2.0
*/
dml 1.4;

device test;

/// COMPILE-ONLY
/// WARNING WDMLAST T_WDMLAST.dml
Empty file.
2 changes: 2 additions & 0 deletions test/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1889,6 +1889,8 @@ def test(self):
# Don't bother.
'test/1.2/misc/T_dos_newline.dml',
# empty
'test/1.4/errors/T_WDMLAST.dmlast',
# empty
'test/SUITEINFO',
# data files
'test/XFAIL',
Expand Down