---------------------------------------- ---------------------------------------- -- -- -- OCARINA COMPONENTS -- -- -- -- OCARINA.GENERATORS.PO_HI_C.MARSHALLERS -- -- -- -- B o d y -- -- -- -- Copyright (C) 2007, GET-Telecom Paris. -- -- -- -- Ocarina is free software; you can redistribute it and/or modify -- -- it under terms of the GNU General Public License as published by the -- -- Free Software Foundation; either version 2, or (at your option) any -- -- later version. Ocarina is distributed in the hope that it will be -- -- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -- -- Public License for more details. You should have received a copy of the -- -- GNU General Public License distributed with Ocarina; see file COPYING. -- -- If not, write to the Free Software Foundation, 51 Franklin Street, Fifth -- -- Floor, Boston, MA 02111-1301, USA. -- -- -- -- As a special exception, if other files instantiate generics from this -- -- unit, or you link this unit with other files to produce an executable, -- -- this unit does not by itself cause the resulting executable to be -- -- covered by the GNU General Public License. This exception does not -- -- however invalidate any other reasons why the executable file might be -- -- covered by the GNU Public License. -- -- -- -- Ocarina is maintained by the Ocarina team -- -- (ocarina-users@listes.enst.fr) -- -- -- ------------------------------------------------------------------------------ with Ocarina.Nodes; with Ocarina.Nutils; with Ocarina.Entities.Components; with Ocarina.Generators.Utils; with Ocarina.Generators.Properties; with Ocarina.Generators.Messages; with Ocarina.Generators.C_Tree.Nutils; with Ocarina.Generators.C_Tree.Nodes; with Ocarina.Generators.C_Values; with Ocarina.Generators.PO_HI_C.Mapping; with Ocarina.Generators.PO_HI_C.Runtime; package body Ocarina.Generators.PO_HI_C.Marshallers is use Ocarina.Nodes; use Ocarina.Entities.Components; use Ocarina.Generators.Utils; use Ocarina.Generators.Properties; use Ocarina.Generators.Messages; use Ocarina.Generators.C_Tree.Nutils; use Ocarina.Generators.PO_HI_C.Mapping; use Ocarina.Generators.PO_HI_C.Runtime; package AAU renames Ocarina.Nutils; package CTN renames Ocarina.Generators.C_Tree.Nodes; package CV renames Ocarina.Generators.C_Values; Marshaller_Request_Spec : node_id; Unmarshaller_Request_Spec : node_id; ----------------- -- Header_File -- ----------------- package body Header_File is procedure Visit_Architecture_Instance (E : node_id); procedure Visit_Component_Instance (E : node_id); procedure Visit_System_Instance (E : node_id); procedure Visit_Process_Instance (E : node_id); procedure Visit_Thread_Instance (E : node_id); procedure Visit_Subprogram_Instance (E : node_id); procedure Visit_Data_Instance (E : node_id); function Marshall_Type_Spec (E : node_id) return node_id; function Unmarshall_Type_Spec (E : node_id) return node_id; function Marshall_Request_Spec (E : node_id) return node_id; function Unmarshall_Request_Spec (E : node_id) return node_id; --------------------------- -- Marshall_Request_Spec -- --------------------------- function Marshall_Request_Spec (E : node_id) return node_id is N : node_id; Parameters : constant list_id := New_List (CTN.k_parameter_list); begin Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_request)), Parameter_Type => Make_Pointer_Type (RE (re_request_t))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_message)), Parameter_Type => Make_Pointer_Type (RE (re_msg_t))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_offset)), Parameter_Type => Make_Pointer_Type (RE (re_uint16_t))), Parameters); N := Make_Function_Specification (Defining_Identifier => Map_C_Marshaller_Subprogram (E, Is_Request => True), Parameters => Parameters, Return_Type => New_Node (CTN.k_void)); return N; end Marshall_Request_Spec; ----------------------------- -- Unmarshall_Request_Spec -- ----------------------------- function Unmarshall_Request_Spec (E : node_id) return node_id is N : node_id; Parameters : constant list_id := New_List (CTN.k_parameter_list); begin Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_request)), Parameter_Type => Make_Pointer_Type (RE (re_request_t))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_message)), Parameter_Type => Make_Pointer_Type (RE (re_msg_t))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_offset)), Parameter_Type => Make_Pointer_Type (RE (re_uint16_t))), Parameters); N := Make_Function_Specification (Defining_Identifier => Map_C_Marshaller_Subprogram (E, Is_Request => True, Is_Unmarshall => True), Parameters => Parameters, Return_Type => New_Node (CTN.k_void)); return N; end Unmarshall_Request_Spec; ------------------------ -- Marshall_Type_Spec -- ------------------------ function Marshall_Type_Spec (E : node_id) return node_id is N : node_id; Parameters : constant list_id := New_List (CTN.k_parameter_list); begin Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_value)), Parameter_Type => Map_C_Defining_Identifier (E)), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_message)), Parameter_Type => Make_Pointer_Type (RE (re_msg_t))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_offset)), Parameter_Type => Make_Pointer_Type (RE (re_uint16_t))), Parameters); N := Make_Function_Specification (Defining_Identifier => Map_C_Marshaller_Subprogram (E), Parameters => Parameters, Return_Type => New_Node (CTN.k_void)); return N; end Marshall_Type_Spec; -------------------------- -- Unmarshall_Type_Spec -- -------------------------- function Unmarshall_Type_Spec (E : node_id) return node_id is N : node_id; Parameters : constant list_id := New_List (CTN.k_parameter_list); begin Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_value)), Parameter_Type => Make_Pointer_Type (Map_C_Defining_Identifier (E))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_message)), Parameter_Type => Make_Pointer_Type (RE (re_msg_t))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_offset)), Parameter_Type => Make_Pointer_Type (RE (re_uint16_t))), Parameters); N := Make_Function_Specification (Defining_Identifier => Map_C_Marshaller_Subprogram (E, Is_Unmarshall => True), Parameters => Parameters, Return_Type => New_Node (CTN.k_void)); return N; end Unmarshall_Type_Spec; ----------- -- Visit -- ----------- procedure Visit (E : node_id) is begin case Kind (E) is when k_architecture_instance => Visit_Architecture_Instance (E); when k_component_instance => Visit_Component_Instance (E); when others => null; end case; end Visit; --------------------------------- -- Visit_Architecture_Instance -- --------------------------------- procedure Visit_Architecture_Instance (E : node_id) is begin Visit (Root_System (E)); end Visit_Architecture_Instance; ------------------------------ -- Visit_Component_Instance -- ------------------------------ procedure Visit_Component_Instance (E : node_id) is Cathegory : constant component_category := Get_Category_Of_Component (E); begin case Cathegory is when cc_system => Visit_System_Instance (E); when cc_process => Visit_Process_Instance (E); when cc_thread => Visit_Thread_Instance (E); when cc_data => Visit_Data_Instance (E); when cc_subprogram => Visit_Subprogram_Instance (E); when others => null; end case; end Visit_Component_Instance; ------------------------- -- Visit_Data_Instance -- ------------------------- procedure Visit_Data_Instance (E : node_id) is N : node_id; begin if No (Get_Handling (E, by_name, h_c_marshall_spec)) then N := Marshall_Type_Spec (E); Set_Handling (E, by_name, h_c_marshall_spec, N); Append_Node_To_List (N, CTN.Declarations (Current_File)); end if; if No (Get_Handling (E, by_name, h_c_unmarshall_spec)) then N := Unmarshall_Type_Spec (E); Set_Handling (E, by_name, h_c_unmarshall_spec, N); Append_Node_To_List (N, CTN.Declarations (Current_File)); end if; Bind_AADL_To_Marshaller (Identifier (E), Get_Handling (E, by_name, h_c_marshall_spec)); Bind_AADL_To_Unmarshaller (Identifier (E), Get_Handling (E, by_name, h_c_unmarshall_spec)); end Visit_Data_Instance; ---------------------------- -- Visit_Process_Instance -- ---------------------------- procedure Visit_Process_Instance (E : node_id) is U : constant node_id := CTN.Distributed_Application_Unit (CTN.Naming_Node (Backend_Node (Identifier (E)))); P : constant node_id := CTN.Entity (U); S : node_id; Parameters : list_id; begin Push_Entity (P); Push_Entity (U); Set_Marshallers_Header; -- Start recording the handling since they have to be reset -- for each node. Start_Recording_Handlings; -- Visit all the subcomponents of the process if not AAU.Is_Empty (Subcomponents (E)) then S := First_Node (Subcomponents (E)); while Present (S) loop -- Visit the component instance corresponding to the -- subcomponent S. Visit (Corresponding_Instance (S)); S := Next_Node (S); end loop; end if; -- Make the main marshall_request function Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_request)), Parameter_Type => Make_Pointer_Type (RE (re_request_t))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_message)), Parameter_Type => Make_Pointer_Type (RE (re_msg_t))), Parameters); Marshaller_Request_Spec := Make_Function_Specification (Defining_Identifier => RE (re_marshall_request), Parameters => Parameters, Return_Type => New_Node (CTN.k_void)); Append_Node_To_List (Marshaller_Request_Spec, CTN.Declarations (Current_File)); -- Make the main unmarshall_request function Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_request)), Parameter_Type => Make_Pointer_Type (RE (re_request_t))), Parameters); Append_Node_To_List (Make_Parameter_Specification (Defining_Identifier => Make_Defining_Identifier (PN (p_message)), Parameter_Type => Make_Pointer_Type (RE (re_msg_t))), Parameters); Unmarshaller_Request_Spec := Make_Function_Specification (Defining_Identifier => RE (re_unmarshall_request), Parameters => Parameters, Return_Type => New_Node (CTN.k_void)); Append_Node_To_List (Unmarshaller_Request_Spec, CTN.Declarations (Current_File)); -- Unmark all the marked types Reset_Handlings; Pop_Entity; -- U Pop_Entity; -- P end Visit_Process_Instance; ------------------------------- -- Visit_Subprogram_Instance -- ------------------------------- procedure Visit_Subprogram_Instance (E : node_id) is F : node_id; begin -- Declare all necessary data types if not AAU.Is_Empty (Features (E)) then F := First_Node (Features (E)); while Present (F) loop if Kind (F) = k_port_spec_instance then Display_Located_Error (Loc (F), "Port features in subprogram are not supported", Fatal => True); end if; if Present (Corresponding_Instance (F)) then Visit (Corresponding_Instance (F)); end if; F := Next_Node (F); end loop; end if; end Visit_Subprogram_Instance; --------------------------- -- Visit_System_Instance -- --------------------------- procedure Visit_System_Instance (E : node_id) is S : node_id; begin Push_Entity (HI_Distributed_Application_Root); -- Visit all the subcomponents of the system if not AAU.Is_Empty (Subcomponents (E)) then S := First_Node (Subcomponents (E)); while Present (S) loop -- Visit the component instance corresponding to the -- subcomponent S. Visit (Corresponding_Instance (S)); S := Next_Node (S); end loop; end if; Pop_Entity; -- HI_Distributed_Application_Root end Visit_System_Instance; --------------------------- -- Visit_Thread_Instance -- --------------------------- procedure Visit_Thread_Instance (E : node_id) is Call_Seq : node_id; Spg_Call : node_id; F : node_id; N : node_id; begin if not AAU.Is_Empty (Features (E)) then F := First_Node (Features (E)); while Present (F) loop if Kind (F) = k_port_spec_instance and then Nodes.Is_Data (F) then Visit (Corresponding_Instance (F)); end if; F := Next_Node (F); end loop; end if; -- Visit all the call sequences of the thread if not AAU.Is_Empty (Calls (E)) then Call_Seq := First_Node (Calls (E)); while Present (Call_Seq) loop -- For each call sequence visit all the called -- subprograms. if not AAU.Is_Empty (Subprogram_Calls (Call_Seq)) then Spg_Call := First_Node (Subprogram_Calls (Call_Seq)); while Present (Spg_Call) loop Visit (Corresponding_Instance (Spg_Call)); Spg_Call := Next_Node (Spg_Call); end loop; end if; Call_Seq := Next_Node (Call_Seq); end loop; end if; if Has_Ports (E) then F := First_Node (Features (E)); while Present (F) loop if Kind (F) = k_port_spec_instance then N := Marshall_Request_Spec (F); Set_Handling (F, by_name, h_c_marshall_spec, N); Append_Node_To_List (N, CTN.Declarations (Current_File)); N := Unmarshall_Request_Spec (F); Set_Handling (F, by_name, h_c_unmarshall_spec, N); Append_Node_To_List (N, CTN.Declarations (Current_File)); Bind_AADL_To_Marshaller (Identifier (F), Get_Handling (F, by_name, h_c_marshall_spec)); Bind_AADL_To_Unmarshaller (Identifier (F), Get_Handling (F, by_name, h_c_unmarshall_spec)); end if; F := Next_Node (F); end loop; end if; end Visit_Thread_Instance; end Header_File; ----------------- -- Source_File -- ----------------- package body Source_File is procedure Visit_Architecture_Instance (E : node_id); procedure Visit_Component_Instance (E : node_id); procedure Visit_System_Instance (E : node_id); procedure Visit_Process_Instance (E : node_id); procedure Visit_Thread_Instance (E : node_id); procedure Visit_Data_Instance (E : node_id); procedure Visit_Subprogram_Instance (E : node_id); function Get_Marshall_Function_Name (E : node_id) return node_id; function Get_Unmarshall_Function_Name (E : node_id) return node_id; Marshall_Alternatives : list_id; Unmarshall_Alternatives : list_id; ----------------------------- -- Make_Marshall_Type_Body -- ----------------------------- function Make_Marshall_Type_Body (E : node_id) return node_id is Data_Type : supported_data_type; C : node_id; N : node_id; Declarations : list_id; Statements : list_id; Parameters : list_id; Marshall_Spec : constant node_id := CTN.Marshaller_Node (Backend_Node (Identifier (E))); begin -- Create the marshall function for this type Declarations := New_List (CTN.k_declaration_list); Statements := New_List (CTN.k_statement_list); Data_Type := Get_Data_Type (E); if Data_Type = data_with_accessors or else Data_Type = data_record then C := First_Node (Subcomponents (E)); while Present (C) loop Visit (Corresponding_Instance (C)); Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Member_Designator (Aggregate_Name => Make_Defining_Identifier (PN (p_value)), Defining_Identifier => Map_C_Defining_Identifier (C), Is_Pointer => False), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_offset)), Parameters); N := Make_Call_Profile (Get_Marshall_Function_Name (Corresponding_Instance (C)), Parameters); Append_Node_To_List (N, Statements); C := Next_Node (C); end loop; else Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Defining_Identifier (PN (p_value)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_offset)), Parameters); N := Make_Call_Profile (Get_Marshall_Function_Name (E), Parameters); Append_Node_To_List (N, Statements); end if; N := Make_Function_Implementation (Marshall_Spec, Declarations, Statements); return N; end Make_Marshall_Type_Body; ------------------------------- -- Make_Unmarshall_Type_Body -- ------------------------------- function Make_Unmarshall_Type_Body (E : node_id) return node_id is Data_Type : supported_data_type; N : node_id; C : node_id; Declarations : list_id; Statements : list_id; Parameters : list_id; Unmarshall_Spec : constant node_id := CTN.Unmarshaller_Node (Backend_Node (Identifier (E))); begin -- Create the unmarshall function for this type Declarations := New_List (CTN.k_declaration_list); Statements := New_List (CTN.k_statement_list); Data_Type := Get_Data_Type (E); if Data_Type = data_with_accessors or else Data_Type = data_record then C := First_Node (Subcomponents (E)); while Present (C) loop Visit (Corresponding_Instance (C)); Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Variable_Address (Make_Member_Designator (Aggregate_Name => Make_Defining_Identifier (PN (p_value)), Defining_Identifier => Map_C_Defining_Identifier (C), Is_Pointer => True)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_offset)), Parameters); N := Make_Call_Profile (Get_Unmarshall_Function_Name (Corresponding_Instance (C)), Parameters); Append_Node_To_List (N, Statements); C := Next_Node (C); end loop; else Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Defining_Identifier (PN (p_value)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_offset)), Parameters); N := Make_Call_Profile (Get_Unmarshall_Function_Name (E), Parameters); Append_Node_To_List (N, Statements); end if; N := Make_Function_Implementation (Unmarshall_Spec, Declarations, Statements); return N; end Make_Unmarshall_Type_Body; -------------------------------- -- Get_Marshall_Function_Name -- -------------------------------- function Get_Marshall_Function_Name (E : node_id) return node_id is Data_Type : supported_data_type; Data_Size : size_type; begin Data_Type := Get_Data_Type (E); Data_Size := Get_Data_Size (E); case Data_Type is when data_boolean => return (RE (re_marshall_int)); when data_integer => if Data_Size.S = 0 then return (RE (re_marshall_int)); elsif Data_Size.S = 8 and then Data_Size.U = bit then return (RE (re_marshall_int8)); elsif Data_Size.S = 1 and then Data_Size.U = Properties.byte then return (RE (re_marshall_int8)); elsif Data_Size.S = 16 and then Data_Size.U = bit then return (RE (re_marshall_int16)); elsif Data_Size.S = 2 and then Data_Size.U = Properties.byte then return (RE (re_marshall_int16)); elsif Data_Size.S = 32 and then Data_Size.U = bit then return (RE (re_marshall_int32)); elsif Data_Size.S = 4 and then Data_Size.U = Properties.byte then return (RE (re_marshall_int32)); elsif Data_Size.S = 64 and then Data_Size.U = bit then return (RE (re_marshall_int64)); elsif Data_Size.S = 8 and then Data_Size.U = Properties.byte then return (RE (re_marshall_int64)); else Display_Error ("Unsupported data size", Fatal => True); return (No_Node); end if; when data_float | data_fixed => return (RE (re_marshall_float)); when others => return (Map_C_Marshaller_Subprogram (E)); end case; end Get_Marshall_Function_Name; ---------------------------------- -- Get_Unmarshall_Function_Name -- ---------------------------------- function Get_Unmarshall_Function_Name (E : node_id) return node_id is Data_Type : supported_data_type; Data_Size : size_type; begin Data_Type := Get_Data_Type (E); Data_Size := Get_Data_Size (E); case Data_Type is when data_boolean => return (RE (re_unmarshall_int)); when data_integer => if Data_Size.S = 0 then return (RE (re_unmarshall_int)); elsif Data_Size.S = 8 and then Data_Size.U = bit then return (RE (re_unmarshall_int8)); elsif Data_Size.S = 1 and then Data_Size.U = Properties.byte then return (RE (re_unmarshall_int8)); elsif Data_Size.S = 16 and then Data_Size.U = bit then return (RE (re_unmarshall_int16)); elsif Data_Size.S = 2 and then Data_Size.U = Properties.byte then return (RE (re_unmarshall_int16)); elsif Data_Size.S = 32 and then Data_Size.U = bit then return (RE (re_unmarshall_int32)); elsif Data_Size.S = 4 and then Data_Size.U = Properties.byte then return (RE (re_unmarshall_int32)); elsif Data_Size.S = 64 and then Data_Size.U = bit then return (RE (re_unmarshall_int64)); elsif Data_Size.S = 8 and then Data_Size.U = Properties.byte then return (RE (re_unmarshall_int64)); else Display_Error ("Unsupported data size", Fatal => True); return (No_Node); end if; when data_float | data_fixed => return (RE (re_unmarshall_float)); when others => return (Map_C_Marshaller_Subprogram (E, Is_Unmarshall => True)); end case; end Get_Unmarshall_Function_Name; ----------- -- Visit -- ----------- procedure Visit (E : node_id) is begin case Kind (E) is when k_architecture_instance => Visit_Architecture_Instance (E); when k_component_instance => Visit_Component_Instance (E); when others => null; end case; end Visit; --------------------------------- -- Visit_Architecture_Instance -- --------------------------------- procedure Visit_Architecture_Instance (E : node_id) is begin Visit (Root_System (E)); end Visit_Architecture_Instance; ------------------------------ -- Visit_Component_Instance -- ------------------------------ procedure Visit_Component_Instance (E : node_id) is Cathegory : constant component_category := Get_Category_Of_Component (E); begin case Cathegory is when cc_system => Visit_System_Instance (E); when cc_process => Visit_Process_Instance (E); when cc_thread => Visit_Thread_Instance (E); when cc_data => Visit_Data_Instance (E); when cc_subprogram => Visit_Subprogram_Instance (E); when others => null; end case; end Visit_Component_Instance; ------------------------- -- Visit_Data_Instance -- ------------------------- procedure Visit_Data_Instance (E : node_id) is N : node_id; begin Add_Include (RH (rh_types)); Add_Include (RH (rh_po_hi_types)); if No (Get_Handling (E, by_name, h_c_marshall_body)) and then Present (CTN.Marshaller_Node (Backend_Node (Identifier (E)))) then N := Make_Marshall_Type_Body (E); Set_Handling (E, by_name, h_c_marshall_body, N); Append_Node_To_List (N, CTN.Declarations (Current_File)); end if; if No (Get_Handling (E, by_name, h_c_unmarshall_body)) and then Present (CTN.Unmarshaller_Node (Backend_Node (Identifier (E)))) then N := Make_Unmarshall_Type_Body (E); Set_Handling (E, by_name, h_c_unmarshall_body, N); Append_Node_To_List (N, CTN.Declarations (Current_File)); end if; end Visit_Data_Instance; ---------------------------- -- Visit_Process_Instance -- ---------------------------- procedure Visit_Process_Instance (E : node_id) is U : constant node_id := CTN.Distributed_Application_Unit (CTN.Naming_Node (Backend_Node (Identifier (E)))); P : constant node_id := CTN.Entity (U); S : node_id; N : node_id; C : node_id; I : node_id; D : node_id; F : node_id; J : node_id; Declarations : list_id; Statements : list_id; Parameters : list_id; begin Push_Entity (P); Push_Entity (U); Set_Marshallers_Source; Start_Recording_Handlings; Marshall_Alternatives := New_List (CTN.k_alternatives_list); Unmarshall_Alternatives := New_List (CTN.k_alternatives_list); if not AAU.Is_Empty (Features (E)) then C := First_Node (Features (E)); while Present (C) loop if Kind (C) = k_port_spec_instance and then not AAU.Is_Empty (Destinations (C)) then D := First_Node (Destinations (C)); I := Item (D); if Present (I) and then Kind (I) = k_port_spec_instance and then not AAU.Is_Empty (Destinations (I)) then F := First_Node (Destinations (I)); while Present (F) loop J := Item (F); if Present (J) then Visit (Parent_Component (J)); end if; F := Next_Node (F); end loop; end if; D := Next_Node (D); end if; C := Next_Node (C); end loop; end if; -- Visit all the subcomponents of the process if not AAU.Is_Empty (Subcomponents (E)) then S := First_Node (Subcomponents (E)); while Present (S) loop -- Visit the component instance corresponding to the -- subcomponent S. Visit (Corresponding_Instance (S)); S := Next_Node (S); end loop; end if; -- Make the global __po_hi_marshall_request function Declarations := New_List (CTN.k_declaration_list); Statements := New_List (CTN.k_statement_list); Append_Node_To_List (Make_Variable_Declaration (Defining_Identifier => Make_Defining_Identifier (PN (p_offset)), Used_Type => RE (re_uint16_t)), Declarations); Append_Node_To_List (Make_Expression (Left_Expr => Make_Defining_Identifier (PN (p_offset)), Operator => op_equal, Right_Expr => Make_Literal (CV.New_Int_Value (0, 1, 10))), Statements); Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Member_Designator (Defining_Identifier => Make_Defining_Identifier (MN (m_port)), Aggregate_Name => Make_Defining_Identifier (PN (p_request)), Is_Pointer => True), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); N := Make_Call_Profile (RE (re_marshall_port), Parameters); Append_Node_To_List (N, Statements); if not Is_Empty (Marshall_Alternatives) then N := Make_Switch_Alternative (No_List, No_List); Append_Node_To_List (N, Marshall_Alternatives); N := Make_Switch_Statement (Expression => Make_Member_Designator (Defining_Identifier => Make_Defining_Identifier (MN (m_port)), Aggregate_Name => Make_Defining_Identifier (VN (v_request)), Is_Pointer => True), Alternatives => Marshall_Alternatives); else N := Message_Comment ("No alternative was declared"); end if; Append_Node_To_List (N, Statements); N := Make_Function_Implementation (Marshaller_Request_Spec, Declarations, Statements); Append_Node_To_List (N, CTN.Declarations (Current_File)); -- Make the global __po_hi_unmarshall_request function Declarations := New_List (CTN.k_declaration_list); Statements := New_List (CTN.k_statement_list); Append_Node_To_List (Make_Variable_Declaration (Defining_Identifier => Make_Defining_Identifier (PN (p_offset)), Used_Type => RE (re_uint16_t)), Declarations); Append_Node_To_List (Make_Expression (Left_Expr => Make_Defining_Identifier (PN (p_offset)), Operator => op_equal, Right_Expr => Make_Literal (CV.New_Int_Value (0, 1, 10))), Statements); Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Variable_Address (Make_Member_Designator (Defining_Identifier => Make_Defining_Identifier (MN (m_port)), Aggregate_Name => Make_Defining_Identifier (PN (p_request)), Is_Pointer => True)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); N := Make_Call_Profile (RE (re_unmarshall_port), Parameters); Append_Node_To_List (N, Statements); if not Is_Empty (Marshall_Alternatives) then N := Make_Switch_Alternative (No_List, No_List); Append_Node_To_List (N, Unmarshall_Alternatives); N := Make_Switch_Statement (Expression => Make_Member_Designator (Defining_Identifier => Make_Defining_Identifier (MN (m_port)), Aggregate_Name => Make_Defining_Identifier (VN (v_request)), Is_Pointer => True), Alternatives => Unmarshall_Alternatives); else N := Message_Comment ("No alternative was declared"); end if; Append_Node_To_List (N, Statements); N := Make_Function_Implementation (Unmarshaller_Request_Spec, Declarations, Statements); Append_Node_To_List (N, CTN.Declarations (Current_File)); -- Unmark all the marked types Reset_Handlings; Pop_Entity; -- U Pop_Entity; -- P end Visit_Process_Instance; ------------------------------- -- Visit_Subprogram_Instance -- ------------------------------- procedure Visit_Subprogram_Instance (E : node_id) is F : node_id; begin -- Declare all necessary data types if not AAU.Is_Empty (Features (E)) then F := First_Node (Features (E)); while Present (F) loop if Kind (F) = k_port_spec_instance then Display_Located_Error (Loc (F), "Port features in subprogram are not supported", Fatal => True); end if; if Present (Corresponding_Instance (F)) then Visit (Corresponding_Instance (F)); end if; F := Next_Node (F); end loop; end if; end Visit_Subprogram_Instance; --------------------------- -- Visit_System_Instance -- --------------------------- procedure Visit_System_Instance (E : node_id) is S : node_id; begin Push_Entity (HI_Distributed_Application_Root); -- Visit all the subcomponents of the system if not AAU.Is_Empty (Subcomponents (E)) then S := First_Node (Subcomponents (E)); while Present (S) loop -- Visit the component instance corresponding to the -- subcomponent S. Visit (Corresponding_Instance (S)); S := Next_Node (S); end loop; end if; Pop_Entity; -- HI_Distributed_Application_Root end Visit_System_Instance; --------------------------- -- Visit_Thread_Instance -- --------------------------- procedure Visit_Thread_Instance (E : node_id) is Call_Seq : node_id; Spg_Call : node_id; F : node_id; N : node_id; D : node_id; Parameters : list_id; Marshall_Declarations : list_id; Unmarshall_Declarations : list_id; Marshall_Statements : list_id; Unmarshall_Statements : list_id; Switch_Labels : list_id; Switch_Statements : list_id; Marshall_Spec : node_id; Unmarshall_Spec : node_id; begin if not AAU.Is_Empty (Features (E)) then F := First_Node (Features (E)); while Present (F) loop if Kind (F) = k_port_spec_instance and then Nodes.Is_Data (F) then Visit (Corresponding_Instance (F)); end if; F := Next_Node (F); end loop; end if; -- Visit all the call sequences of the thread if not AAU.Is_Empty (Calls (E)) then Call_Seq := First_Node (Calls (E)); while Present (Call_Seq) loop -- For each call sequence visit all the called -- subprograms. if not AAU.Is_Empty (Subprogram_Calls (Call_Seq)) then Spg_Call := First_Node (Subprogram_Calls (Call_Seq)); while Present (Spg_Call) loop Visit (Corresponding_Instance (Spg_Call)); Spg_Call := Next_Node (Spg_Call); end loop; end if; Call_Seq := Next_Node (Call_Seq); end loop; end if; if Has_Ports (E) then F := First_Node (Features (E)); while Present (F) loop if Kind (F) = k_port_spec_instance and then Nodes.Is_Data (F) then Unmarshall_Spec := CTN.Unmarshaller_Node (Backend_Node (Identifier (F))); Marshall_Spec := CTN.Marshaller_Node (Backend_Node (Identifier (F))); D := Corresponding_Instance (F); Marshall_Declarations := New_List (CTN.k_declaration_list); Unmarshall_Declarations := New_List (CTN.k_declaration_list); Unmarshall_Statements := New_List (CTN.k_statement_list); Marshall_Statements := New_List (CTN.k_statement_list); Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Member_Designator (Defining_Identifier => Make_Member_Designator (Defining_Identifier => Make_Defining_Identifier (Map_C_Enumerator_Name (F)), Aggregate_Name => Make_Member_Designator (Defining_Identifier => Make_Defining_Identifier (Map_C_Enumerator_Name (F)), Aggregate_Name => Make_Defining_Identifier (MN (m_vars)))), Aggregate_Name => Make_Defining_Identifier (PN (p_request)), Is_Pointer => True), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_offset)), Parameters); N := Make_Call_Profile (Map_C_Marshaller_Subprogram (D), Parameters); Append_Node_To_List (N, Marshall_Statements); Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Variable_Address (Make_Member_Designator (Defining_Identifier => Make_Member_Designator (Defining_Identifier => Make_Defining_Identifier (Map_C_Enumerator_Name (F)), Aggregate_Name => Make_Member_Designator (Defining_Identifier => Make_Defining_Identifier (Map_C_Enumerator_Name (F)), Aggregate_Name => Make_Defining_Identifier (MN (m_vars)))), Aggregate_Name => Make_Defining_Identifier (PN (p_request)), Is_Pointer => True)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_offset)), Parameters); N := Make_Call_Profile (Map_C_Marshaller_Subprogram (D, Is_Unmarshall => True), Parameters); Append_Node_To_List (N, Unmarshall_Statements); N := Make_Function_Implementation (Marshall_Spec, Marshall_Declarations, Marshall_Statements); Set_Handling (E, by_name, h_c_marshall_body, N); Append_Node_To_List (N, CTN.Declarations (Current_File)); N := Make_Function_Implementation (Unmarshall_Spec, Unmarshall_Declarations, Unmarshall_Statements); Set_Handling (F, by_name, h_c_unmarshall_body, N); Append_Node_To_List (N, CTN.Declarations (Current_File)); -- Now, add alternatives to the main switches to use -- our marshallers functions. Switch_Statements := New_List (CTN.k_statement_list); Switch_Labels := New_List (CTN.k_label_list); Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Defining_Identifier (PN (p_request)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); Append_Node_To_List (Make_Variable_Address (Make_Defining_Identifier (PN (p_offset))), Parameters); N := Make_Call_Profile (Map_C_Marshaller_Subprogram (F, Is_Request => True), Parameters); Append_Node_To_List (N, Switch_Statements); Append_Node_To_List (Make_Defining_Identifier (Map_C_Enumerator_Name (F)), Switch_Labels); N := Make_Switch_Alternative (Switch_Labels, Switch_Statements); Append_Node_To_List (N, Marshall_Alternatives); -- Make the alternative for the global unmarshall_request -- function. Switch_Statements := New_List (CTN.k_statement_list); Switch_Labels := New_List (CTN.k_label_list); Parameters := New_List (CTN.k_parameter_list); Append_Node_To_List (Make_Defining_Identifier (PN (p_request)), Parameters); Append_Node_To_List (Make_Defining_Identifier (PN (p_message)), Parameters); Append_Node_To_List (Make_Variable_Address (Make_Defining_Identifier (PN (p_offset))), Parameters); N := Make_Call_Profile (Map_C_Marshaller_Subprogram (F, Is_Request => True, Is_Unmarshall => True), Parameters); Append_Node_To_List (N, Switch_Statements); Append_Node_To_List (Make_Defining_Identifier (Map_C_Enumerator_Name (F)), Switch_Labels); N := Make_Switch_Alternative (Switch_Labels, Switch_Statements); Append_Node_To_List (N, Unmarshall_Alternatives); end if; F := Next_Node (F); end loop; end if; end Visit_Thread_Instance; end Source_File; end Ocarina.Generators.PO_HI_C.Marshallers;