From f1c30ad16e0914455ee2c84e80714f6b271021f2 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 30 Dec 2020 10:29:16 +0100 Subject: Rework initialization and finalization. libghdl can now be re-initialized. --- pyGHDL/dom/Misc.py | 3 +++ pyGHDL/libghdl/__init__.py | 11 +++++++++++ src/files_map.adb | 6 +++++- src/files_map.ads | 5 ++++- src/ghdldrv/ghdlrun.adb | 10 ++++++---- src/libraries.adb | 27 ++++++++++++++++++++------- src/libraries.ads | 10 ++++++---- src/lists.adb | 8 ++++++-- src/lists.ads | 6 ++++-- src/name_table.adb | 4 ---- src/name_table.ads | 4 ++++ src/options.adb | 28 ++++++++++++++++++++++++---- src/options.ads | 17 +++++++++++++++++ src/str_table.adb | 6 +++++- src/str_table.ads | 5 ++++- src/vhdl/libghdl/libghdl.ads | 3 ++- src/vhdl/vhdl-nodes.adb | 6 +++++- src/vhdl/vhdl-nodes.adb.in | 6 +++++- src/vhdl/vhdl-nodes.ads | 5 ++++- testsuite/pyunit/libghdl/Initialize.py | 1 + 20 files changed, 136 insertions(+), 35 deletions(-) diff --git a/pyGHDL/dom/Misc.py b/pyGHDL/dom/Misc.py index df1ab4cce..0c9736cb0 100644 --- a/pyGHDL/dom/Misc.py +++ b/pyGHDL/dom/Misc.py @@ -27,6 +27,9 @@ class Design(VHDLModel_Design): def __ghdl_init(self): """Initialization: set options and then load libraries""" + # Initialize libghdl + libghdl.finalize() + libghdl.initialize() # Collect error messages in memory errorout_memory.Install_Handler() diff --git a/pyGHDL/libghdl/__init__.py b/pyGHDL/libghdl/__init__.py index da39a4475..431008df3 100644 --- a/pyGHDL/libghdl/__init__.py +++ b/pyGHDL/libghdl/__init__.py @@ -76,7 +76,9 @@ _libghdl_path = _get_libghdl_path() libghdl = ctypes.CDLL(_libghdl_path) # Initialize it. +# First Ada elaboration (must be the first call) libghdl.libghdl_init() +# Then 'normal' initialization (set hooks) libghdl.libghdl__set_hooks_for_analysis() # Set the prefix in order to locate the vhdl libraries. @@ -84,6 +86,15 @@ libghdl.libghdl__set_exec_prefix( *_to_char_p(dirname(dirname(_libghdl_path)).encode("utf-8")) ) +def finalize(): + "Free all the memory, be ready for a new initialization" + libghdl.options__finalize() + + +def initialize(): + "Initialize or re-initialize the library" + libghdl.options__initialize() + def set_option(opt): "Set option OPT. Return true iff the option is known and handled" diff --git a/src/files_map.adb b/src/files_map.adb index 9e3fd1ac9..3c17715ca 100644 --- a/src/files_map.adb +++ b/src/files_map.adb @@ -1213,12 +1213,16 @@ package body Files_Map is pragma Unreferenced (Debug_Source_Lines); pragma Unreferenced (Debug_Source_Loc); - procedure Initialize is + procedure Finalize is begin for I in Source_Files.First .. Source_Files.Last loop Free_Source_File (I); end loop; Source_Files.Free; + end Finalize; + + procedure Initialize is + begin Source_Files.Init; Next_Location := Location_Nil + 1; end Initialize; diff --git a/src/files_map.ads b/src/files_map.ads index ca7763b4f..2fcf53599 100644 --- a/src/files_map.ads +++ b/src/files_map.ads @@ -261,9 +261,12 @@ package Files_Map is function Image (Loc : Location_Type; Filename : Boolean := True) return String; - -- Free all memory and reinitialize. + -- Initialize. procedure Initialize; + -- Free all memory. + procedure Finalize; + private Lines_Table_Init : Natural := 64; diff --git a/src/ghdldrv/ghdlrun.adb b/src/ghdldrv/ghdlrun.adb index e19216fff..2e35122e7 100644 --- a/src/ghdldrv/ghdlrun.adb +++ b/src/ghdldrv/ghdlrun.adb @@ -34,6 +34,7 @@ with Interning; with Files_Map; with Name_Table; with Flags; +with Libraries; with Errorout; use Errorout; with Vhdl.Nodes; use Vhdl.Nodes; @@ -763,11 +764,12 @@ package body Ghdlrun is Ortho_Jit.Finish; Translation.Finalize; - Vhdl.Lists.Initialize; - Str_Table.Initialize; - Vhdl.Nodes.Initialize; - Files_Map.Initialize; + Vhdl.Lists.Finalize; + Str_Table.Finalize; + Vhdl.Nodes.Finalize; + Files_Map.Finalize; Name_Table.Finalize; + Libraries.Finalize; if Flag_Verbose then Put_Line ("Starting simulation"); diff --git a/src/libraries.adb b/src/libraries.adb index 42228ea6c..14526497d 100644 --- a/src/libraries.adb +++ b/src/libraries.adb @@ -15,22 +15,25 @@ -- along with GHDL; see the file COPYING. If not, write to the Free -- Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. -with Interfaces.C_Streams; with System; +with Interfaces.C_Streams; with GNAT.OS_Lib; + with Logging; use Logging; with Tables; with Errorout; use Errorout; with Options; use Options; -with Vhdl.Errors; use Vhdl.Errors; -with Vhdl.Scanner; -with Vhdl.Utils; use Vhdl.Utils; with Name_Table; use Name_Table; with Str_Table; -with Vhdl.Tokens; with Files_Map; with Flags; +with Std_Names; + +with Vhdl.Tokens; with Vhdl.Std_Package; +with Vhdl.Errors; use Vhdl.Errors; +with Vhdl.Scanner; +with Vhdl.Utils; use Vhdl.Utils; package body Libraries is -- Chain of known libraries. This is also the top node of all iir node. @@ -69,17 +72,27 @@ package body Libraries is -- Initialize paths table. -- Set the local path. - procedure Init_Paths is + procedure Initialize is begin -- Always look in current directory first. + Paths.Init; Name_Nil := Get_Identifier (""); Paths.Append (Name_Nil); Local_Directory := Name_Nil; Work_Directory := Name_Nil; + Libraries_Chain := Null_Iir; + Std_Library := Null_Iir; + Work_Library_Name := Std_Names.Name_Work; + Create_Virtual_Locations; - end Init_Paths; + end Initialize; + + procedure Finalize is + begin + Paths.Free; + end Finalize; function Path_To_Id (Path : String) return Name_Id is begin diff --git a/src/libraries.ads b/src/libraries.ads index 8e9967ff1..a4028cdad 100644 --- a/src/libraries.ads +++ b/src/libraries.ads @@ -17,7 +17,6 @@ -- 02111-1307, USA. with Types; use Types; with Vhdl.Nodes; use Vhdl.Nodes; -with Std_Names; package Libraries is -- This package defines the library manager. @@ -41,7 +40,7 @@ package Libraries is -- Library declaration for the std library. -- This is also the first library of the libraries chain. - Std_Library : Iir_Library_Declaration := Null_Iir; + Std_Library : Iir_Library_Declaration; -- Library declaration for the work library. -- Note: the identifier of the work_library is work_library_name, which @@ -49,7 +48,7 @@ package Libraries is Work_Library: Iir_Library_Declaration; -- Name of the WORK library. - Work_Library_Name : Name_Id := Std_Names.Name_Work; + Work_Library_Name : Name_Id; -- Directory of the work library. -- Set by default by INIT_PATHS to the local directory. @@ -67,7 +66,10 @@ package Libraries is -- Initialize library paths table. -- Set the local path. - procedure Init_Paths; + procedure Initialize; + + -- Free memory + procedure Finalize; -- Add PATH in the search path. procedure Add_Library_Path (Path : String); diff --git a/src/lists.adb b/src/lists.adb index f6739cd36..bd0cb5480 100644 --- a/src/lists.adb +++ b/src/lists.adb @@ -157,11 +157,15 @@ package body Lists is List := Null_List; end Destroy_List; - procedure Initialize is + procedure Finalize is begin Listt.Free; - Listt.Init; Chunkt.Free; + end Finalize; + + procedure Initialize is + begin + Listt.Init; Chunkt.Init; List_Free_Chain := Null_List; Chunk_Free_List := No_Chunk_Index; diff --git a/src/lists.ads b/src/lists.ads index 06fd601d9..0c47f8b56 100644 --- a/src/lists.ads +++ b/src/lists.ads @@ -69,8 +69,10 @@ package Lists is -- Destroy a list. procedure Destroy_List (List : in out List_Type); - -- Free all the lists and reset to initial state. - -- Must be used to free the memory used by the lists. + -- Free all the lists. + procedure Finalize; + + -- Reset to initial state. procedure Initialize; -- Append ELEMENT to the list. It's an O(1) operation. diff --git a/src/name_table.adb b/src/name_table.adb index e5d880a75..ba2bd4b98 100644 --- a/src/name_table.adb +++ b/src/name_table.adb @@ -103,8 +103,6 @@ package body Name_Table is Info => 0)); end Append_Terminator; - -- Initialize this package - -- This must be called once and only once before any use. procedure Initialize is begin Strings_Table.Init; @@ -454,6 +452,4 @@ package body Name_Table is end loop; end; end Disp_Stats; -begin - Initialize; end Name_Table; diff --git a/src/name_table.ads b/src/name_table.ads index 2dc6137c6..e9b948206 100644 --- a/src/name_table.ads +++ b/src/name_table.ads @@ -86,6 +86,10 @@ package Name_Table is -- Be sure all info fields have their default value. procedure Assert_No_Infos; + -- Initialize this package + -- This must be called once and only once before any use. + procedure Initialize; + -- Free all resources. The package cannot be used anymore after calling -- this procedure. procedure Finalize; diff --git a/src/options.adb b/src/options.adb index bf97e4533..ad9558f9d 100644 --- a/src/options.adb +++ b/src/options.adb @@ -19,28 +19,48 @@ with Simple_IO; with Errorout; use Errorout; with Types; use Types; -with Libraries; with Std_Names; +with Name_Table; +with Str_Table; +with Libraries; with PSL.Nodes; with PSL.Dump_Tree; +with Flags; use Flags; +with Files_Map; + +with Vhdl.Nodes; +with Vhdl.Lists; with Vhdl.Disp_Tree; with Vhdl.Scanner; with Vhdl.Parse; with Vhdl.Errors; with Vhdl.Back_End; use Vhdl.Back_End; -with Flags; use Flags; -with Files_Map; package body Options is procedure Initialize is begin + Name_Table.Initialize; Std_Names.Std_Names_Initialize; - Libraries.Init_Paths; + Str_Table.Initialize; + Vhdl.Lists.Initialize; + Vhdl.Nodes.Initialize; + Files_Map.Initialize; + Libraries.Initialize; PSL.Nodes.Init (Libraries.Library_Location); PSL.Dump_Tree.Dump_Hdl_Node := Vhdl.Disp_Tree.Disp_Tree_For_Psl'Access; Vhdl.Errors.Initialize; end Initialize; + procedure Finalize is + begin + Name_Table.Finalize; + Str_Table.Finalize; + Vhdl.Lists.Finalize; + Vhdl.Nodes.Finalize; + Files_Map.Finalize; + Libraries.Finalize; + end Finalize; + function Option_Warning (Opt: String; Val : Boolean) return Option_State is begin -- Handle -Werror. diff --git a/src/options.ads b/src/options.ads index 4b73a3ec7..5fca60477 100644 --- a/src/options.ads +++ b/src/options.ads @@ -47,8 +47,25 @@ package Options is -- Disp help about these options. procedure Disp_Options_Help; + -- Initialization + -- There are several stages: + -- 1) C, C++ initialization, Ada elaboration + -- That should be automatic + -- 2) ghdl initialization + -- Call the Initialize procedure below. + -- 3) Set options + -- 4) VHDL initialization (build of standard package) + -- Done by setup_libraries. Must be done after options because + -- the standard package changes according to the options + -- 5) Analyze... + -- 6) Finalize to free all the memory. + -- Then you can restart from 2). + -- Front-end intialization. procedure Initialize; + -- Free all the memory. + procedure Finalize; + Option_Error: exception; end Options; diff --git a/src/str_table.adb b/src/str_table.adb index 46a42dfe8..9993a68b9 100644 --- a/src/str_table.adb +++ b/src/str_table.adb @@ -90,7 +90,11 @@ package body Str_Table is procedure Initialize is begin - String8_Table.Free; String8_Table.Init; end Initialize; + + procedure Finalize is + begin + String8_Table.Free; + end Finalize; end Str_Table; diff --git a/src/str_table.ads b/src/str_table.ads index fd783562e..c15bd8089 100644 --- a/src/str_table.ads +++ b/src/str_table.ads @@ -58,6 +58,9 @@ package Str_Table is -- valid anymore. function String8_Address (Id : String8_Id) return System.Address; - -- Free all the memory and reinitialize the package. + -- Free all the memory + procedure Finalize; + + -- Initialize the package. procedure Initialize; end Str_Table; diff --git a/src/vhdl/libghdl/libghdl.ads b/src/vhdl/libghdl/libghdl.ads index 5326666b8..de2556069 100644 --- a/src/vhdl/libghdl/libghdl.ads +++ b/src/vhdl/libghdl/libghdl.ads @@ -36,7 +36,8 @@ package Libghdl is -- To be called before Analyze_File to initialize analysis. function Analyze_Init_Status return Integer; - -- Deprecated. Raise an exception in case of error. + -- Deprecated, use Analyze_Init_Status instead. + -- Raise an exception in case of error. procedure Analyze_Init; -- Analyze one file. diff --git a/src/vhdl/vhdl-nodes.adb b/src/vhdl/vhdl-nodes.adb index f02857bd4..b879ba275 100644 --- a/src/vhdl/vhdl-nodes.adb +++ b/src/vhdl/vhdl-nodes.adb @@ -741,10 +741,14 @@ package body Vhdl.Nodes is procedure Initialize is begin - Nodet.Free; Nodet.Init; end Initialize; + procedure Finalize is + begin + Nodet.Free; + end Finalize; + function Is_Null (Node : Iir) return Boolean is begin return Node = Null_Iir; diff --git a/src/vhdl/vhdl-nodes.adb.in b/src/vhdl/vhdl-nodes.adb.in index e35ed1832..5f98405a3 100644 --- a/src/vhdl/vhdl-nodes.adb.in +++ b/src/vhdl/vhdl-nodes.adb.in @@ -741,10 +741,14 @@ package body Vhdl.Nodes is procedure Initialize is begin - Nodet.Free; Nodet.Init; end Initialize; + procedure Finalize is + begin + Nodet.Free; + end Finalize; + function Is_Null (Node : Iir) return Boolean is begin return Node = Null_Iir; diff --git a/src/vhdl/vhdl-nodes.ads b/src/vhdl/vhdl-nodes.ads index fb92c5882..855dccebd 100644 --- a/src/vhdl/vhdl-nodes.ads +++ b/src/vhdl/vhdl-nodes.ads @@ -7338,9 +7338,12 @@ package Vhdl.Nodes is type Free_Iir_Hook is access procedure (N : Iir); procedure Register_Free_Hook (Hook : Free_Iir_Hook); - -- Free all and reinit. + -- Initialize. procedure Initialize; + -- Free all the memory. + procedure Finalize; + -- Disp statistics about node usage. procedure Disp_Stats; diff --git a/testsuite/pyunit/libghdl/Initialize.py b/testsuite/pyunit/libghdl/Initialize.py index 0a46fe8b4..ccc157fd7 100644 --- a/testsuite/pyunit/libghdl/Initialize.py +++ b/testsuite/pyunit/libghdl/Initialize.py @@ -23,6 +23,7 @@ class Instantiate(TestCase): def test_InitializeGHDL(self) -> None: """Initialization: set options and then load libaries""" + libghdl.initialize() # Print error messages on the console. errorout_console.Install_Handler() -- cgit v1.2.3