A packet (compilation unit) may emit more than one module interface in its exports section. This is because a module may publicize the exports of other module. This commit makes the import infrastructure to read multiple module interfaces from exports sections and then look for the accessed module in the data.
Signed-off-by: Jose E. Marchesi <[email protected]> gcc/algol68/ChangeLog * a68-types.h (struct MOIF_T): Add chain_next to GTY info. * a68-imports.cc (a68_decode_modes): Mode offsets are relative to the start of the moif, not the start of the exports. (a68_decode_moifs): Renamed from a68_decode_moif and changed to decode multiple moifs from the exports. (a68_open_packet): Call a68_decode_moifs and look for the right moif. * a68-exports.cc (a68_moif_new): Initialize NEXT (moif). gcc/testsuite/ChangeLog * algol68/execute/modules/module17.a68: New test. --- gcc/algol68/a68-exports.cc | 1 + gcc/algol68/a68-imports.cc | 98 +++++++++++-------- gcc/algol68/a68-types.h | 3 +- .../algol68/execute/modules/module17.a68 | 2 +- 4 files changed, 61 insertions(+), 43 deletions(-) diff --git a/gcc/algol68/a68-exports.cc b/gcc/algol68/a68-exports.cc index 375b6213cef..ff4561f54a7 100644 --- a/gcc/algol68/a68-exports.cc +++ b/gcc/algol68/a68-exports.cc @@ -59,6 +59,7 @@ a68_moif_new (const char *module_name) NAME (moif) = (module_name == NULL ? NULL : ggc_strdup (module_name)); PRELUDE (moif) = NULL; POSTLUDE (moif) = NULL; + NEXT (moif) = NO_MOIF; vec_alloc (MODES (moif), 16); vec_alloc (MODULES (moif), 16); vec_alloc (IDENTIFIERS (moif), 16); diff --git a/gcc/algol68/a68-imports.cc b/gcc/algol68/a68-imports.cc index 6c76e921f13..775d58c0715 100644 --- a/gcc/algol68/a68-imports.cc +++ b/gcc/algol68/a68-imports.cc @@ -957,7 +957,7 @@ a68_replace_equivalent_mode (vec<MOID_T*,va_gc> *mode_list, static bool a68_decode_modes (MOIF_T *moif, encoded_modes_map_t &encoded_modes, - const char *data, size_t size, size_t pos, + const char *data, size_t size, size_t pos, size_t moif_pos, size_t *ppos, const char **errstr) { bool siga; @@ -974,7 +974,7 @@ a68_decode_modes (MOIF_T *moif, encoded_modes_map_t &encoded_modes, int8_t sizety; uint8_t ndims, nmodes, nargs; uint16_t nfields; - uint64_t mode_offset = pos; + uint64_t mode_offset = pos - moif_pos; uint64_t sub, ret_mode_offset; struct encoded_mode *encoded_mode; @@ -1106,6 +1106,7 @@ a68_decode_modes (MOIF_T *moif, encoded_modes_map_t &encoded_modes, for (auto entry : encoded_modes) { struct encoded_mode *em = entry.second; + gcc_assert (em->moid != NO_MOID); vec_safe_push (MODES (moif), em->moid); } @@ -1285,61 +1286,71 @@ a68_decode_extracts (MOIF_T *moif, encoded_modes_map_t &encoded_modes, return false; } -/* Decode the given exports data into a moif. If there is a decoding error - then put an explicative mssage in *ERRSTR and return NULL. */ +/* Decode the given exports data into a linked list of moifs. If there is a + decoding error then put an explicative mssage in *ERRSTR and return + NULL. */ static MOIF_T * -a68_decode_moif (const char *data, size_t size, const char **errstr) +a68_decode_moifs (const char *data, size_t size, const char **errstr) { + MOIF_T *moif_list = NO_MOIF; size_t pos = 0; - MOIF_T *moif = a68_moif_new (NULL /* name */); - encoded_modes_map_t encoded_modes (16); uint8_t magic1, magic2; uint16_t version; char *name, *prelude, *postlude; - DUINT8 (magic1); - DUINT8 (magic2); - if (magic1 != A68_EXPORT_MAGIC1 || magic2 != A68_EXPORT_MAGIC2) + while (pos < size) { - *errstr = "invalid magic number"; - goto decode_error; - } + MOIF_T *moif = a68_moif_new (NULL /* name */); + NEXT (moif) = moif_list; + moif_list = moif; + + size_t moif_pos = pos; + DUINT8 (magic1); + DUINT8 (magic2); + if (magic1 != A68_EXPORT_MAGIC1 || magic2 != A68_EXPORT_MAGIC2) + { + *errstr = "invalid magic number"; + goto decode_error; + } - DUINT16 (version); - if (version != 1) - { - *errstr = "invalid a68 exports version"; - goto decode_error; - } + DUINT16 (version); + if (version != 1) + { + *errstr = "invalid a68 exports version"; + goto decode_error; + } - DSTR (name); - DSTR (prelude); - DSTR (postlude); - NAME (moif) = name; - PRELUDE (moif) = prelude; - POSTLUDE (moif) = postlude; + DSTR (name); + DSTR (prelude); + DSTR (postlude); + NAME (moif) = name; + PRELUDE (moif) = prelude; + POSTLUDE (moif) = postlude; - /* Decode the modes table. - This installs the resulting moids in MOIF. */ - if (!a68_decode_modes (moif, encoded_modes, data, size, pos, &pos, errstr)) - goto decode_error; + encoded_modes_map_t encoded_modes (16); - /* Decode the extracts table. - This installs the resulting tags in MOIF. */ - if (!a68_decode_extracts (moif, encoded_modes, data, size, pos, &pos, errstr)) - goto decode_error; + /* Decode the modes table. + This installs the resulting moids in MOIF. */ + if (!a68_decode_modes (moif, encoded_modes, data, size, pos, moif_pos, &pos, errstr)) + goto decode_error; - /* We don't need the encoded modes anymore. */ - for (auto entry : encoded_modes) - { - struct encoded_mode *em = entry.second; - encoded_mode_free (em); + /* Decode the extracts table. + This installs the resulting tags in MOIF. */ + if (!a68_decode_extracts (moif, encoded_modes, data, size, pos, &pos, errstr)) + goto decode_error; + + /* We don't need the encoded modes anymore. */ + for (auto entry : encoded_modes) + { + struct encoded_mode *em = entry.second; + encoded_mode_free (em); + } } /* Got some juicy exports for youuuuuu... */ - return moif; + return moif_list; decode_error: if (*errstr == NULL) *errstr = "premature end of data"; @@ -1382,8 +1393,13 @@ a68_open_packet (const char *module) if (exports_data == NULL) return NULL; - /* Got some data. Parse it into a moif. */ + /* Got some data. Decode it into a list of moif. */ const char *errstr = NULL; - MOIF_T *moif = a68_decode_moif (exports_data, exports_data_size, &errstr); + MOIF_T *moif = a68_decode_moifs (exports_data, exports_data_size, &errstr); + + /* The moif we are looking for must be in the list. Note these are garbage + collected. */ + while (moif != NO_MOIF && strcmp (NAME (moif), module) != 0) + moif = NEXT (moif); return moif; } diff --git a/gcc/algol68/a68-types.h b/gcc/algol68/a68-types.h index 06d05e7f8f5..859f4148266 100644 --- a/gcc/algol68/a68-types.h +++ b/gcc/algol68/a68-types.h @@ -706,7 +706,7 @@ struct GTY(()) EXTRACT_T #define NO_MOIF ((MOIF_T *) 0) -struct GTY(()) MOIF_T +struct GTY((chain_next ("%h.next"))) MOIF_T { unsigned int version; const char *name; @@ -718,6 +718,7 @@ struct GTY(()) MOIF_T vec<EXTRACT_T*,va_gc> *identifiers; vec<EXTRACT_T*,va_gc> *prios; vec<EXTRACT_T*,va_gc> *operators; + MOIF_T *next; }; struct MODE_CACHE_T diff --git a/gcc/testsuite/algol68/execute/modules/module17.a68 b/gcc/testsuite/algol68/execute/modules/module17.a68 index 232ddeb5b91..b87425fbfdc 100644 --- a/gcc/testsuite/algol68/execute/modules/module17.a68 +++ b/gcc/testsuite/algol68/execute/modules/module17.a68 @@ -1,4 +1,4 @@ -module Module = +module Module_17 = def pub int ce_port; pub string ce_host; -- 2.30.2
