implementation module DynamicLinkerOffsets;

import StdArray;
//1.3
from StdString import String;
//3.1

import SymbolTable;
from DynamicLink import SetCurrentLibrary, StoreLong, GetFuncAddress;
from Offsets import Remove_at_size;

Dcompute_imported_library_symbol_offsets :: LibraryList Int Int Int *{#Bool} *{#Int} -> (*{#Bool},!LibraryList,!Int,!*{#Int}); 
Dcompute_imported_library_symbol_offsets EmptyLibraryList thunk_data_offset0 n_libraries symbol_n marked_bool_a module_offset_a0
	= (marked_bool_a,EmptyLibraryList,thunk_data_offset0,module_offset_a0);

Dcompute_imported_library_symbol_offsets (Library library_name base_of_client_dll library_symbols n_symbols library_list0) thunk_data_offset0 n_libraries symbol_n marked_bool_a module_offset_a0
	#! (ok,library) 
		= SetCurrentLibrary library_name
	|	not ok
		=	abort "Dcompute_imported_library_symbol_offsets: library doesn't exist"

		# (library,marked_bool_a, /* imported_symbols */ _,thunk_data_offset1,module_offset_a1)
			= compute_library_symbol_offsets library library_symbols symbol_n thunk_data_offset0 marked_bool_a module_offset_a0;
		| not (CloseLibrary library)
			= abort "Dcompute_imported_library_symbol_offsets: error"
		
			# (marked_bool_a,library_list1,thunk_data_offset2, module_offset_a2)
				= Dcompute_imported_library_symbol_offsets library_list0 thunk_data_offset1 (inc n_libraries) (symbol_n+n_symbols) marked_bool_a module_offset_a1; 
		
			# n_imported_symbols 
				= (thunk_data_offset1-thunk_data_offset0) / 4;	
		
			= (marked_bool_a, Library library_name base_of_client_dll library_symbols n_symbols/* imported_symbols n_imported_symbols*/ library_list1,thunk_data_offset2,module_offset_a2); {}
	{
		compute_library_symbol_offsets :: !*Int LibrarySymbolsList Int Int *{#Bool} *{#Int} -> (!*Int,*{#Bool},!LibrarySymbolsList, !Int,!*{#Int});
		compute_library_symbol_offsets library EmptyLibrarySymbolsList symbol_n thunk_data_offset0 marked_bool_a module_offset_a0
			= (library,marked_bool_a,EmptyLibrarySymbolsList, thunk_data_offset0 /*+4*/,module_offset_a0);
		
		compute_library_symbol_offsets library (LibrarySymbol symbol_name symbol_list) symbol_n thunk_data_offset0 marked_bool_a module_offset_a0
			| marked_bool_a.[symbol_n]
				#! (func_address,library1) 
					= GetFuncAddress (Remove_at_size symbol_name) base_of_client_dll library; 
					
					#	ok	
						= StoreLong (symbol_name) thunk_data_offset0 func_address;



					|	not ok 
						= abort ("Dcompute_imported_library_symbol_offsets: can not store long");
		
						= (library2,marked_bool_a1,LibrarySymbol symbol_name imported_symbols,thunk_data_offset1,module_offset_a1);
						{
							(library2,marked_bool_a1,imported_symbols,thunk_data_offset1,module_offset_a1)
								= compute_library_symbol_offsets library1 symbol_list (symbol_n+2) (thunk_data_offset0+4) marked_bool_a 
									{module_offset_a0 & [symbol_n]= func_address,
									[symbol_n+1]= thunk_data_offset0 };
						}
						
						
						
					
				// unmarked symbol
				= compute_library_symbol_offsets library symbol_list (symbol_n+2) thunk_data_offset0 marked_bool_a module_offset_a0; 
	}
	
E :: !a .b -> .b;
E a b = b;
	
CloseLibrary :: !*Int -> !Bool;
CloseLibrary _ = 	code { 
		ccall CloseLibrary "I-I"
	};
	
