From 3ed5d236280fd983782615866234231958d3f229 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Thu, 21 Nov 2024 23:32:02 +0100 Subject: [PATCH] Implemented cwd and options map. --- source/loader/source/loader_impl.c | 7 +- source/loader/source/loader_manager_impl.c | 12 ++- source/metacall/source/metacall.c | 19 ++++- source/portability/CMakeLists.txt | 2 + .../portability/portability_working_path.h | 54 ++++++++++++++ .../source/portability_working_path.c | 74 +++++++++++++++++++ 6 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 source/portability/include/portability/portability_working_path.h create mode 100644 source/portability/source/portability_working_path.c diff --git a/source/loader/source/loader_impl.c b/source/loader/source/loader_impl.c index c6ccf3297..6b7bbafe3 100644 --- a/source/loader/source/loader_impl.c +++ b/source/loader/source/loader_impl.c @@ -87,7 +87,7 @@ struct loader_impl_type loader_impl_data data; /* Derived metadata provided by the loader, usually contains the data of the VM, Interpreter or JIT */ context ctx; /* Contains the objects, classes and functions loaded in the global scope of each loader */ set type_info_map; /* Stores a set indexed by type name of all of the types existing in the loader (global scope (TODO: may need refactor per handle)) */ - void *options; /* Additional initialization options passed in the initialize phase */ + value options; /* Additional initialization options passed in the initialize phase */ set exec_path_map; /* Set of execution paths passed by the end user */ }; @@ -1539,6 +1539,11 @@ void loader_impl_destroy_deallocate(loader_impl impl) context_destroy(impl->ctx); + if (impl->options != NULL) + { + value_type_destroy(impl->options); + } + free(impl); } diff --git a/source/loader/source/loader_manager_impl.c b/source/loader/source/loader_manager_impl.c index b22fa1527..f3f4375a6 100644 --- a/source/loader/source/loader_manager_impl.c +++ b/source/loader/source/loader_manager_impl.c @@ -26,8 +26,8 @@ #include -#include #include +#include #include @@ -52,8 +52,8 @@ static void *loader_manager_impl_is_destroyed_ptr = NULL; vector loader_manager_impl_script_paths_initialize(void) { - portability_executable_path_str exe_path_str = { 0 }; - portability_executable_path_length exe_path_str_length = 0; + portability_working_path_str cwd_path_str = { 0 }; + portability_working_path_length cwd_path_str_length = 0; char *script_path = NULL; size_t script_path_size = 0; vector script_paths = vector_create_type(char *); @@ -63,11 +63,9 @@ vector loader_manager_impl_script_paths_initialize(void) return NULL; } - if (portability_executable_path(exe_path_str, &exe_path_str_length) == 0) + if (portability_working_path(cwd_path_str, &cwd_path_str_length) == 0) { - size_t exe_directory_size = portability_path_get_directory_inplace(exe_path_str, exe_path_str_length + 1); - - script_path = environment_variable_path_create(LOADER_SCRIPT_PATH, exe_path_str, exe_directory_size, &script_path_size); + script_path = environment_variable_path_create(LOADER_SCRIPT_PATH, cwd_path_str, cwd_path_str_length + 1, &script_path_size); } else { diff --git a/source/metacall/source/metacall.c b/source/metacall/source/metacall.c index 45b949c70..171c18482 100644 --- a/source/metacall/source/metacall.c +++ b/source/metacall/source/metacall.c @@ -76,16 +76,33 @@ portability_constructor(metacall_constructor) { const char *metacall_host = environment_variable_get("METACALL_HOST", NULL); + /* We are running from a different host, initialize the loader of the host + * and redirect it to the existing symbols, also avoiding initialization + * and destruction of the runtime as it is being managed externally to MetaCall */ if (metacall_host != NULL) { + static const char host_str[] = "host"; + struct metacall_initialize_configuration_type config[] = { - { metacall_host, NULL /* TODO: Initialize the map and define { host: true } */ }, + { metacall_host, metacall_value_create_map(NULL, 1) }, { NULL, NULL } }; + /* Initialize the loader options with a map defining its options to { "host": true } */ + void **host_tuple, **options_map = metacall_value_to_map(config[0].options); + + options_map[0] = metacall_value_create_array(NULL, 2); + + host_tuple = metacall_value_to_array(options_map[0]); + + host_tuple[0] = metacall_value_create_string(host_str, sizeof(host_str) - 1); + host_tuple[1] = metacall_value_create_bool(1); + + /* Initialize MetaCall with extra options, defining the host properly */ if (metacall_initialize_ex(config) != 0) { log_write("metacall", LOG_LEVEL_ERROR, "MetaCall host constructor failed to initialize"); + metacall_value_destroy(config[0].options); exit(1); } } diff --git a/source/portability/CMakeLists.txt b/source/portability/CMakeLists.txt index 2841f3aaa..cf4af64c6 100644 --- a/source/portability/CMakeLists.txt +++ b/source/portability/CMakeLists.txt @@ -38,6 +38,7 @@ set(headers ${include_path}/portability_constructor.h ${include_path}/portability_executable_path.h ${include_path}/portability_library_path.h + ${include_path}/portability_working_path.h ${include_path}/portability_path.h ) @@ -45,6 +46,7 @@ set(sources ${source_path}/portability.c ${source_path}/portability_executable_path.c ${source_path}/portability_library_path.c + ${source_path}/portability_working_path.c ${source_path}/portability_path.c ) diff --git a/source/portability/include/portability/portability_working_path.h b/source/portability/include/portability/portability_working_path.h new file mode 100644 index 000000000..00866a3a9 --- /dev/null +++ b/source/portability/include/portability/portability_working_path.h @@ -0,0 +1,54 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef PORTABILITY_WORKING_PATH_H +#define PORTABILITY_WORKING_PATH_H 1 + +/* -- Headers -- */ + +#include + +#include + +/* -- Type Definitions -- */ + +typedef char portability_working_path_str[PORTABILITY_PATH_SIZE]; + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) +typedef DWORD portability_working_path_length; +#else +typedef size_t portability_working_path_length; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Methods -- */ + +PORTABILITY_API int portability_working_path(portability_working_path_str path, portability_working_path_length *length); + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABILITY_WORKING_PATH_H */ diff --git a/source/portability/source/portability_working_path.c b/source/portability/source/portability_working_path.c new file mode 100644 index 000000000..1511cef35 --- /dev/null +++ b/source/portability/source/portability_working_path.c @@ -0,0 +1,74 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) + #include +#else + #include +#endif + +int portability_working_path(portability_working_path_str path, portability_working_path_length *length) +{ + const portability_working_path_length path_max_length = PORTABILITY_PATH_SIZE; + + /* Reset the path */ + memset(path, 0, path_max_length); + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) + *length = GetCurrentDirectory(0, NULL); + + if (*length == 0) + { + /* TODO: DWORD dw = GetLastError(); */ + return 1; + } + + if (*length > path_max_length) + { + /* TODO: Handle error */ + return 1; + } + + if (GetCurrentDirectory(*length, path) == 0) + { + /* TODO: DWORD dw = GetLastError(); */ + return 1; + } +#else + if (getcwd(path, path_max_length) == NULL) + { + *length = 0; + /* TODO: Handle error */ + return 1; + } + + *length = strnlen(path, path_max_length); +#endif + + return 0; +}