implementation module encode_dynamic; // control-layer // StdEnv import StdEnv; // Linker import ProcessSerialNumber; import DLState; import UnknownModuleOrSymbol; import DebugUtilities; import dynamics; import dus_label; import pdObjectToMem; import link_library_instance; import link_switches; import check_types; from decode_dynamic import convert_encoded_type_reference_to_rt_type_reference_LibRef, convert_encoded_type_reference_to_rt_type_reference_LibraryInstanceTypeReference, class convert_encoded_type_reference_to_rt_type_reference, instance convert_encoded_type_reference_to_rt_type_reference LibRef, instance convert_encoded_type_reference_to_rt_type_reference LibraryInstanceTypeReference; from type_io_common import FunctionTypeConstructorAsString; from type_io_read import instance == LibraryInstanceTypeReference; // import ExtArray; import ExtInt; import ExtFile; import DynID; import directory_structure; // Compiler import utilities; from type_io_common import get_type_name_and_module_name_from_type_string, isPredefinedModuleName, LowLevelInterfaceModule; // StdDynamicEnv from DynamicLinkerInterface import ::RunTimeIDW(..), instance EnDecode RunTimeIDW, instance DefaultElem RunTimeIDW, ::LazyDynamicReference(..), instance EnDecode LazyDynamicReference, instance DefaultElem LazyDynamicReference; // get address of the graph to string function //GetGraphToStringFunction :: !ProcessSerialNumber [String] !*DLServerState !(IOState !*DLServerState) -> !(!Bool,!ProcessSerialNumber,!*DLServerState, !(IOState !*DLServerState)); GetGraphToStringFunction :: !ProcessSerialNumber [String] !*DLServerState !*f -> !(!Bool,!ProcessSerialNumber,!*DLServerState, !*f) | FileSystem, FileEnv f; GetGraphToStringFunction client_id [label_names_encoded_in_msg] s io #! (client_exists,dl_client_state,s) = RemoveFromDLServerState client_id s; | F "GetGraphToStringFunction" not client_exists = internal_error "GetGraphToStringFunction (internal error): client not registered" client_id dl_client_state s io; #! (dl_client_state) = AddMessage (Verbose "GetGraphToStringFunction") dl_client_state; #! (l,graph_to_string,dl_client_state,s,io) = case True of { True // The conversion-functions are shared among all library instances. The Clean-data structures used within // these functions may only have a single implementation. #! ({tafge_version=latest_version,tafge_conversion},tfge_index,dl_client_state) = get_from_graph_function_address2 Nothing dl_client_state; | isJust tafge_conversion // conversion-functions have already been linked. Re-use these functions #! (dlink_dir,s) = GetDynamicLinkerDirectory s; #! module_name = dlink_dir +++ "\\" +++ copy_graph_to_string +++ "_" +++ (toFileNameSubString latest_version) +++ ".obj"; #! symbol_name = "e____SystemDynamic__d" +++ copy__graph__to__string +++ "__" +++ toFileNameSubString latest_version; #! graph_to_string = [ModuleUnknown module_name symbol_name]; -> ([fromJust tafge_conversion],graph_to_string,dl_client_state,s,io); #! (dlink_dir,s) = GetDynamicLinkerDirectory s; #! module_name = dlink_dir +++ "\\" +++ copy_graph_to_string +++ "_" +++ (toFileNameSubString latest_version) +++ ".obj"; #! symbol_name = "e____SystemDynamic__d" +++ copy__graph__to__string +++ "__" +++ toFileNameSubString latest_version; #! graph_to_string = [ModuleUnknown module_name symbol_name]; #! (Just main_library_instance_i,dl_client_state) = dl_client_state!cs_main_library_instance_i; #! (dl_client_state,s,io) = add_object_module_to_library_instance module_name main_library_instance_i dl_client_state s io; #! label = { default_elem & dusl_label_name = symbol_name , dusl_linked = False , dusl_label_kind = DSL_RUNTIME_SYSTEM_LABEL }; #! (_,l,dl_client_state,io) = LoadLibraryInstance_new main_library_instance_i (Just [label]) dl_client_state io # dl_client_state = { dl_client_state & cs_to_and_from_graph.tafgt_from_graphs.[tfge_index].tafge_conversion = Just (hd l) }; -> (l,graph_to_string,dl_client_state,s,io); }; // check for errors #! (ok,dl_client_state) = IsErrorOccured dl_client_state; | not ok = (not ok,client_id,AddToDLServerState dl_client_state s,io); // DLClientState # (cs_n_lazy_dynamics,dl_client_state) = dl_client_state!cs_n_lazy_dynamics; # (msg,dl_client_state) = build_range_table dl_client_state; # encoded_l = EncodeClientMessage l +++ msg +++ FromIntToString cs_n_lazy_dynamics; # io = SendAddressToClient client_id encoded_l io; //abort "ok"; // verbose #! dl_client_state = SetLinkerMessages (produce_verbose_output graph_to_string l []) dl_client_state; = (not ok,client_id,AddToDLServerState dl_client_state s,io); // ... copy of AddDescriptors where { build_range_table dl_client_state=:{cs_library_instances={lis_n_library_instances}} # (range_entries,dl_client_state) = loopAst build_range_entry3 ([],dl_client_state) lis_n_library_instances; # range_entries = { range_entry \\ range_entry <- range_entries }; # n_sections = size range_entries; # range_id = { rid_n_range_id_entries = n_sections , rid_n_type_tables = /* RTID_LIBRARY_INSTANCE_ID_START + */ lis_n_library_instances , rid_range_entries = range_entries }; // rid_n_type_tables is indexed by run-time ids at run-time = (toString range_id,dl_client_state); where { build_range_entry3 library_instance_i (range_entries,dl_client_state) # (li_memory_areas,dl_client_state) = dl_client_state!cs_library_instances.lis_library_instances.[library_instance_i].li_memory_areas; # range_entries = foldSt add_range_entry li_memory_areas range_entries; = (range_entries,dl_client_state); where { add_range_entry {ma_begin,ma_end} range_entries # range_id_entry = { default_range_id_entry & ride_begin_address = ma_begin , ride_end_address = ma_end , ride_type_table_i = library_instance_i }; = [range_id_entry:range_entries]; }; }; }; :: *DynamicInfoOutput = { // Libraries dio_n_library_instances :: !Int // size dio_library_instance_to_library_index , dio_library_instance_to_library_index :: !*{#LibraryInstanceToLibraryIndexInfo} // indexed by a RunTimeID, index in di_library_index_to_library_name , dio_library_index_to_library_name :: !{#{#Char}} // indexed by index from above array, string reference to {code,type}-library // reflects situation in encoded dynamic , dio_used_library_instances :: !{LibraryInstance1} // maps rt-library instance index to encoded {non_lazy,lazy}-library instance index, if possible // Lazy dynamics , dio_lazy_dynamics :: !{#LazyDiskDynamicInfo} // Type equations , dio_type_equivalence_classes :: !{#{LibraryInstanceTypeReference}} //!{DiskTypeEquivalentClass} , dio_convert_rt_type_equivalence_class :: !{Maybe !Int} // indexed by type_ref from type equivalent class and delivers index in dio_type_equivalence_classes // Type redirection table , dio_type_redirection_table :: !{LibraryInstanceTypeReference} }; :: LibraryInstance1 = UnusedLibraryInstance | UsedLibraryInstance !Int // (non-lazy in encoded dynamic) disk_library_instance_i, means that at least some code from that library has been linked in | LazyLibraryInstance !Int !Int // (lazy in encoded dynamic) lazy_dynamic_index disk_library_instance_i ; isUsedLibraryInstance (UsedLibraryInstance _) = True; isUsedLibraryInstance (UsedLibraryInstance _) = False; :: LazyDiskDynamicInfo = { ldi_runtime_id :: !Int , ldi_name :: !String }; instance DefaultElem LazyDiskDynamicInfo where { default_elem = { ldi_runtime_id = default_elem , ldi_name = default_elem }; }; :: LibraryInstanceToLibraryIndexInfo = { litlii_kind :: !LibraryInstanceKind , litlii_index_in_di_library_index_to_library_name :: !Int , litlii_used_by_code :: !Bool , litlii_used_by_type :: !Bool // Just _ = iff litlii_used_by_type == True and litlii_used_by_code == False // Nothing = otherwise , litlii_reference_to_library_instance_in_lazy_dynamic :: !Maybe !LibraryReference }; instance DefaultElem LibraryInstanceToLibraryIndexInfo where { default_elem = { litlii_kind = LIK_Empty , litlii_index_in_di_library_index_to_library_name = 0 , litlii_used_by_code = False , litlii_used_by_type = False , litlii_reference_to_library_instance_in_lazy_dynamic = Nothing }; }; isLazyLibraryInstanceIndex :: LibraryInstanceToLibraryIndexInfo -> !Bool; isLazyLibraryInstanceIndex {litlii_used_by_code=False,litlii_used_by_type=True,litlii_reference_to_library_instance_in_lazy_dynamic=Just _} = True; isLazyLibraryInstanceIndex _ //{litlii_used_by_code=True} = False; :: LibraryReference = { lr_library_instance_i :: !Int // disk library instance index w.r.t. lazy dynamic lr_dynamic_index_i , lr_dynamic_index_i :: !Int // w.r.t. main dynamic }; instance == LibraryReference where { (==) {lr_library_instance_i=lr_library_instance_i1,lr_dynamic_index_i=lr_dynamic_index_i1} {lr_library_instance_i,lr_dynamic_index_i} = lr_library_instance_i1 == lr_library_instance_i && lr_dynamic_index_i1 == lr_dynamic_index_i; }; instance DefaultElem LibraryReference where { default_elem = { lr_library_instance_i = 0 , lr_dynamic_index_i = 0 }; }; :: DynamicInfoInput = { dii_library_instances_a :: {Maybe !LibraryInstanceInfo} // used run-time library instances , dii_lazy_dynamic_references :: !{#LazyDynamicReference} // used lazy dynamic by main dynamic , dii_run_time_ids :: !{#RunTimeIDW} // references to types in type component }; :: LibraryInstanceInfo = { lii_used_by_code :: !Bool , lii_used_by_type :: !Bool , lii_encoded_library_instance :: !Int // assigned disk id for the run-time library instance }; instance DefaultElem LibraryInstanceInfo where { default_elem = { lii_used_by_code = False , lii_used_by_type = False , lii_encoded_library_instance = -1 }; }; instance DefaultElemU DynamicInfoOutput where { default_elemU = { // Libraries dio_n_library_instances = 0 , dio_library_instance_to_library_index = {} , dio_library_index_to_library_name = {} , dio_used_library_instances = {} // Lazy dynamics , dio_lazy_dynamics = {} // Type equations , dio_type_equivalence_classes = {} , dio_convert_rt_type_equivalence_class = {} // Type redirection table , dio_type_redirection_table = {} }; }; :: *EliminateLazyReferencesState = { elrs_predefined_library_instance :: !Int // diskID , elrs_library_instance_to_library_index_index :: !*{#LibraryInstanceToLibraryIndexInfo} , elrs_library_index_to_library_name :: !*{#{#Char}} }; TempFunc dii dio dl_client_state io # (dio,dl_client_state) = determine_references_to_a_library_instance_of_a_lazy_dynamic dii dio dl_client_state; # (dio,dl_client_state,io) = determine_references_to_type_implementation dii dio dl_client_state io; = (dio,dl_client_state,io); // send to get extra dynamic rts information GetDynamicRTSInfo :: !ProcessSerialNumber [String] !*DLServerState !*f -> !(!Bool,!ProcessSerialNumber,!*DLServerState, !*f) | FileSystem, FileEnv f; GetDynamicRTSInfo client_id [arg] s io #! (client_exists,dl_client_state,s) = RemoveFromDLServerState client_id s; | F "GetDynamicRTSInfo" not client_exists = internal_error "GetDynamicRTSInfo (internal error): client not registered" client_id dl_client_state s io; #! (dl_client_state) = AddMessage (Verbose "GetDynamicRTSInfo") dl_client_state; # dii = decode_arg_block arg; # (dio,dl_client_state) = determine_used_lazy_dynamics dii default_elemU dl_client_state; # (dio,dl_client_state) = determine_used_libraries dii dio dl_client_state; // pass: // 1. # (dio,dl_client_state,io) = determine_used_type_equations dii dio dl_client_state io; // # (dio,dl_client_state) // = determine_references_to_a_library_instance_of_a_lazy_dynamic dii dio dl_client_state; # (dio,dl_client_state,io) = COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES (redirect_type_reference dii dio dl_client_state io) (TempFunc dii dio dl_client_state io) ; /* # (dio,dl_client_state) = determine_references_to_a_library_instance_of_a_lazy_dynamic dii dio dl_client_state; # (dio,dl_client_state,io) = determine_references_to_type_implementation dii dio dl_client_state io; */ // ----------------------------------------------- // UITPAKKEN #! (lazy_dynamics_a,dio) = dio!dio_lazy_dynamics; #! (di_disk_type_equivalent_classes,dio) = dio!dio_type_equivalence_classes; #! (library_instance_to_library_index_a,dio) = get dio; #! (library_index_to_library_name_a,dio) = dio!dio_library_index_to_library_name; #! (dio_type_redirection_table,dio) = dio!dio_type_redirection_table; #! di = { default_dynamic_info & di_library_instance_to_library_index = { convert_litlii_to_library_instance_kind library_instance \\ library_instance <-: library_instance_to_library_index_a } // LIBRARY INSTANCE TABLE , di_library_index_to_library_name = if IS_NORMAL_FILE_IDENTIFICATION library_index_to_library_name_a // LIBRARY STRING TABLE { extract_dynamic_or_library_identification library_name \\ library_name <-: library_index_to_library_name_a } , di_disk_type_equivalent_classes = di_disk_type_equivalent_classes , di_lazy_dynamics_a = { (FILE_IDENTIFICATION extract_dynamic_or_library_identification ldi_name) ldi_name \\ {ldi_name} <-: lazy_dynamics_a } , di_type_redirection_table = dio_type_redirection_table }; #! io = SendAddressToClient client_id (encode di) io; # ok = True = (not ok,client_id,AddToDLServerState dl_client_state s,/*KillClient3 client_id ok*/ io); where { get dio=:{dio_library_instance_to_library_index} = (dio_library_instance_to_library_index,{dio & dio_library_instance_to_library_index = {} }); convert_litlii_to_library_instance_kind {litlii_kind=LIK_LibraryRedirection disk_library_instance_i} = ALLOW_LIBRARY_REDIRECTIONS (LIK_LibraryRedirection disk_library_instance_i) (abort "library redirections are incorrectly implemented") ; convert_litlii_to_library_instance_kind litlii=:{litlii_index_in_di_library_index_to_library_name,litlii_reference_to_library_instance_in_lazy_dynamic} | isLazyLibraryInstanceIndex litlii # {lr_library_instance_i,lr_dynamic_index_i} = fromJust litlii_reference_to_library_instance_in_lazy_dynamic; # lik_lazy_library_instance = { LIK_LazyLibraryInstance | lik_index_in_di_library_index_to_library_name = litlii_index_in_di_library_index_to_library_name , lik_library_instance_i = lr_library_instance_i , lik_dynamic_index_i = lr_dynamic_index_i }; = LIK_LazyLibraryInstance lik_lazy_library_instance; # lik_library_instance = { LIK_LibraryInstance | lik_index_in_di_library_index_to_library_name = litlii_index_in_di_library_index_to_library_name}; = LIK_LibraryInstance lik_library_instance; decode_arg_block :: !String -> !DynamicInfoInput; decode_arg_block arg_block # (library_instances_a,j) = help_type_checker2 (from_string 0 arg_block); /// maps diskids to library_instances # library_instances_a = q { if (x == ~1) Nothing (Just { default_elem & lii_used_by_code = IS_CODE_LIBRARY_INSTANCE x , lii_used_by_type = IS_TYPE_LIBRARY_INSTANCE x , lii_encoded_library_instance = GET_LIBRARY_INSTANCE_I x }) \\ x <-: library_instances_a }; # (lazy_dynamic_references,k) = (from_string j arg_block); # (run_time_ids,l) = /*help_type_checker3*/ (from_string k arg_block); // # run_time_ids // = { runtime_id_w \\ runtime_id_w=:{rtid_type_string} <-: run_time_ids | rtid_type_string <> FunctionTypeConstructorAsString}; # dii = { dii_library_instances_a = library_instances_a , dii_lazy_dynamic_references = lazy_dynamic_references , dii_run_time_ids = run_time_ids }; = dii; where { help_type_checker2 :: (!{#Int},!Int) -> (!{#Int},!Int); help_type_checker2 i = i; help_type_checker3 :: (!{#RunTimeIDW},!Int) -> (!{#RunTimeIDW},!Int); help_type_checker3 i = i; q :: !*{Maybe LibraryInstanceInfo} -> !*{Maybe LibraryInstanceInfo}; q i = i; }; } // The build_block rt_lazy_dynamic id (defined in _SystemDynamic) have been collected in the LazyDynamicReferences-array by the // conversion function. This functions puts them into a list. determine_used_lazy_dynamics :: !DynamicInfoInput !*DynamicInfoOutput !*DLClientState -> (!*DynamicInfoOutput,!*DLClientState); determine_used_lazy_dynamics dii=:{dii_lazy_dynamic_references=lazy_dynamic_references} dio dl_client_state // determine used lazy dynamics # max_lazy_dynamic_index = mapASt (\{ldr_lazy_dynamic_index} accu -> max ldr_lazy_dynamic_index accu) lazy_dynamic_references (-1); # n_lazy_dynamics = inc max_lazy_dynamic_index; # lazy_dynamics_a = createArray n_lazy_dynamics default_elem; # (lazy_dynamics_a,dl_client_state) = mapASt collect_lazy_dynamic_reference lazy_dynamic_references (lazy_dynamics_a,dl_client_state); # dio = { dio & dio_lazy_dynamics = lazy_dynamics_a }; = (dio,dl_client_state); where { collect_lazy_dynamic_reference {ldr_id,ldr_lazy_dynamic_index} (lazy_dynamics_a,dl_client_state) #! (di_file_name,dl_client_state) = dl_client_state!cs_dynamic_info.[ldr_id].di_file_name; #! lazy_dynamics_a = { lazy_dynamics_a & [ldr_lazy_dynamic_index] = { ldi_runtime_id = ldr_id, ldi_name = di_file_name } }; = (lazy_dynamics_a,dl_client_state); }; determine_used_libraries :: !DynamicInfoInput !*DynamicInfoOutput !*DLClientState -> (!*DynamicInfoOutput,!*DLClientState); determine_used_libraries dii=:{dii_library_instances_a=library_instances_a,dii_lazy_dynamic_references=lazy_dynamic_references} dio dl_client_state // create library used # (n_type_tables,dl_client_state) = get_number_of_type_tables dl_client_state; # library_used = createArray n_type_tables False; // determine used type and code libraries # (library_instance_max_index,_,n_libraries_used,dl_client_state) = mapAiSt compute_amount_of_libraries_and_instance_used library_instances_a (0,library_used,0,dl_client_state); # n_library_instances = inc library_instance_max_index; // maps a type_table_i to its index in library_name_a (temp) # library_name_indices = createArray n_type_tables Nothing; // maps a library instance to its library name; LIBRARY INSTANCE TABLE # library_instance_to_library_index_a = createArray n_library_instances default_elem; // indexed by an element from library_instance_to_library_name_a to a library name; LIBRARY STRING TABLE # library_index_to_library_name_a = { "" \\ _ <- [1..n_libraries_used] }; // fill LIBRARY INSTANCE TABLE and LIBRARY STRING TABLE # (_,library_instance_to_library_index_a,library_index_to_library_name_a,_,dl_client_state) = mapAiSt (fill_library_arrays n_libraries_used) library_instances_a (library_name_indices,library_instance_to_library_index_a,library_index_to_library_name_a,0,dl_client_state); // ----------------------------------------------- // Store type equations for all library instances involved // library_instances_a contains the used library instances for the new dynamic being created. Type equations must // be inserted before the first block of the new dynamic will be demanded. These equations are called *eager* type // equations. // # (lis_n_library_instances,dl_client_state) = dl_client_state!cs_library_instances.lis_n_library_instances; // Auxillary array which maps *used* library instances used in the main dynamic i.e. the dynamic being created to encoded // library instances. There are two kinds of library instances: library instances in the main dynamic and library instances // relative to a lazy dynamic of the main dynamic. The algorithm reflects this fact by also creating the array in two steps. // step 1: collect the library instances directly used by the main dynamic #! used_library_instances = createArray lis_n_library_instances UnusedLibraryInstance; #! (used_library_instances,dl_client_state) = mapAiSt determine_the_used_library_instances_of_main_dynamic library_instances_a (used_library_instances,dl_client_state); // step 2: collect the used library instances of lazy dynamics which are used by the main dynamic #! (used_library_instances,dl_client_state) = mapASt determine_the_used_library_instances_within_the_lazy_dynamics_of_the_main_dynamic lazy_dynamic_references (used_library_instances,dl_client_state) # dio = { dio & dio_n_library_instances = n_library_instances , dio_library_instance_to_library_index = library_instance_to_library_index_a , dio_library_index_to_library_name = library_index_to_library_name_a , dio_used_library_instances = used_library_instances }; = (dio,dl_client_state); where { // computes from the library instances which physical libraries are being used. A physical library occurs at most once // in the LIBRARY STRING TABLE. compute_amount_of_libraries_and_instance_used :: !Int !(Maybe !LibraryInstanceInfo) !*(!Int,*{#Bool},!Int,!*DLClientState) -> *(!Int,*{#Bool},!Int,!*DLClientState); compute_amount_of_libraries_and_instance_used library_instance_i (Just {lii_encoded_library_instance=library_instance_i_non_runtime_index}) s=:(library_instance_max_index,library_used,n_libraries_used,dl_client_state) // library_instance_i_non_runtime_index | library_instance_i < RTID_LIBRARY_INSTANCE_ID_START // || library_instance_i_non_runtime_index == TTUT_UNUSED = s; // compute maximum library *instance* index # library_instance_max_index = max library_instance_max_index library_instance_i_non_runtime_index; // WASlibrary_instance_i; // get type table for current library instance # (type_table_i,dl_client_state) = dl_client_state!cs_library_instances.lis_library_instances.[library_instance_i].li_type_table_i; | library_used.[type_table_i] = (library_instance_max_index,library_used,/* WAS inc*/ n_libraries_used,dl_client_state); # library_used = { library_used & [type_table_i] = True }; = (library_instance_max_index,library_used,inc n_libraries_used,dl_client_state); compute_amount_of_libraries_and_instance_used _ _ s = s; // computes the LIBRARY INSTANCE TABLE in library_instance_to_library_index_a and the LIBRARY STRING TABLE in // library_index_to_library_name_a. // library_instance_i_non_runtime_index fill_library_arrays :: !Int !Int !(Maybe !LibraryInstanceInfo) *(*{Maybe !Int},*{#LibraryInstanceToLibraryIndexInfo},*{#String},.Int,*DLClientState) -> *(*{Maybe Int},*{#LibraryInstanceToLibraryIndexInfo},*{#String},Int,*DLClientState); fill_library_arrays n_libraries_used library_instance_i (Just {lii_used_by_code,lii_used_by_type,lii_encoded_library_instance=library_instance_i_non_runtime_index}) s=:(library_name_indices,library_instance_to_library_index_a,library_index_to_library_name_a,free_library_index_to_library_name_index,dl_client_state) | library_instance_i < RTID_LIBRARY_INSTANCE_ID_START = s; // get type table for current library instance # (type_table_i,dl_client_state) = dl_client_state!cs_library_instances.lis_library_instances.[library_instance_i].li_type_table_i; | isNothing library_name_indices.[type_table_i] // fill library_instance_to_library_index_a with index in library_index_to_library_name_a # library_instance_to_library_index_a = { library_instance_to_library_index_a & [library_instance_i_non_runtime_index] = {default_elem & litlii_index_in_di_library_index_to_library_name = free_library_index_to_library_name_index , litlii_used_by_code = lii_used_by_code , litlii_used_by_type = lii_used_by_type } }; // fill library_index_to_library_name_a # (li_library_name,dl_client_state) = dl_client_state!cs_library_instances.lis_library_instances.[library_instance_i].li_library_name; # library_index_to_library_name_a = { library_index_to_library_name_a & [free_library_index_to_library_name_index] = fromJust li_library_name }; // # library_name_indices = { library_name_indices & [type_table_i] = Just free_library_index_to_library_name_index }; // # free_library_index_to_library_name_index = inc free_library_index_to_library_name_index; = (library_name_indices,library_instance_to_library_index_a,library_index_to_library_name_a,free_library_index_to_library_name_index,dl_client_state) # library_index_to_library_name = fromJust library_name_indices.[type_table_i]; // fill library_instance_to_library_index_a with index in library_index_to_library_name_a # library_instance_to_library_index_a = { library_instance_to_library_index_a & [library_instance_i_non_runtime_index] = {default_elem & litlii_index_in_di_library_index_to_library_name = free_library_index_to_library_name_index , litlii_used_by_code = lii_used_by_code , litlii_used_by_type = lii_used_by_type } }; = (library_name_indices,library_instance_to_library_index_a,library_index_to_library_name_a,free_library_index_to_library_name_index,dl_client_state); fill_library_arrays _ _ _ s = s; // collect used library *code* instances in a set // library_instance_i_non_runtime_index2 determine_the_used_library_instances_of_main_dynamic :: .Int !(Maybe .LibraryInstanceInfo) !*(*{LibraryInstance1},!*DLClientState) -> (*{LibraryInstance1},!*DLClientState); determine_the_used_library_instances_of_main_dynamic library_instance_i (Just {lii_used_by_code=True,lii_encoded_library_instance=library_instance_i_non_runtime_index}) (used_library_instances,dl_client_state) | library_instance_i < RTID_LIBRARY_INSTANCE_ID_START = (used_library_instances,dl_client_state); #! used_library_instances = { used_library_instances & [library_instance_i] = UsedLibraryInstance library_instance_i_non_runtime_index }; = (used_library_instances,dl_client_state); determine_the_used_library_instances_of_main_dynamic _ _ s = s; // rt_dynamic_id -> set of library ids -> set of currently *used* library ids // mark UnusedLibrary instance reachable from the set of lazy dynamics as LazyLibraryInstance // what about if it was a UsedLibraryInstance? determine_the_used_library_instances_within_the_lazy_dynamics_of_the_main_dynamic :: !.LazyDynamicReference !*(*{LibraryInstance1},!*DLClientState) -> *(*{LibraryInstance1},*DLClientState); determine_the_used_library_instances_within_the_lazy_dynamics_of_the_main_dynamic {ldr_id,ldr_lazy_dynamic_index} (used_library_instances,dl_client_state) #! (di_disk_id_to_library_instance_i,dl_client_state) = dl_client_state!cs_dynamic_info.[ldr_id].di_disk_id_to_library_instance_i; #! used_library_instances = mapAiSt determine_the_used_library_instances_within_a_lazy_dynamic di_disk_id_to_library_instance_i used_library_instances; = (used_library_instances,dl_client_state); where { determine_the_used_library_instances_within_a_lazy_dynamic disk_library_instance_i library_instance_i used_library_instances | disk_library_instance_i < RTID_DISKID_RENUMBER_START || library_instance_i == TTUT_UNUSED = used_library_instances; | LLI_IS_LAZY_LIBRARY_INSTANCE library_instance_i = used_library_instances; //abort "determine_the_used_library_instances_within_a_lazy_dynamic: (unimplemented) lazy type reference detected which cannot yet be handled"; #! (kind,used_library_instances) = used_library_instances![library_instance_i]; #! used_library_instances = case kind of { UnusedLibraryInstance #! used_library_instances = { used_library_instances & [library_instance_i] = LazyLibraryInstance ldr_lazy_dynamic_index disk_library_instance_i }; -> used_library_instances; UsedLibraryInstance _ -> abort "determine_the_used_library_instances_within_a_lazy_dynamic: internal error; partially used dynamics are not yet supported"; _ // Library instance has already been used. If it is used by an UsedLibraryInstance, // then the dynamic being constructed uses an already constructed block i.e. a block // without build_block of another dynamic and at least some build_blocks. Because at // least one block has been included in the new dynamic, all the disk library instances // have been converted to run-time library instances: there is no need for lazy type // equations. -> used_library_instances; }; = used_library_instances; }; }; determine_used_type_equations :: !DynamicInfoInput !*DynamicInfoOutput !*DLClientState !*f -> (!*DynamicInfoOutput,!*DLClientState,!*f) | FileEnv f; determine_used_type_equations dii=:{dii_lazy_dynamic_references} dio=:{dio_lazy_dynamics,dio_used_library_instances=used_library_instances,dio_library_index_to_library_name} dl_client_state io // Compute the type equations to be stored in the dynamic. The fixed avalailable types are skipped because they // are automatically inserted each time a new library is added. #! ( n_fixed_available_types,dl_client_state) = dl_client_state!cs_n_fixed_available_types; #! (n_type_equivalent_classes,dl_client_state) = dl_client_state!cs_type_implementation_table.teit_n_type_implementations #! n_fixed_available_types = if (isNothing n_fixed_available_types) 0 (fromJust n_fixed_available_types); #! dio_convert_rt_type_equivalence_class = createArray n_type_equivalent_classes Nothing; #! (_,di_disk_type_equivalent_classes,dio_convert_rt_type_equivalence_class,dl_client_state,dio,io) = foldSt collect_type_equation [n_fixed_available_types..(dec n_type_equivalent_classes)] (0,[],dio_convert_rt_type_equivalence_class,dl_client_state,dio,io) # dio = { dio & // type equations dio_type_equivalence_classes = { { t \\ t <- reverse x } \\ x <- di_disk_type_equivalent_classes } , dio_convert_rt_type_equivalence_class = dio_convert_rt_type_equivalence_class }; = (dio,dl_client_state,io); where { collect_type_equation type_implementation_table_ref s=:(i,collected_type_equations,dio_convert_rt_type_equivalence_class,dl_client_state,dio,io) #! (tei_type_implementations,dl_client_state) = dl_client_state!cs_type_implementation_table.teit_type_implementations_a.[type_implementation_table_ref].tei_type_implementations; #! (converted,dio,dl_client_state,io) = foldSt filter_type_implementations tei_type_implementations ([],dio,dl_client_state,io); | length converted < 2 = (i,collected_type_equations,dio_convert_rt_type_equivalence_class,dl_client_state,dio,io); # dio_convert_rt_type_equivalence_class = { dio_convert_rt_type_equivalence_class & [type_implementation_table_ref] = Just i }; = (inc i,[converted:collected_type_equations],dio_convert_rt_type_equivalence_class,dl_client_state,dio,io); where { filter_type_implementations t (list,dio,dl_client_state,io) #! (maybe_encoded_type_reference,dio,dl_client_state,io) = convert_rt_type_reference_to_encoded_type_reference t dii dio dl_client_state io; #! list = if (isNothing maybe_encoded_type_reference) list // ignore, type reference will not appear in encoded dynamic [fromJust maybe_encoded_type_reference:list] // encoded type reference ; = (list,dio,dl_client_state,io); }; }; determine_references_to_a_library_instance_of_a_lazy_dynamic dii=:{dii_library_instances_a=library_instances_a,dii_lazy_dynamic_references=lazy_dynamic_references} dio=:{dio_n_library_instances=n_library_instances,dio_library_instance_to_library_index=library_instance_to_library_index_a} dl_client_state // A type is represented at run-time by the T_ypeObjectType-type from _SystemDynamic. A type consists of a name, a module_name // and reference to a library instance represented by the RunTimeID-constructor. This constructor has a single argument: a // reference to a library instance. A library instance contains among other things: // - reference to type library i.e. type definition table // - reference to code library i.e. code // // If the library instance is going to be part of the dynamic being created, then that instance provides both the type definition // and its implementation. In this case the library instance is being used by code and by type. // // Otherwise the library instance is used only by type and it can be provided by a lazy dynamic later. This can be encoded by using // the following tuple: // - library instance within that lazy dynamic // - lazy dynamic index w.r.t. the main dynamic // #! (library_instance_to_library_index_a,dl_client_state) = mapAiSt (collect_references_to_a_library_instance_within_a_lazy_dynamic lazy_dynamic_references) library_instances_a (library_instance_to_library_index_a,dl_client_state); #! dio = { dio & dio_library_instance_to_library_index = library_instance_to_library_index_a }; = (dio,dl_client_state); where { // A library instance can be referenced as: // 1. a library instance number in the main dynamic // 2. a library instance number w.r.t. its lazy dynamic number (within the main dynamic) collect_references_to_a_library_instance_within_a_lazy_dynamic :: !{#LazyDynamicReference} !Int !(Maybe LibraryInstanceInfo) (*{#LibraryInstanceToLibraryIndexInfo},!*DLClientState) -> (*{#LibraryInstanceToLibraryIndexInfo},!*DLClientState); collect_references_to_a_library_instance_within_a_lazy_dynamic lazy_dynamic_references rt_library_instance_i (Just {lii_used_by_code=False,lii_used_by_type=True,lii_encoded_library_instance}) (library_instance_to_library_index_a,dl_client_state) // rt_library_instance_i = ith run-time library instance // lii_encoded_library_instance = ith disk library instance in main dynamic (assigned by conversion functions) // Determine to what dynamic, the rt_library_instance_i is associated. The pattern below must always succeed // because all library instances but the main library instance. The result is the run-time lazy dynamic id. #! (Just rt_lazy_dynamic_index,dl_client_state) = dl_client_state!cs_library_instances.lis_library_instances.[rt_library_instance_i].li_dynamic_index; // Determine the disk lazy dynamic id recorded in lazy_dynamic_references-array. If the run-time lazy dynamic index // (rt_lazy_dynamic_index) equals the ldr_id-field, then the ldr_lazy_dynamic_index-field gives the by the graph_to // _string-conversion function assigned disk lazy dynamic index. #! r = findAi (determine_disk_lazy_dynamic_index rt_lazy_dynamic_index) lazy_dynamic_references; | isNothing r // For the time being it is assumed that a lazy type reference always refers to some // type table in a lazy dynamic. This need probably not be so. = abort "!collect_references_to_a_library_instance_within_a_lazy_dynamic: internal error; lazy type references which does not reference to a type table in a lazy dynamic"; // determine library instance on disk #! (di_disk_id_to_library_instance_i,dl_client_state) = dl_client_state!cs_dynamic_info.[rt_lazy_dynamic_index].di_disk_id_to_library_instance_i; #! maybe_disk_library_instance_i = findAi determine_disk_library_instance_i di_disk_id_to_library_instance_i | isNothing maybe_disk_library_instance_i // For the time being it is assumed that each disk_library_instance is mapped onto a (valid) // run-time library instance. = abort "collect_references_to_a_library_instance_within_a_lazy_dynamic; internal error"; #! lr = { default_elem & lr_library_instance_i = fromJust maybe_disk_library_instance_i , lr_dynamic_index_i = fromJust r }; #! library_instance_to_library_index_a = { library_instance_to_library_index_a & [lii_encoded_library_instance].litlii_reference_to_library_instance_in_lazy_dynamic = Just lr }; = (library_instance_to_library_index_a,dl_client_state) where { determine_disk_lazy_dynamic_index rt_lazy_dynamic_index _ {ldr_id,ldr_lazy_dynamic_index} | ldr_id == rt_lazy_dynamic_index = Just ldr_lazy_dynamic_index; = Nothing; determine_disk_library_instance_i disk_library_instance_j rt_library_instance_j | rt_library_instance_i == rt_library_instance_j = Just disk_library_instance_j; = Nothing; }; collect_references_to_a_library_instance_within_a_lazy_dynamic _ rt_library_instance_i x s // The library instance is unused (x=:Nothing) by the main dynamic or at least used by code (x=:Just _) of the main // dynamic. The former is ignored because it doesn't reappear in the dynamic. The latter means that if there is a // reference from the type component of the main dynamic, then . = s; }; // only those references in types whose library instances have not yet been linked in. determine_references_to_type_implementation dii=:{dii_library_instances_a=library_instances_a,dii_lazy_dynamic_references=lazy_dynamic_references,dii_run_time_ids=run_time_ids} dio=:{dio_library_index_to_library_name,dio_convert_rt_type_equivalence_class,dio_type_equivalence_classes} dl_client_state io #! (dio_library_instance_to_library_index,dio) = getQ dio; // Find an arbitrary library instance whose code is used because each library instance can implement the // predefined types. This library instance exists always because there always some code needed to use a // dynamic (except for a data dynamic). # (r,dio_library_instance_to_library_index) = findAieu find_code_library_instance dio_library_instance_to_library_index; | isNothing r = abort "try_to_eliminate_lazy_references_in_types; internal error; the code of at least one library instance should be used by the dynamic being encoded"; // bezig met elrs toevoegen aan de map #! elrs = { elrs_predefined_library_instance = fromJust r , elrs_library_instance_to_library_index_index = dio_library_instance_to_library_index //{ x \\ x <-: dio_library_instance_to_library_index } , elrs_library_index_to_library_name = { x \\ x <-: dio_library_index_to_library_name } }; # (library_instances_a,elrs,dio,dl_client_state,io) = mapASt try_to_eliminate_lazy_reference run_time_ids (library_instances_a,elrs,dio,dl_client_state,io) # ({elrs_library_instance_to_library_index_index,elrs_library_index_to_library_name}) = elrs; # dio = { dio & dio_library_instance_to_library_index = elrs_library_instance_to_library_index_index , dio_library_index_to_library_name = elrs_library_index_to_library_name// { x \\ x <-: elrs_library_index_to_library_name } }; = (dio,dl_client_state,io); where { find_code_library_instance i {litlii_used_by_code=True} | i < RTID_DISKID_RENUMBER_START = Nothing; = Just i; find_code_library_instance _ _ = Nothing; try_to_eliminate_lazy_reference x=:{rtid_runtime_id=library_instance_i,rtid_type_string,rtid_assigned_disk_id} s=:(library_instances_a,elrs=:{elrs_predefined_library_instance},dio,dl_client_state,io) | ALLOW_LAZY_LIBRARY_REFERENCES False True = abort "try_to_eliminate_lazy_reference; lazy library references (lazy dynamic) unimplemented"; | LLI_IS_MAIN_LIBRARY_INSTANCE library_instance_i = s; //abort "process_lazy_type_references; internal error; type reference should be lazy"; #! (type_name,module_name) = get_type_name_and_module_name_from_type_string rtid_type_string; | isPredefinedModuleName module_name // predefined type are defined in the run-time system which is (of course) shared by the // library instances. # elrs = { elrs & elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_kind = LIK_LibraryRedirection elrs_predefined_library_instance , elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_used_by_type = True }; = ALLOW_LIBRARY_REDIRECTIONS (library_instances_a,elrs,dio,dl_client_state,io) (abort "library redirections are not correctly implemented") ; // non-predefined type # lazy_dynamic_index = LLI_EXTRACT_LAZY_DYNAMIC_INDEX library_instance_i; # lazy_library_instance_index = LLI_EXTRACT_LAZY_LIBRARY_INSTANCE_INDEX library_instance_i; # ({ldi_lazy_dynamic_index_to_dynamic=maybe_initialized_lazy_dynamic},dl_client_state) = dl_client_state!cs_lazy_dynamic_index_to_dynamic_id.[lazy_dynamic_index]; = try_to_eliminate_lazy_reference_to_a_nonpredefined_type maybe_initialized_lazy_dynamic type_name module_name lazy_dynamic_index lazy_library_instance_index x (library_instances_a,elrs,dio,dl_client_state,io); try_to_eliminate_lazy_reference_to_a_nonpredefined_type maybe_initialized_lazy_dynamic type_name module_name lazy_dynamic_index lazy_library_instance_index {/*rtid_runtime_id=library_instance_i,*/rtid_type_string,rtid_assigned_disk_id} (library_instances_a,elrs=:{elrs_predefined_library_instance},dio,dl_client_state,io) # (Just (disk_lazy_dynamic_index,main_dynamic_index),dl_client_state) = get_dynamic_id lazy_dynamic_index dl_client_state; // lazy(lazy_library_instance_index,disk_lazy_dynamic_index) // GOAL: type_table_i // get library instance of its main dynamic #! (di_library_instance_to_library_index,dl_client_state) = dl_client_state!cs_dynamic_info.[main_dynamic_index].di_library_instance_to_library_index; #! r = findAi (find_lazy_library_reference lazy_library_instance_index disk_lazy_dynamic_index) di_library_instance_to_library_index; | isNothing r // A library instance reference which refers to a library instance of a lazy dynamic (aka a // lazy library reference) when the dynamic was created, has been created as lazy. See also // isLazyLibraryInstanceIndex. Otherwise an internal error is reported. = abort "try_to_eliminate_lazy_reference; internal error; cannot find lazy (?,?)"; // get type table name #! library_index_to_library_name = case di_library_instance_to_library_index.[fromJust r] of { LIK_LazyLibraryInstance {LIK_LazyLibraryInstance | lik_index_in_di_library_index_to_library_name} -> lik_index_in_di_library_index_to_library_name; }; #! (library_name,dl_client_state) = dl_client_state!cs_dynamic_info.[main_dynamic_index].di_library_index_to_library_name.[library_index_to_library_name]; // allocate & load required type table # (type_table_i,dl_client_state) = AddReferenceToTypeTable library_name dl_client_state; # (dl_client_state,io) = LoadTypeTable type_table_i dl_client_state io; # (maybe_tio_type_reference,dl_client_state) = findTypeUsingTypeName type_name module_name type_table_i dl_client_state; | isNothing maybe_tio_type_reference // A type_name and module_name for the given type library must exist. Otherwise an internal // error is reported. = abort "try_to_eliminate_lazy_reference; internal error; cannot find required type"; # tio_type_reference = fromJust maybe_tio_type_reference; # (lit_type_reference,dl_client_state) = case maybe_initialized_lazy_dynamic of { Nothing # lib_ref = LibRefViaLazyDynamic lazy_library_instance_index lazy_dynamic_index type_table_i; # lit_type_reference = LIT_TypeReference lib_ref tio_type_reference; -> (lit_type_reference, dl_client_state); Just rt_dynamic_index #! (rt_library_instance,dl_client_state) = dl_client_state!cs_dynamic_info.[rt_dynamic_index].di_disk_id_to_library_instance_i.[lazy_library_instance_index]; #! lit_type_reference = LIT_TypeReference (LibRef rt_library_instance) tio_type_reference; -> (lit_type_reference,dl_client_state); }; # (found,type_ref,dl_client_state) = findImplementationType lit_type_reference dl_client_state; # maybe_disk_type_equivalent_classes_index = if (not found || isNothing type_ref) Nothing (dio_convert_rt_type_equivalence_class.[fromJust type_ref]); | isNothing maybe_disk_type_equivalent_classes_index // This alternative is taken iff // - the current type i.e. lit_type_reference is *not* a member of some type equivalent class. // - the current type is a member of some *stripped* type equivalent class. A stripped type // equivalent class is to be stored and only contains types which are relevant i.e. used by // the dynamic being created. // Create an new level of indirection by making it a LAZY-entry. #! maybe_disk_main_dynamic_index = findAi (\_ {ldr_id,ldr_lazy_dynamic_index} -> if (ldr_id == main_dynamic_index) (Just ldr_lazy_dynamic_index) Nothing) lazy_dynamic_references; | isNothing maybe_disk_main_dynamic_index // The dynamic being built does not have the required lazy dynamic which is being // referenced from its type. = abort "try_to_eliminate_lazy_reference; internal error; cannot find required lazy dynamic"; #! disk_main_dynamic_index = fromJust maybe_disk_main_dynamic_index #! (index,elrs) = get_library_index library_name elrs; # elrs = { elrs & elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_index_in_di_library_index_to_library_name = index , elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_used_by_type = True , elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_used_by_code = False , elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_reference_to_library_instance_in_lazy_dynamic = Just {lr_library_instance_i=fromJust r, lr_dynamic_index_i=disk_main_dynamic_index} }; = (library_instances_a,elrs,dio,dl_client_state,io); // There is a run-time type equivalent class with at least two types to be stored in it and the // current type is also in it. The current type can be replaced by another member of the same // (disk) type equivalent class. #! disk_type_equivalent_classes_index = fromJust maybe_disk_type_equivalent_classes_index; // select an arbitrarily type of the type equivalent class. There is no need for conversion from run-time indices to // disk indices and/or checking for the availability of library instances because it has already been done when the // type equations were collected. #! type = choose_type_from_equivalent_class dio_type_equivalence_classes.[disk_type_equivalent_classes_index]; #! (library_instances_a,elrs,dio,dl_client_state,io) = case type of { LIT_TypeReference (LibRef disk_library_instance) _ # elrs = { elrs & elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_kind = LIK_LibraryRedirection disk_library_instance , elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_used_by_type = True }; -> ALLOW_LIBRARY_REDIRECTIONS (library_instances_a,elrs,dio,dl_client_state,io) (abort "library redirections are incorrectly implemented") ; LIT_TypeReference (LibRefViaLazyDynamic disk_library_instance lazy_dynamic_index_in_main_dynamic type_library_reference) _ # elrs = { elrs & elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_index_in_di_library_index_to_library_name = type_library_reference , elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_used_by_type = True , elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_used_by_code = False , elrs_library_instance_to_library_index_index.[rtid_assigned_disk_id].litlii_reference_to_library_instance_in_lazy_dynamic = Just {lr_library_instance_i=disk_library_instance, lr_dynamic_index_i=lazy_dynamic_index_in_main_dynamic} }; -> (library_instances_a,elrs,dio,dl_client_state,io); }; = (library_instances_a,elrs,dio,dl_client_state,io); where { get_library_index library_name elrs=:{elrs_library_index_to_library_name} # (found,elrs_library_index_to_library_name) = findAieu (\i library_name2 -> if (library_name == library_name2) (Just i) Nothing) elrs_library_index_to_library_name; | isJust found # elrs = { elrs & elrs_library_index_to_library_name = elrs_library_index_to_library_name }; = (fromJust found,elrs); // include the library in table because it has not been included. #! (new_index,new) = extend_array_nu 1 elrs_library_index_to_library_name; #! new = { new & [new_index] = library_name }; # elrs = { elrs & elrs_library_index_to_library_name = new }; = (new_index,elrs); find_lazy_library_reference lazy_library_instance_index disk_lazy_dynamic i (LIK_LazyLibraryInstance { LIK_LazyLibraryInstance | lik_library_instance_i,lik_dynamic_index_i}) | lik_dynamic_index_i == disk_lazy_dynamic && lik_library_instance_i == lazy_library_instance_index = Just i; = Nothing; find_lazy_library_reference lazy_library_instance_index disk_lazy_dynamic i _ = Nothing; } getQ dio=:{dio_library_instance_to_library_index} = (dio_library_instance_to_library_index,{dio & dio_library_instance_to_library_index = {}}); }; choose_type_from_equivalent_class type_equivalent_class // A reference to a non-lazy library instance i.e. a library instance that is *not* a library in instance of // lazy dynamic within the main_dynamic is prefered to a lazy library instance. The latter imposes run-time // overhead when the dynamic is used. #! find_type = CHOOSE_TYPE_REF_IN_LIBRARY_INSTANCE_TABLE try_to_find_type_with_library_instance_in_main_dynamic try_to_find_lazy_type_ref_with_library_instance_in_main_dynamic; #! maybe_type = findAi find_type type_equivalent_class; | isJust maybe_type = fromJust maybe_type; # random_member = 0; = type_equivalent_class.[random_member]; where { try_to_find_type_with_library_instance_in_main_dynamic _ type=:(LIT_TypeReference (LibRef _) _) = Just type; try_to_find_type_with_library_instance_in_main_dynamic _ _ = Nothing; try_to_find_lazy_type_ref_with_library_instance_in_main_dynamic _ type=:(LIT_TypeReference (LibRefViaLazyDynamic _ _ _) _) = Just type; try_to_find_lazy_type_ref_with_library_instance_in_main_dynamic _ _ = Nothing; }; // ------------------------------------------------------------------------------------------------------------------------------------ :: *RedirectTypeReferenceState = { rtrs_default_library_instance_i :: !Int }; instance DefaultElemU RedirectTypeReferenceState where { default_elemU = { rtrs_default_library_instance_i = 0 }; }; //redirect_type_reference :: !.DynamicInfoInput *DynamicInfoOutput *DLClientState *a -> *(*DynamicInfoOutput,*DLClientState,*a) | FileEnv a redirect_type_reference dii=:{dii_run_time_ids} dio dl_client_state io # (default_disk_library_instance_i,dio) = find_default_library_instance dio # rtrs = { default_elemU & rtrs_default_library_instance_i = default_disk_library_instance_i }; # (encoded_type_references,(dio,dl_client_state,io,rtrs)) = real_mapAiSt convert_type_reference dii_run_time_ids (dio,dl_client_state,io,rtrs); // pas op: ->, predefined types // // 1. gebruikt binnen de te encoderen dynamic of niet (representant keuze) // 2. lazy / non-lazy // 3. lazy to non-lazy conversion when possible // // lazy entries in de library instance tabel moeten worden aangemaakt. // Momenteel komen er met het f-project te weinig type referenties uit. #! dio = { dio & dio_type_redirection_table = encoded_type_references }; = (dio,dl_client_state,io); where { // fixed: a type reference is used. // but is the right one used. convert_type_reference i {rtid_type_string,rtid_runtime_id} (dio=:{dio_used_library_instances,dio_convert_rt_type_equivalence_class,dio_type_equivalence_classes},dl_client_state,io,rtrs=:{rtrs_default_library_instance_i}) #! (type_name,module_name) = get_type_name_and_module_name_from_type_string rtid_type_string; # (lib_ref,type_reference,dl_client_state,io) = convert_T_ypeID_to_internal_type_reference_Int type_name module_name rtid_runtime_id dl_client_state io; | isTypeWithoutDefinition type_reference # type_reference = convert_to_library_instance_type_reference (LibRef rtrs_default_library_instance_i) type_reference; = (type_reference,(dio,dl_client_state,io,rtrs)); # type_reference = convert_to_library_instance_type_reference lib_ref type_reference; # (maybe_converted_type_reference,dio,dl_client_state,io) = convert_rt_type_reference_to_encoded_type_reference type_reference dii dio dl_client_state io; | is_lib_ref maybe_converted_type_reference = (fromJust maybe_converted_type_reference,(dio,dl_client_state,io,rtrs)); // type reference either lazy or non-existent # (found,type_ref,dl_client_state) = findImplementationType type_reference dl_client_state; # maybe_disk_type_equivalent_classes_index = if (not found || isNothing type_ref) Nothing (dio_convert_rt_type_equivalence_class.[fromJust type_ref]); | isNothing maybe_disk_type_equivalent_classes_index // debug: <<- ("on_disk",dio_type_equivalence_classes.[fromJust maybe_disk_type_equivalent_classes_index]) <<- ("searched: ",type_reference, "\nfound: ",found, "\nencoded classes: ",dio_convert_rt_type_equivalence_class) // no encoded type equivalent class for type type_reference. | isNothing maybe_converted_type_reference // type reference cannot be encoded = abort "redirect_type_reference; internal error; type reference cannot be encoded"; // there is no way around using the lazy type reference = (fromJust maybe_converted_type_reference,(dio,dl_client_state,io,rtrs)); // an encoded type equivalent class existss #! converted_equivalent_type = choose_type_from_equivalent_class dio_type_equivalence_classes.[fromJust maybe_disk_type_equivalent_classes_index]; // CHOOSE_TYPE_REF_IN_LIBRARY_INSTANCE_TABLE = (converted_equivalent_type,(dio,dl_client_state,io,rtrs)); where { is_lib_ref (Just (LIT_TypeReference (LibRef _) _)) = True; is_lib_ref _ = False; } // At least one library is included. Once data dynamics are supported this will not be the // case anymore. find_default_library_instance dio #! (dio_library_instance_to_library_index,dio) = getQ dio; // Find an arbitrary library instance whose code is used because each library instance can implement the // predefined types. This library instance exists always because there always some code needed to use a // dynamic (except for a data dynamic). # (r,dio_library_instance_to_library_index) = findAieu find_code_library_instance dio_library_instance_to_library_index; | isNothing r = abort "try_to_eliminate_lazy_references_in_types; internal error; the code of at least one library instance should be used by the dynamic being encoded"; #! dio = { dio & dio_library_instance_to_library_index = dio_library_instance_to_library_index }; = (fromJust r,dio); where { getQ dio=:{dio_library_instance_to_library_index} = (dio_library_instance_to_library_index,{dio & dio_library_instance_to_library_index = {}}); find_code_library_instance i {litlii_used_by_code=True} | i < RTID_DISKID_RENUMBER_START = Nothing; = Just i; find_code_library_instance _ _ = Nothing; }; }; // ------------------------------------------------------------------------------------------------------------------------- find_type_table library_name dio=:{dio_library_index_to_library_name} # (found,dio_library_index_to_library_name) = findAieu (\i library_name2 -> if (library_name == library_name2) (Just i) Nothing) dio_library_index_to_library_name; | isJust found #! dio = { dio & dio_library_index_to_library_name = dio_library_index_to_library_name }; = (fromJust found,dio); # (new_library_name_index,dio_library_index_to_library_name) = extend_array_nu 1 dio_library_index_to_library_name; # dio_library_index_to_library_name = { dio_library_index_to_library_name & [new_library_name_index] = library_name }; #! dio = { dio & dio_library_index_to_library_name = dio_library_index_to_library_name }; = (new_library_name_index,dio); find_encoded_type (rt_dynamic_i,t) dl_client_state io #! (di_type_redirection_table,dl_client_state) = dl_client_state!cs_dynamic_info.[rt_dynamic_i].di_type_redirection_table; #! (maybe_encoded_type_redirection_index,(dl_client_state,io)) = findAiSt2 (find_type rt_dynamic_i t) di_type_redirection_table (dl_client_state,io); = (maybe_encoded_type_redirection_index,dl_client_state,io); where { find_type rt_dynamic_j rt_library_type_reference i_w encoded_library_type_reference_j (dl_client_state,io) #! (rt_library_type_reference_j,(dl_client_state,io)) = convert_encoded_type_reference_to_rt_type_reference_LibraryInstanceTypeReference rt_dynamic_j encoded_library_type_reference_j (dl_client_state,io); #! (ok,dl_client_state,io) = compare_type_implementation rt_library_type_reference rt_library_type_reference_j dl_client_state io; = (if ok (Just i_w) Nothing,(dl_client_state,io)); compare_type_implementation (LIT_TypeReference (LibRef library_instance_i) tio_type_ref_i) (LIT_TypeReference (LibRef library_instance_j) tio_type_ref_j) dl_client_state io = (library_instance_i == library_instance_j && (eq tio_type_ref_i tio_type_ref_j),dl_client_state,io); where { eq {tio_type_without_definition=Just type_name1} {tio_type_without_definition=Just type_name2} = type_name1 == type_name2; eq {tio_tr_module_n=tio_tr_module_n1,tio_tr_type_def_n=tio_tr_type_def_n1} {tio_tr_module_n=tio_tr_module_n2,tio_tr_type_def_n=tio_tr_type_def_n2} = tio_tr_module_n1 == tio_tr_module_n2 && tio_tr_type_def_n1 == tio_tr_type_def_n2; }; compare_type_implementation t1=:(LIT_TypeReference rt_lib_ref_i tio_type_ref_i) t2=:(LIT_TypeReference rt_lib_ref_j tio_type_ref_j) dl_client_state io | not IS_COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES = abort "dereference_lib_ref: internal error; may only be used when COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES is on"; | not (eq tio_type_ref_i tio_type_ref_j) // not sufficient = (False,dl_client_state,io); #! (lib_ref_chain_i,dl_client_state,io) = dereference_rt_lib_ref rt_lib_ref_i [] dl_client_state io; #! (lib_ref_chain_j,dl_client_state,io) = dereference_rt_lib_ref rt_lib_ref_j [] dl_client_state io; | has_same_end_point lib_ref_chain_i lib_ref_chain_j <<- (t1,lib_ref_chain_i,t2,lib_ref_chain_j) = (True,dl_client_state,io); = (False,dl_client_state,io); where { eq {tio_type_without_definition=Just type_name1} {tio_type_without_definition=Just type_name2} = type_name1 == type_name2; eq {tio_tr_module_n=tio_tr_module_n1,tio_tr_type_def_n=tio_tr_type_def_n1} {tio_tr_module_n=tio_tr_module_n2,tio_tr_type_def_n=tio_tr_type_def_n2} = tio_tr_module_n1 == tio_tr_module_n2 && tio_tr_type_def_n1 == tio_tr_type_def_n2; // check_types }; }; // converts a library type reference into an encoded version of it provided dio_used_library_instances has been set. convert_rt_type_reference_to_encoded_type_reference :: !LibraryInstanceTypeReference !DynamicInfoInput !*DynamicInfoOutput !*DLClientState !*f -> ((Maybe !LibraryInstanceTypeReference),!*DynamicInfoOutput,!*DLClientState,!*f) | FileEnv f; convert_rt_type_reference_to_encoded_type_reference t=:(LIT_TypeReference (LibRef library_instance_i) tio_type_ref) dii dio=:{dio_used_library_instances=used_library_instances} dl_client_state io # (maybe_encoded_type_reference,dio,dl_client_state,io) = case used_library_instances.[library_instance_i] of { UnusedLibraryInstance // ignore because it cannot be converted -> (Nothing,dio,dl_client_state,io); UsedLibraryInstance disk_library_instance_i #! encoded_type_reference = LIT_TypeReference (LibRef disk_library_instance_i) tio_type_ref; -> (Just encoded_type_reference,dio,dl_client_state,io); LazyLibraryInstance lazy_dynamic_index disk_library_instance_i | not IS_COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES // detected a reference to a library instance which is part of a lazy dynamic used by the current // main dynamic. This reference is converted into a lazy one in the encoded dynamic. #! (type_library_reference,dio,dl_client_state) = add_type_table_of_library_instance_i library_instance_i dio dl_client_state; #! encoded_lazy_type_reference = LIT_TypeReference (LibRefViaLazyDynamic disk_library_instance_i lazy_dynamic_index type_library_reference) tio_type_ref; -> (Just encoded_lazy_type_reference,dio,dl_client_state,io); // uit welke dynamic? (de libraries van de dynamic zijn al toegewezen) // welke index in type redirection tabel? // DLClientState #! (maybe_rt_dynamic_i,dl_client_state) = dl_client_state!cs_library_instances.lis_library_instances.[library_instance_i].li_dynamic_index; | isNothing maybe_rt_dynamic_i -> abort "convert_rt_id_to_disk_id"; #! rt_dynamic_i = fromJust maybe_rt_dynamic_i; #! (maybe_encoded_type_redirection_index,dl_client_state,io) = find_encoded_type (rt_dynamic_i,t) dl_client_state io; | isNothing maybe_encoded_type_redirection_index // <<- ("RESULT", maybe_encoded_type_redirection_index) -> abort "convert_rt_type_reference_to_encoded_type_reference; type expected but not present in type redirection table of lazy dynamic"; #! encoded_type_redirection_index = fromJust maybe_encoded_type_redirection_index; #! (type_library_reference,dio,dl_client_state) = add_type_table_of_library_instance_i library_instance_i dio dl_client_state; #! encoded_lazy_lib_ref = LIT_TypeReference (LazyLibRef encoded_type_redirection_index lazy_dynamic_index type_library_reference) tio_type_ref; -> (Just encoded_lazy_lib_ref,dio,dl_client_state,io); }; = (maybe_encoded_type_reference,dio,dl_client_state,io); where { add_type_table_of_library_instance_i library_instance_i dio dl_client_state #! (Just library_name,dl_client_state) = dl_client_state!cs_library_instances.lis_library_instances.[library_instance_i].li_library_name; #! (library_index,dio) = find_type_table library_name dio; = (library_index,dio,dl_client_state); }; convert_rt_type_reference_to_encoded_type_reference q=:(LIT_TypeReference lib_ref=:(LazyLibRef rt_type_redirection_i rt_lazy_dynamic_i type_table_i) tio_type_ref) dii=:{dii_lazy_dynamic_references} dio =:{dio_lazy_dynamics,dio_used_library_instances=used_library_instances} dl_client_state io #! (rt_main_dynamic_i,dl_client_state) = dl_client_state!cs_lazy_dynamic_index_to_dynamic_id.[rt_lazy_dynamic_i].ldi_parent_index; // determine whether the lazy dynamic is included in the dynamic to be written #! maybe_encoded_dynamic_i = findAi (\_ {ldr_id,ldr_lazy_dynamic_index} -> if (ldr_id == rt_main_dynamic_i) (Just ldr_lazy_dynamic_index) Nothing) dii_lazy_dynamic_references; | isNothing maybe_encoded_dynamic_i // type reference does not belong to a lazy dynamic referenced from the main encoded dynamic = (Nothing,dio,dl_client_state,io); #! encoded_dynamic_i = fromJust maybe_encoded_dynamic_i; // lookup type in main dynamic #! (maybe_encoded_type_redirection_index,dl_client_state,io) = find_encoded_type (rt_main_dynamic_i,q) dl_client_state io; | isNothing maybe_encoded_type_redirection_index // type not in main dynamic = (Nothing,dio,dl_client_state,io); #! encoded_type_redirection_i = fromJust maybe_encoded_type_redirection_index; #! (type_library_reference,dio,dl_client_state) = add_type_table type_table_i dio dl_client_state; #! converted_type = LIT_TypeReference (LazyLibRef encoded_type_redirection_i encoded_dynamic_i type_library_reference) tio_type_ref; = (Just converted_type,dio,dl_client_state,io); convert_rt_type_reference_to_encoded_type_reference (LIT_TypeReference (LibRefViaLazyDynamic disk_library_instance rt_dynamic_index type_table_i) tio_type_ref) dii=:{dii_lazy_dynamic_references} dio=:{dio_lazy_dynamics,dio_used_library_instances=used_library_instances} dl_client_state io | ALLOW_LAZY_LIBRARY_REFERENCES False True = abort "convert_rt_id_to_disk_id; lazy library references (lazy dynamic) unimplemented"; | IS_COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES = abort "convert_rt_type_reference_to_encoded_type_reference; unimplemented for COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES"; // determine the main dynamic of the lazy dynamic # (Just (disk_lazy_dynamic_index,rt_main_dynamic_index),dl_client_state) = get_dynamic_id rt_dynamic_index dl_client_state; // determine whether the lazy dynamic is included in the dynamic to be written # maybe_disk_dynamic_index_within_main_dynamic = findAi (\_ {ldr_id,ldr_lazy_dynamic_index} -> if (ldr_id == rt_main_dynamic_index) (Just ldr_lazy_dynamic_index) Nothing) dii_lazy_dynamic_references; | isNothing maybe_disk_dynamic_index_within_main_dynamic // type reference does not belong to a lazy dynamic of the main dynamic being created. Ignore it. = (Nothing,dio,dl_client_state,io); // determine the lazy library instance within the main dynamic of the lazy dynamic. // SUPERFLUOUS? ... # lazy_id = {lr_library_instance_i=disk_library_instance,lr_dynamic_index_i=disk_lazy_dynamic_index}; # (di_library_instance_to_library_index,dl_client_state) = dl_client_state!cs_dynamic_info.[rt_main_dynamic_index].di_library_instance_to_library_index; # r = findAi (find_library_instance_i_for_lazy_reference lazy_id) di_library_instance_to_library_index; | isNothing r = (Nothing,dio,dl_client_state,io); // ... SUPERFLUOUS? #! (type_library_reference,dio,dl_client_state) = add_type_table type_table_i dio dl_client_state; # converted_type = LIT_TypeReference (LibRefViaLazyDynamic (fromJust r) (fromJust maybe_disk_dynamic_index_within_main_dynamic) type_library_reference) tio_type_ref; = (Just converted_type,dio,dl_client_state,io); where { find_library_instance_i_for_lazy_reference searched_lazy_id disk_library_instance_i (LIK_LazyLibraryInstance {LIK_LazyLibraryInstance | lik_library_instance_i,lik_dynamic_index_i}) #! lazy_id = {lr_library_instance_i=lik_library_instance_i,lr_dynamic_index_i=lik_dynamic_index_i} = if (searched_lazy_id == lazy_id) (Just disk_library_instance_i) Nothing; find_library_instance_i_for_lazy_reference searched_lazy_id disk_library_instance_i _ = Nothing; }; // Nothing als de type referentie niet binnen de te weg te schrijven dynamic valt. add_type_table type_table_i dio dl_client_state #! (tt_name,dl_client_state) = dl_client_state!cs_type_tables.[type_table_i].tt_name; #! (library_index,dio) = find_type_table tt_name dio; = (library_index,dio,dl_client_state); has_same_end_point [lib_ref_i:_] [lib_ref_j:_] = same_end_point lib_ref_i lib_ref_j; where { same_end_point (LibRef library_instance_i) (LibRef library_instance_j) = library_instance_i == library_instance_j; same_end_point (LazyLibRef ith_type_redirection_entry rt_lazy_dynamic_i _) (LazyLibRef jth_type_redirection_entry rt_lazy_dynamic_j _) = ith_type_redirection_entry == jth_type_redirection_entry && rt_lazy_dynamic_i == rt_lazy_dynamic_j; }; has_same_end_point _ _ = False; dereference_rt_lib_ref :: !LibRef [LibRef] !*DLClientState !*f -> ([LibRef],!*DLClientState,!*f) | FileEnv f; dereference_rt_lib_ref rt_lib_ref=:(LibRef _) lib_ref_chain dl_client_state io | not IS_COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES <<- ("dereference_rt_lib_ref", rt_lib_ref,lib_ref_chain) = abort "dereference_lib_ref: internal error; may only be used when COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES is on"; #! lib_ref_chain = [rt_lib_ref:lib_ref_chain]; = (lib_ref_chain,dl_client_state,io); dereference_rt_lib_ref rt_lib_ref=:(LazyLibRef ith_type_redirection_entry rt_lazy_dynamic_i _) lib_ref_chain dl_client_state io | not IS_COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES<<- ("dereference_rt_lib_ref", rt_lib_ref, lib_ref_chain) = abort "dereference_lib_ref: internal error; may only be used when COLLECT_AND_RENUMBER_EXTERNAL_TYPE_REFERENCES is on"; #! lib_ref_chain = [rt_lib_ref:lib_ref_chain]; #! (maybe_rt_dynamic_i,dl_client_state) = dl_client_state!cs_lazy_dynamic_index_to_dynamic_id.[rt_lazy_dynamic_i].ldi_lazy_dynamic_index_to_dynamic; | isNothing maybe_rt_dynamic_i = (lib_ref_chain,dl_client_state,io); #! rt_dynamic_i = fromJust maybe_rt_dynamic_i; #! (encoded_lib_ref,dl_client_state) = dl_client_state!cs_dynamic_info.[rt_dynamic_i].di_rt_type_redirection_table.[ith_type_redirection_entry].rtid_runtime_id; = dereference_rt_lib_ref (decode_lib_ref encoded_lib_ref) lib_ref_chain dl_client_state io;