Skip to content

Commit 6189084

Browse files
committed
Refactor load/save implementations for mod/pyc files
1 parent d09d004 commit 6189084

File tree

1 file changed

+36
-59
lines changed

1 file changed

+36
-59
lines changed

src/libasr/modfile.cpp

Lines changed: 36 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,8 @@ namespace LFortran {
1212

1313
const std::string lfortran_modfile_type_string = "LFortran Modfile";
1414

15-
// The save_modfile() and load_modfile() must stay consistent. What is saved
16-
// must be loaded in exactly the same order.
17-
18-
/*
19-
Saves the module into a binary stream.
20-
21-
That stream can be saved to a mod file by the caller.
22-
The sections in the file/stream are saved using write_string(), so they
23-
can be efficiently read by the loader and ignored if needed.
24-
25-
Comments below show some possible future improvements to the mod format.
26-
*/
27-
std::string save_modfile(const ASR::TranslationUnit_t &m) {
28-
LFORTRAN_ASSERT(m.m_global_scope->get_scope().size()== 1);
29-
for (auto &a : m.m_global_scope->get_scope()) {
30-
LFORTRAN_ASSERT(ASR::is_a<ASR::Module_t>(*a.second));
31-
if ((bool&)a) { } // Suppress unused warning in Release mode
32-
}
33-
#ifdef WITH_LFORTRAN_BINARY_MODFILES
15+
inline void save_asr(const ASR::TranslationUnit_t &m, std::string& asr_string) {
16+
#ifdef WITH_LFORTRAN_BINARY_MODFILES
3417
BinaryWriter b;
3518
#else
3619
TextWriter b;
@@ -54,39 +37,40 @@ std::string save_modfile(const ASR::TranslationUnit_t &m) {
5437
// Full ASR:
5538
b.write_string(serialize(m));
5639

57-
return b.get_str();
40+
asr_string = b.get_str();
5841
}
5942

60-
std::string save_pycfile(const ASR::TranslationUnit_t &m) {
61-
#ifdef WITH_LFORTRAN_BINARY_MODFILES
62-
BinaryWriter b;
63-
#else
64-
TextWriter b;
65-
#endif
66-
// Header
67-
b.write_string(lfortran_modfile_type_string);
68-
b.write_string(LFORTRAN_VERSION);
43+
// The save_modfile() and load_modfile() must stay consistent. What is saved
44+
// must be loaded in exactly the same order.
6945

70-
// AST section: Original module source code:
71-
// Currently empty.
72-
// Note: in the future we can save here:
73-
// * A path to the original source code
74-
// * Hash of the orig source code
75-
// * AST binary export of it (this AST only changes if the hash changes)
46+
/*
47+
Saves the module into a binary stream.
7648
77-
// ASR section:
49+
That stream can be saved to a mod file by the caller.
50+
The sections in the file/stream are saved using write_string(), so they
51+
can be efficiently read by the loader and ignored if needed.
7852
79-
// Export ASR:
80-
// Currently empty.
53+
Comments below show some possible future improvements to the mod format.
54+
*/
55+
std::string save_modfile(const ASR::TranslationUnit_t &m) {
56+
LFORTRAN_ASSERT(m.m_global_scope->get_scope().size()== 1);
57+
for (auto &a : m.m_global_scope->get_scope()) {
58+
LFORTRAN_ASSERT(ASR::is_a<ASR::Module_t>(*a.second));
59+
if ((bool&)a) { } // Suppress unused warning in Release mode
60+
}
8161

82-
// Full ASR:
83-
b.write_string(serialize(m));
62+
std::string asr_string;
63+
save_asr(m, asr_string);
64+
return asr_string;
65+
}
8466

85-
return b.get_str();
67+
std::string save_pycfile(const ASR::TranslationUnit_t &m) {
68+
std::string asr_string;
69+
save_asr(m, asr_string);
70+
return asr_string;
8671
}
8772

88-
ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s,
89-
bool load_symtab_id, SymbolTable &symtab) {
73+
inline void load_serialised_asr(const std::string &s, std::string& asr_binary) {
9074
#ifdef WITH_LFORTRAN_BINARY_MODFILES
9175
BinaryReader b(s);
9276
#else
@@ -100,7 +84,13 @@ ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s,
10084
if (version != LFORTRAN_VERSION) {
10185
throw LCompilersException("Incompatible format: LFortran Modfile was generated using version '" + version + "', but current LFortran version is '" + LFORTRAN_VERSION + "'");
10286
}
103-
std::string asr_binary = b.read_string();
87+
asr_binary = b.read_string();
88+
}
89+
90+
ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s,
91+
bool load_symtab_id, SymbolTable &symtab) {
92+
std::string asr_binary;
93+
load_serialised_asr(s, asr_binary);
10494
ASR::asr_t *asr = deserialize_asr(al, asr_binary, load_symtab_id, symtab);
10595

10696
ASR::TranslationUnit_t *tu = ASR::down_cast2<ASR::TranslationUnit_t>(asr);
@@ -109,21 +99,8 @@ ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s,
10999

110100
ASR::TranslationUnit_t* load_pycfile(Allocator &al, const std::string &s,
111101
bool load_symtab_id) {
112-
#ifdef WITH_LFORTRAN_BINARY_MODFILES
113-
BinaryReader b(s);
114-
#else
115-
TextReader b(s);
116-
#endif
117-
118-
std::string file_type = b.read_string();
119-
if (file_type != lfortran_modfile_type_string) {
120-
throw LCompilersException("LFortran Modfile format not recognized");
121-
}
122-
std::string version = b.read_string();
123-
if (version != LFORTRAN_VERSION) {
124-
throw LCompilersException("Incompatible format: LFortran Modfile was generated using version '" + version + "', but current LFortran version is '" + LFORTRAN_VERSION + "'");
125-
}
126-
std::string asr_binary = b.read_string();
102+
std::string asr_binary;
103+
load_serialised_asr(s, asr_binary);
127104
ASR::asr_t *asr = deserialize_asr(al, asr_binary, load_symtab_id);
128105

129106
ASR::TranslationUnit_t *tu = ASR::down_cast2<ASR::TranslationUnit_t>(asr);

0 commit comments

Comments
 (0)