Skip to content

Commit 8a3e90a

Browse files
committed
Refactor of paths, this new methodology will solve bugs related to the load_from_file of multiple loaders. This new mode will standardize how it works and reduce friction between loaders.
1 parent 83bd101 commit 8a3e90a

File tree

53 files changed

+1166
-432
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1166
-432
lines changed

source/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44

55
# Export output script directory
6-
set(LOADER_SCRIPT_PATH "${PROJECT_BINARY_DIR}/scripts/" CACHE PATH "MetaCall scripts path")
6+
set(LOADER_SCRIPT_PATH "${PROJECT_BINARY_DIR}/scripts" CACHE PATH "MetaCall scripts path")
77

88
# Export output loader plugin directory
99
set(LOADER_LIBRARY_PATH "@OUTPUT_DIRECTORY_DIR@" CACHE PATH "MetaCall loaders path")

source/loader/source/loader.c

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -403,45 +403,7 @@ int loader_load_from_file(const loader_naming_tag tag, const loader_naming_path
403403

404404
if (impl != NULL)
405405
{
406-
const char *script_path = loader_env_script_path();
407-
408-
if (script_path != NULL)
409-
{
410-
loader_naming_path *absolute_paths = malloc(sizeof(loader_naming_path) * size);
411-
412-
size_t iterator;
413-
414-
int result;
415-
416-
if (absolute_paths == NULL)
417-
{
418-
log_write("metacall", LOG_LEVEL_ERROR, "Loader load from file invalid absolute paths allocation");
419-
420-
return 1;
421-
}
422-
423-
for (iterator = 0; iterator < size; ++iterator)
424-
{
425-
if (loader_path_is_absolute(paths[iterator]) != 0)
426-
{
427-
(void)loader_path_join(script_path, strlen(script_path) + 1, paths[iterator], strnlen(paths[iterator], LOADER_NAMING_PATH_SIZE - 1) + 1, absolute_paths[iterator]);
428-
}
429-
else
430-
{
431-
strncpy(absolute_paths[iterator], paths[iterator], strnlen(paths[iterator], LOADER_NAMING_PATH_SIZE - 1) + 1);
432-
}
433-
}
434-
435-
result = loader_impl_load_from_file(impl, (const loader_naming_path *)absolute_paths, size, handle);
436-
437-
free(absolute_paths);
438-
439-
return result;
440-
}
441-
else
442-
{
443-
return loader_impl_load_from_file(impl, paths, size, handle);
444-
}
406+
return loader_impl_load_from_file(impl, paths, size, handle);
445407
}
446408
}
447409
}

source/loader/source/loader_impl.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ int loader_impl_initialize(loader_impl impl)
273273
configuration config;
274274

275275
const char *script_path = NULL;
276+
const char *library_path = NULL;
276277

277278
vector paths;
278279

@@ -303,6 +304,16 @@ int loader_impl_initialize(loader_impl impl)
303304
loader_impl_configuration(impl, config);
304305
}
305306

307+
library_path = loader_env_library_path();
308+
309+
if (library_path != NULL)
310+
{
311+
if (loader_impl_execution_path(impl, library_path) != 0)
312+
{
313+
log_write("metacall", LOG_LEVEL_ERROR, "Error when loading path %s", library_path);
314+
}
315+
}
316+
306317
script_path = loader_env_script_path();
307318

308319
if (script_path != NULL)
@@ -665,7 +676,7 @@ int loader_impl_load_from_file(loader_impl impl, const loader_naming_path paths[
665676

666677
handle = interface_impl->load_from_file(impl, paths, size);
667678

668-
log_write("metacall", LOG_LEVEL_DEBUG, "Loader interface: %p\nLoader handle: %p", (void *)interface_impl, (void *)handle);
679+
log_write("metacall", LOG_LEVEL_DEBUG, "Loader interface: %p; Loader handle: %p", (void *)interface_impl, (void *)handle);
669680

670681
if (handle != NULL)
671682
{

source/loader/source/loader_path.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,19 @@ size_t loader_path_join(const loader_naming_path left_path, size_t left_path_siz
226226
size_t loader_path_canonical(const loader_naming_path path, size_t size, loader_naming_path canonical)
227227
{
228228
size_t iterator, canonical_size = 0;
229+
int separator_found = 1;
230+
char separator;
231+
232+
/* Standarize the separators */
233+
for (iterator = 0; iterator < size; ++iterator)
234+
{
235+
if (LOADER_PATH_SEPARATOR(path[iterator]))
236+
{
237+
separator_found = 0;
238+
separator = path[iterator];
239+
break;
240+
}
241+
}
229242

230243
/* Remove first dots */
231244
for (iterator = 0; path[iterator] == '.'; ++iterator)
@@ -310,7 +323,8 @@ size_t loader_path_canonical(const loader_naming_path path, size_t size, loader_
310323
}
311324
}
312325

313-
canonical[canonical_size++] = path[iterator];
326+
/* Store the correct separator */
327+
canonical[canonical_size++] = LOADER_PATH_SEPARATOR(path[iterator]) && separator_found == 0 ? separator : path[iterator];
314328
}
315329

316330
return canonical_size;

source/loaders/cob_loader/source/cob_loader_impl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ loader_impl_data cob_loader_impl_initialize(loader_impl impl, configuration conf
123123
(void)impl;
124124
(void)config;
125125

126+
// TODO: The enviroment path trick wont be needed if
127+
// we implement cob_loader_impl_execution_path properly.
128+
// Remove this once we implement this properly (if needed)
129+
126130
// Copy environment variables in order to resolve properly the scripts
127131
const char *scripts_path = getenv("LOADER_SCRIPT_PATH");
128132

source/loaders/cs_loader/include/cs_loader/defs.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,23 @@ typedef struct
5252
reflect_param pars[10];
5353
} reflect_function;
5454

55-
typedef void(void_func)(void);
55+
typedef char(execution_path_w)(const wchar_t *source);
56+
typedef char(execution_path_c)(const char *source);
5657

57-
typedef char(load_from_source_w)(wchar_t *source);
58+
typedef char(load_from_source_w)(const wchar_t *source);
5859
typedef char(load_from_source_c)(const char *source);
5960

60-
typedef char(load_from_files_w)(wchar_t **source, size_t size);
61-
typedef char(load_from_files_c)(char **source, size_t size);
61+
typedef char(load_from_files_w)(const wchar_t **source, size_t size);
62+
typedef char(load_from_files_c)(const char **source, size_t size);
6263

63-
typedef char(load_from_assembly_w)(wchar_t *source);
64+
typedef char(load_from_assembly_w)(const wchar_t *source);
6465
typedef char(load_from_assembly_c)(const char *source);
6566

6667
typedef void(corefunction_destroy_execution_result)(execution_result *er);
67-
typedef execution_result *(execute_function_c)(char *function);
68-
typedef execution_result *(execute_function_w)(wchar_t *function);
69-
typedef execution_result *(execute_function_with_params_w)(wchar_t *function, parameters *);
70-
typedef execution_result *(execute_function_with_params_c)(char *function, parameters *);
68+
typedef execution_result *(execute_function_c)(const char *function);
69+
typedef execution_result *(execute_function_w)(const wchar_t *function);
70+
typedef execution_result *(execute_function_with_params_w)(const wchar_t *function, parameters *);
71+
typedef execution_result *(execute_function_with_params_c)(const char *function, parameters *);
7172
typedef void(get_loaded_functions)(int *, reflect_function *);
7273

7374
#if defined(__linux) | defined(linux)

source/loaders/cs_loader/include/cs_loader/netcore.h

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class netcore
3333
char *dotnet_loader_assembly_path;
3434

3535
public:
36+
execution_path_w *core_execution_path_w;
37+
execution_path_c *core_execution_path_c;
38+
3639
load_from_source_w *core_load_from_source_w;
3740
load_from_source_c *core_load_from_source_c;
3841

@@ -53,6 +56,9 @@ class netcore
5356
const CHARSTRING *class_name = W("CSLoader.MetacallEntryPoint");
5457
const CHARSTRING *assembly_name = W("CSLoader");
5558

59+
const CHARSTRING *delegate_execution_path_w = W("ExecutionPathW");
60+
const CHARSTRING *delegate_execution_path_c = W("ExecutionPathW");
61+
5662
const CHARSTRING *delegate_load_source_w = W("LoadSourceW");
5763
const CHARSTRING *delegate_load_source_c = W("LoadSourceC");
5864

@@ -75,20 +81,23 @@ class netcore
7581
virtual bool start() = 0;
7682
virtual void stop() = 0;
7783

78-
bool load_source(wchar_t *source);
79-
bool load_source(char *source);
84+
bool execution_path(const wchar_t *path);
85+
bool execution_path(const char *path);
86+
87+
bool load_source(const wchar_t *source);
88+
bool load_source(const char *source);
8089

81-
bool load_files(wchar_t **source, size_t size);
82-
bool load_files(char **source, size_t size);
90+
bool load_files(const wchar_t **source, size_t size);
91+
bool load_files(const char **source, size_t size);
8392

84-
bool load_assembly(wchar_t *source);
85-
bool load_assembly(char *source);
93+
bool load_assembly(const wchar_t *source);
94+
bool load_assembly(const char *source);
8695

87-
execution_result *execute(char *function);
88-
execution_result *execute(wchar_t *function);
96+
execution_result *execute(const char *function);
97+
execution_result *execute(const wchar_t *function);
8998

90-
execution_result *execute_with_params(char *function, parameters *params);
91-
execution_result *execute_with_params(wchar_t *function, parameters *params);
99+
execution_result *execute_with_params(const char *function, parameters *params);
100+
execution_result *execute_with_params(const wchar_t *function, parameters *params);
92101

93102
bool create_delegates();
94103

source/loaders/cs_loader/include/cs_loader/simple_netcore.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,19 @@ typedef char source_file[512];
3636

3737
netcore_handle simple_netcore_create(char *dotnet_root, char *dotnet_loader_assembly_path);
3838

39-
reflect_function *simple_netcore_get_functions(netcore_handle, int *);
39+
reflect_function *simple_netcore_get_functions(netcore_handle handle, int *count);
4040

41-
int simple_netcore_load_script_from_files(netcore_handle handle, char *files[MAX_FILES], size_t size);
41+
int simple_netcore_load_script_from_files(netcore_handle handle, const char *files[MAX_FILES], size_t size);
4242

43-
int simple_netcore_load_script_from_assembly(netcore_handle handle, char *file);
43+
int simple_netcore_execution_path(netcore_handle handle, const char *path);
44+
45+
int simple_netcore_load_script_from_assembly(netcore_handle handle, const char *file);
4446

4547
int simple_netcore_load_script_from_memory(netcore_handle handle, const char *buffer, size_t size);
4648

47-
execution_result *simple_netcore_invoke(netcore_handle, const char *);
49+
execution_result *simple_netcore_invoke(netcore_handle handle, const char *func);
4850

49-
void simple_netcore_destroy(netcore_handle);
51+
void simple_netcore_destroy(netcore_handle handle);
5052

5153
execution_result *simple_netcore_invoke_with_params(netcore_handle handle, const char *func, parameters *params);
5254

source/loaders/cs_loader/netcore/source/MetacallEntryPoint.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ public unsafe static bool LoadFromPointer(string[] source)
4747
}
4848
}
4949

50+
public static bool ExecutionPathC([System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]string path)
51+
{
52+
return loader.ExecutionPath(path);
53+
}
54+
55+
public static bool ExecutionPathW([System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]string path)
56+
{
57+
return loader.ExecutionPath(path);
58+
}
59+
5060
public static bool Load(string source)
5161
{
5262
try {
@@ -61,7 +71,7 @@ public static bool Load(string source)
6171
public static bool Load(string[] files)
6272
{
6373
try {
64-
return loader.LoadFromSourceFunctions(files.Select(x => System.IO.File.ReadAllText(x)).ToArray());
74+
return loader.LoadFromFileFunctions(files);
6575
} catch (Exception ex) {
6676
// TODO: Implement error handling
6777
log.Error(ex.Message, ex);

source/loaders/cs_loader/netcore/source/Providers/LoaderBase.cs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ protected LoaderBase(ILog log)
2121
this.log = log;
2222
}
2323

24+
public bool ExecutionPath(string path)
25+
{
26+
if (!paths.Contains(path))
27+
{
28+
log.Info("Loading execution path: " + path);
29+
paths.Add(path);
30+
return true;
31+
}
32+
33+
return false;
34+
}
35+
2436
public ReflectFunction[] Functions()
2537
{
2638
return this.functions.Select(x => x.Value.GetReflectFunction()).ToArray();
@@ -35,6 +47,65 @@ protected virtual IEnumerable<string> AdditionalLibs()
3547

3648
protected abstract Assembly MakeAssembly(MemoryStream stream);
3749

50+
private static bool IsFullPath(string path)
51+
{
52+
// https://stackoverflow.com/a/47569899
53+
if (string.IsNullOrWhiteSpace(path) || path.IndexOfAny(Path.GetInvalidPathChars()) != -1 || !Path.IsPathRooted(path))
54+
return false;
55+
56+
string pathRoot = Path.GetPathRoot(path);
57+
if (pathRoot.Length <= 2 && pathRoot != "/") // Accepts X:\ and \\UNC\PATH, rejects empty string, \ and X:, but accepts / to support Linux
58+
return false;
59+
60+
if (pathRoot[0] != '\\' || pathRoot[1] != '\\')
61+
return true; // Rooted and not a UNC path
62+
63+
return pathRoot.Trim('\\').IndexOf('\\') != -1; // A UNC server name without a share name (e.g "\\NAME" or "\\NAME\") is invalid
64+
}
65+
66+
private string LoadFromFileFunctionsRelative(string file)
67+
{
68+
foreach (var path in paths)
69+
{
70+
try
71+
{
72+
return System.IO.File.ReadAllText(Path.Combine(path, file));
73+
}
74+
catch (Exception ex)
75+
{
76+
continue;
77+
}
78+
}
79+
80+
throw new Exception("File " + file + " not found");
81+
}
82+
83+
public bool LoadFromFileFunctions(string[] files)
84+
{
85+
List<string> sources = new List<string>();
86+
87+
foreach (var file in files)
88+
{
89+
try
90+
{
91+
sources.Add(IsFullPath(file) ? System.IO.File.ReadAllText(file) : LoadFromFileFunctionsRelative(file));
92+
}
93+
catch (Exception ex)
94+
{
95+
this.log.Error("CSLoader loading error: " + ex.Message);
96+
return false;
97+
}
98+
}
99+
100+
if (files.Length != sources.Count)
101+
{
102+
this.log.Error("Not all files could be loaded (" + sources.Count + "/" + files.Length + ")");
103+
return false;
104+
}
105+
106+
return LoadFromSourceFunctions(sources.ToArray());
107+
}
108+
38109
public bool LoadFromSourceFunctions(string[] source)
39110
{
40111
Assembly assembly = null;
@@ -102,8 +173,6 @@ public bool LoadFromSourceFunctions(string[] source)
102173

103174
public void LoadFunctions(Assembly assembly)
104175
{
105-
this.log.Info("CSLoader load functions");
106-
107176
foreach (var item in assembly.DefinedTypes.SelectMany(x => x.GetMethods()).Where(x => x.IsStatic))
108177
{
109178
var con = new FunctionContainer(item);

0 commit comments

Comments
 (0)