---------------------------------------- ---------------------------------------- -- -- -- 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;