diff --git a/FEXCore/Scripts/config_generator.py b/FEXCore/Scripts/config_generator.py index af755af04..4b996eeeb 100644 --- a/FEXCore/Scripts/config_generator.py +++ b/FEXCore/Scripts/config_generator.py @@ -423,7 +423,7 @@ def print_parse_argloader_options(options): # these need a bit more help output_argloader.write("\tauto Array = Options.all(\"{0}\");\n".format(op_key)) output_argloader.write("\tfor (auto iter = Array.begin(); iter != Array.end(); ++iter) {\n") - output_argloader.write("\t\tSet(FEXCore::Config::ConfigOption::CONFIG_{0}, *iter);\n".format(op_key.upper())) + output_argloader.write("\t\tAppendStrArrayValue(FEXCore::Config::ConfigOption::CONFIG_{0}, *iter);\n".format(op_key.upper())) output_argloader.write("\t}\n") else: if (NeedsString): @@ -466,7 +466,11 @@ def print_parse_jsonloader_options(options): value_type = op_vals["Type"] if (value_type == "strenum"): output_argloader.write("else if (KeyName == \"{0}\") {{\n".format(op_key)) - output_argloader.write("Set(KeyOption, FEXCore::Config::EnumParser(FEXCore::Config::{}_EnumPairs, Value_View));\n".format(op_key, op_key, op_key)) + output_argloader.write("\tSet(KeyOption, FEXCore::Config::EnumParser(FEXCore::Config::{}_EnumPairs, Value_View));\n".format(op_key, op_key, op_key)) + output_argloader.write("}\n") + elif (value_type == "strarray"): + output_argloader.write("else if (KeyName == \"{0}\") {{\n".format(op_key)) + output_argloader.write("\tAppendStrArrayValue(KeyOption, ConfigString);\n") output_argloader.write("}\n") output_argloader.write("else {{\n".format(op_key)) diff --git a/FEXCore/Source/Common/StringConv.h b/FEXCore/Source/Common/StringConv.h index 7a39a80bb..e690d51f0 100644 --- a/FEXCore/Source/Common/StringConv.h +++ b/FEXCore/Source/Common/StringConv.h @@ -19,12 +19,24 @@ static bool Conv(std::string_view Value, uint8_t* Result) { return true; } +[[maybe_unused]] +static bool Conv(std::string_view Value, int8_t* Result) { + *Result = std::strtol(Value.data(), nullptr, 0); + return true; +} + [[maybe_unused]] static bool Conv(std::string_view Value, uint16_t* Result) { *Result = std::strtoul(Value.data(), nullptr, 0); return true; } +[[maybe_unused]] +static bool Conv(std::string_view Value, int16_t* Result) { + *Result = std::strtol(Value.data(), nullptr, 0); + return true; +} + [[maybe_unused]] static bool Conv(std::string_view Value, uint32_t* Result) { *Result = std::strtoul(Value.data(), nullptr, 0); @@ -42,6 +54,13 @@ static bool Conv(std::string_view Value, uint64_t* Result) { *Result = std::strtoull(Value.data(), nullptr, 0); return true; } + +[[maybe_unused]] +static bool Conv(std::string_view Value, int64_t* Result) { + *Result = std::strtoll(Value.data(), nullptr, 0); + return true; +} + template::value, T>> [[maybe_unused]] static bool Conv(std::string_view Value, T* Result) { diff --git a/FEXCore/Source/Interface/Config/Config.cpp b/FEXCore/Source/Interface/Config/Config.cpp index 74497a44d..5c47d6fed 100644 --- a/FEXCore/Source/Interface/Config/Config.cpp +++ b/FEXCore/Source/Interface/Config/Config.cpp @@ -122,7 +122,8 @@ uint64_t GetConfig(FEXCore::Context::Context* CTX, ConfigOption Option) { } static fextl::map> ConfigLayers; -static FEXCore::Config::Layer* Meta {}; +class MetaLayer; +static FEXCore::Config::MetaLayer* Meta {}; constexpr std::array LoadOrder = { FEXCore::Config::LayerType::LAYER_GLOBAL_MAIN, FEXCore::Config::LayerType::LAYER_MAIN, @@ -143,9 +144,39 @@ public: ~MetaLayer() {} void Load(); + template + requires (!std::is_same_v && !std::is_same_v) + std::optional GetConv(ConfigOption Option) { + const auto it = OptionMap.find(Option); + if (it == OptionMap.end()) { + return std::nullopt; + } + + const auto& Value = it->second; + LOGMAN_THROW_A_FMT(!std::holds_alternative(Value), "Tried to get config of invalid type!"); + + if (std::holds_alternative(Value)) [[likely]] { + return std::get(Value); + } + + T ConvertedValue; + if (std::holds_alternative(Value)) { + const auto& StrVal = std::get(Value); + if (FEXCore::StrConv::Conv(StrVal, &ConvertedValue)) { + // Convert the value. + OptionMap[Option].emplace(ConvertedValue); + return ConvertedValue; + } else { + LOGMAN_MSG_A_FMT("Couldn't Convert {} to specified type!", StrVal); + } + } + + FEX_UNREACHABLE; + } + private: void MergeConfigMap(const LayerOptions& Options); - void MergeEnvironmentVariables(const ConfigOption& Option, const LayerValue& Value); + void MergeEnvironmentVariables(const ConfigOption& Option, const DefaultValues::Type::StringArrayType& Value); }; void MetaLayer::Load() { @@ -161,7 +192,7 @@ void MetaLayer::Load() { } -void MetaLayer::MergeEnvironmentVariables(const ConfigOption& Option, const LayerValue& Value) { +void MetaLayer::MergeEnvironmentVariables(const ConfigOption& Option, const DefaultValues::Type::StringArrayType& Value) { // Environment variables need a bit of additional work // We want to merge the arrays rather than overwrite entirely auto MetaEnvironment = OptionMap.find(Option); @@ -173,7 +204,7 @@ void MetaLayer::MergeEnvironmentVariables(const ConfigOption& Option, const Laye // If an environment variable exists in both current meta and in the incoming layer then the meta layer value is overwritten fextl::unordered_map LookupMap; - const auto AddToMap = [&LookupMap](const FEXCore::Config::LayerValue& Value) { + const auto AddToMap = [&LookupMap](const DefaultValues::Type::StringArrayType& Value) { for (const auto& EnvVar : Value) { const auto ItEq = EnvVar.find_first_of('='); if (ItEq == fextl::string::npos) { @@ -189,7 +220,7 @@ void MetaLayer::MergeEnvironmentVariables(const ConfigOption& Option, const Laye } }; - AddToMap(MetaEnvironment->second); + AddToMap(std::get(MetaEnvironment->second)); AddToMap(Value); // Now with the two layers merged in the map @@ -197,7 +228,7 @@ void MetaLayer::MergeEnvironmentVariables(const ConfigOption& Option, const Laye Erase(Option); for (auto& Val : LookupMap) { // Set will emplace multiple options in to its list - Set(Option, Val.first + "=" + Val.second); + AppendStrArrayValue(Option, Val.first + "=" + Val.second); } } @@ -205,7 +236,8 @@ void MetaLayer::MergeConfigMap(const LayerOptions& Options) { // Insert this layer's options, overlaying previous options that exist here for (auto& it : Options) { if (it.first == FEXCore::Config::ConfigOption::CONFIG_ENV || it.first == FEXCore::Config::ConfigOption::CONFIG_HOSTENV) { - MergeEnvironmentVariables(it.first, it.second); + LOGMAN_THROW_A_FMT(std::holds_alternative(it.second), "Tried to get config of invalid type!"); + MergeEnvironmentVariables(it.first, std::get(it.second)); } else { OptionMap.insert_or_assign(it.first, it.second); } @@ -214,7 +246,7 @@ void MetaLayer::MergeConfigMap(const LayerOptions& Options) { void Initialize() { AddLayer(fextl::make_unique(FEXCore::Config::LayerType::LAYER_TOP)); - Meta = ConfigLayers.begin()->second.get(); + Meta = dynamic_cast(ConfigLayers.begin()->second.get()); } void Shutdown() { @@ -322,7 +354,7 @@ void ReloadMetaLayer() { auto ExpandPathIfExists = [&ContainerPrefix](FEXCore::Config::ConfigOption Config, const fextl::string& PathName) { const auto NewPath = ExpandPath(ContainerPrefix, PathName); if (!NewPath.empty()) { - FEXCore::Config::EraseSet(Config, NewPath); + FEXCore::Config::Set(Config, NewPath); } }; @@ -331,7 +363,7 @@ void ReloadMetaLayer() { const auto ExpandedString = ExpandPath(ContainerPrefix, *PathName); if (!ExpandedString.empty()) { // Adjust the path if it ended up being relative - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, ExpandedString); + FEXCore::Config::Set(FEXCore::Config::CONFIG_ROOTFS, ExpandedString); } else if (!PathName->empty()) { // If the filesystem doesn't exist then let's see if it exists in the fex-emu folder const auto PathNameCopy = *PathName; @@ -339,7 +371,7 @@ void ReloadMetaLayer() { for (auto DirectoryFetchers : {GetDataDirectory, GetConfigDirectory}) { fextl::string NamedRootFS = DirectoryFetchers(Global) + "RootFS/" + PathNameCopy; if (FHU::Filesystem::Exists(NamedRootFS)) { - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, NamedRootFS); + FEXCore::Config::Set(FEXCore::Config::CONFIG_ROOTFS, NamedRootFS); } } } @@ -358,7 +390,7 @@ void ReloadMetaLayer() { const auto ExpandedString = ExpandPath(ContainerPrefix, *PathName); if (!ExpandedString.empty()) { // Adjust the path if it ended up being relative - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_THUNKCONFIG, ExpandedString); + FEXCore::Config::Set(FEXCore::Config::CONFIG_THUNKCONFIG, ExpandedString); } else if (!PathName->empty()) { // If the filesystem doesn't exist then let's see if it exists in the fex-emu folder const auto PathNameCopy = *PathName; @@ -366,7 +398,7 @@ void ReloadMetaLayer() { for (auto DirectoryFetchers : {GetDataDirectory, GetConfigDirectory}) { fextl::string NamedConfig = DirectoryFetchers(Global) + "ThunkConfigs/" + PathNameCopy; if (FHU::Filesystem::Exists(NamedConfig)) { - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_THUNKCONFIG, NamedConfig); + FEXCore::Config::Set(FEXCore::Config::CONFIG_THUNKCONFIG, NamedConfig); } } } @@ -383,8 +415,8 @@ void ReloadMetaLayer() { // If DumpIR is set but no PassManagerDumpIR configuration is set, then default to `afteropt` const auto PathName = *Meta->Get(FEXCore::Config::CONFIG_DUMPIR); if (*PathName != "no") { - EraseSet(FEXCore::Config::ConfigOption::CONFIG_PASSMANAGERDUMPIR, - fextl::fmt::format("{}", static_cast(FEXCore::Config::PassManagerDumpIR::AFTEROPT))); + Set(FEXCore::Config::ConfigOption::CONFIG_PASSMANAGERDUMPIR, + fextl::fmt::format("{}", static_cast(FEXCore::Config::PassManagerDumpIR::AFTEROPT))); } } @@ -402,7 +434,7 @@ bool Exists(ConfigOption Option) { return Meta->OptionExists(Option); } -std::optional All(ConfigOption Option) { +std::optional All(ConfigOption Option) { return Meta->All(Option); } @@ -410,6 +442,11 @@ std::optional Get(ConfigOption Option) { return Meta->Get(Option); } +template +std::optional GetConv(ConfigOption Option) { + return Meta->GetConv(Option); +} + void Set(ConfigOption Option, std::string_view Data) { Meta->Set(Option, Data); } @@ -418,31 +455,14 @@ void Erase(ConfigOption Option) { Meta->Erase(Option); } -void EraseSet(ConfigOption Option, std::string_view Data) { - Meta->EraseSet(Option, Data); -} - -template -T Value::Get(FEXCore::Config::ConfigOption Option) { - T Result; - auto Value = FEXCore::Config::Get(Option); - - if (!FEXCore::StrConv::Conv(**Value, &Result)) { - LOGMAN_MSG_A_FMT("Attempted to convert invalid value"); - } - return Result; -} - template T Value::GetIfExists(FEXCore::Config::ConfigOption Option, T Default) { - T Result; - auto Value = FEXCore::Config::Get(Option); - - if (Value && FEXCore::StrConv::Conv(**Value, &Result)) { - return Result; - } else { - return Default; + auto Value = FEXCore::Config::GetConv(Option); + if (Value) { + return *Value; } + + return Default; } template<> diff --git a/FEXCore/include/FEXCore/Config/Config.h b/FEXCore/include/FEXCore/Config/Config.h index 6ca3369a2..f23f6c1dd 100644 --- a/FEXCore/include/FEXCore/Config/Config.h +++ b/FEXCore/include/FEXCore/Config/Config.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace FEXCore::Config { namespace Handler { @@ -138,7 +139,9 @@ FEX_DEFAULT_VISIBILITY const fextl::string& GetConfigDirectory(bool Global); FEX_DEFAULT_VISIBILITY const fextl::string& GetConfigFileLocation(bool Global = false); FEX_DEFAULT_VISIBILITY fextl::string GetApplicationConfig(const std::string_view Program, bool Global); -using LayerValue = fextl::list; +using LayerValue = + std::variant< fextl::string, DefaultValues::Type::StringArrayType, uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, bool >; + using LayerOptions = fextl::unordered_map; class FEX_DEFAULT_VISIBILITY Layer { @@ -152,13 +155,16 @@ public: return OptionMap.find(Option) != OptionMap.end(); } - std::optional All(ConfigOption Option) { + std::optional All(ConfigOption Option) { const auto it = OptionMap.find(Option); if (it == OptionMap.end()) { return std::nullopt; } - return &it->second; + auto& Value = it->second; + LOGMAN_THROW_A_FMT(std::holds_alternative(Value), "Tried to get config of invalid type!"); + + return &std::get(Value); } std::optional Get(ConfigOption Option) { @@ -167,31 +173,44 @@ public: return std::nullopt; } - return &it->second.front(); + auto& Value = it->second; + LOGMAN_THROW_A_FMT(std::holds_alternative(Value), "Tried to get config of invalid type!"); + + return &std::get(Value); } + // Set will overwrite the object with a fextl::string without tests. void Set(ConfigOption Option, const char* Data) { LOGMAN_THROW_A_FMT(Data != nullptr, "Data can't be null"); - OptionMap[Option].emplace_back(fextl::string(Data)); + OptionMap[Option].emplace(fextl::string(Data)); } void Set(ConfigOption Option, std::string_view Data) { - OptionMap[Option].emplace_back(fextl::string(Data)); + OptionMap[Option].emplace(fextl::string(Data)); } void Set(ConfigOption Option, fextl::string Data) { - OptionMap[Option].emplace_back(std::move(Data)); + OptionMap[Option].emplace(std::move(Data)); } void Set(ConfigOption Option, std::optional Data) { if (Data) { - OptionMap[Option].emplace_back(std::move(*Data)); + OptionMap[Option].emplace(std::move(*Data)); } } - void EraseSet(ConfigOption Option, std::string_view Data) { - Erase(Option); - Set(Option, Data); + // AppendStrArrayValue will append strings to its StringArrayType. + // If the value was previously a different type, then throw an assert. + void AppendStrArrayValue(ConfigOption Option, std::string_view Data) { + auto it = OptionMap.find(Option); + if (it == OptionMap.end()) { + // If the option didn't exist as a StringArrayType yet, emplace it. + it = OptionMap.emplace(Option, DefaultValues::Type::StringArrayType {}).first; + } + + auto& Value = it->second; + LOGMAN_THROW_A_FMT(std::holds_alternative(Value), "Tried to get config of invalid type!"); + std::get(Value).emplace_back(Data); } void Erase(ConfigOption Option) { @@ -221,12 +240,10 @@ FEX_DEFAULT_VISIBILITY fextl::string FindContainerPrefix(); FEX_DEFAULT_VISIBILITY void AddLayer(fextl::unique_ptr _Layer); FEX_DEFAULT_VISIBILITY bool Exists(ConfigOption Option); -FEX_DEFAULT_VISIBILITY std::optional All(ConfigOption Option); +FEX_DEFAULT_VISIBILITY std::optional All(ConfigOption Option); FEX_DEFAULT_VISIBILITY std::optional Get(ConfigOption Option); - FEX_DEFAULT_VISIBILITY void Set(ConfigOption Option, std::string_view Data); FEX_DEFAULT_VISIBILITY void Erase(ConfigOption Option); -FEX_DEFAULT_VISIBILITY void EraseSet(ConfigOption Option, std::string_view Data); template class FEX_DEFAULT_VISIBILITY Value { @@ -282,7 +299,6 @@ public: private: T ValueData {}; - static T Get(FEXCore::Config::ConfigOption Option); static T GetIfExists(FEXCore::Config::ConfigOption Option, T Default); static T GetIfExists(FEXCore::Config::ConfigOption Option, std::string_view Default); diff --git a/Source/Common/Config.cpp b/Source/Common/Config.cpp index 93a1e43e2..69c55ba4b 100644 --- a/Source/Common/Config.cpp +++ b/Source/Common/Config.cpp @@ -76,8 +76,14 @@ static char* SaveLayerToJSON(char* JsonBuffer, const FEXCore::Config::Layer* Lay break; } } - for (auto& var : it.second) { - JsonBuffer = json_str(JsonBuffer, Name.data(), var.c_str()); + if (std::holds_alternative(it.second)) { + JsonBuffer = json_str(JsonBuffer, Name.data(), std::get(it.second).c_str()); + } else if (std::holds_alternative(it.second)) { + for (auto& var : std::get(it.second)) { + JsonBuffer = json_str(JsonBuffer, Name.data(), var.c_str()); + } + } else { + LogMan::Msg::AFmt("Trying to store config with pre-converted type"); } } return json_objClose(JsonBuffer); @@ -289,6 +295,10 @@ void EnvLoader::Load() { #define OPT_BASE(type, group, enum, json, default) \ Value = GetVar(EnvMap, "FEX_" #enum); \ if (Value.has_value()) Set(FEXCore::Config::ConfigOption::CONFIG_##enum, *Value); +#define OPT_STRARRAY(group, enum, json, default) \ + Value = GetVar(EnvMap, "FEX_" #enum); \ + if (Value.has_value()) AppendStrArrayValue(FEXCore::Config::ConfigOption::CONFIG_##enum, *Value); + #include } diff --git a/Source/Common/FEXServerClient.cpp b/Source/Common/FEXServerClient.cpp index 1da733f92..f6206fac4 100644 --- a/Source/Common/FEXServerClient.cpp +++ b/Source/Common/FEXServerClient.cpp @@ -204,7 +204,7 @@ bool SetupClient(std::string_view InterpreterPath) { fextl::string RootFSPath = FEXServerClient::RequestRootFSPath(ServerFD); //// If everything has passed then we can now update the rootfs path - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, RootFSPath); + FEXCore::Config::Set(FEXCore::Config::CONFIG_ROOTFS, RootFSPath); } return true; diff --git a/Source/Tools/CodeSizeValidation/Main.cpp b/Source/Tools/CodeSizeValidation/Main.cpp index 6261d2f0b..0bee1c1ca 100644 --- a/Source/Tools/CodeSizeValidation/Main.cpp +++ b/Source/Tools/CodeSizeValidation/Main.cpp @@ -447,7 +447,18 @@ public: for (auto& it : EnvConfigLookup) { if (auto Value = GetVar(it.first); Value) { - Set(it.second, *Value); +#define OPT_BASE(type, group, enum, json, default) // Nothing +#define OPT_STRARRAY(group, enum, json, default) \ + else if (it.second == FEXCore::Config::ConfigOption::CONFIG_##enum) { \ + AppendStrArrayValue(it.second, *Value); \ + } + + if (false) { + } +#include + else { + Set(it.second, *Value); + } } } } @@ -479,17 +490,17 @@ int main(int argc, char** argv, char** const envp) { // Setup configurations that this tool needs // Maximum one instruction. - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_MAXINST, "1"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_MAXINST, "1"); // Enable block disassembly. - FEXCore::Config::EraseSet( + FEXCore::Config::Set( FEXCore::Config::CONFIG_DISASSEMBLE, fextl::fmt::format("{}", static_cast(FEXCore::Config::Disassemble::BLOCKS | FEXCore::Config::Disassemble::STATS))); // Choose bitness. - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_IS64BIT_MODE, TestHeaderData->Bitness == 64 ? "1" : "0"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, TestHeaderData->Bitness == 64 ? "1" : "0"); // Disable telemetry, it can affect instruction counts. - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_DISABLETELEMETRY, "1"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_DISABLETELEMETRY, "1"); // Disable vixl simulator indirect calls as it can affect instruction counts. - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_DISABLE_VIXL_INDIRECT_RUNTIME_CALLS, "1"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_DISABLE_VIXL_INDIRECT_RUNTIME_CALLS, "1"); // Host feature override. Only supports overriding SVE width. enum HostFeatures { @@ -559,10 +570,10 @@ int main(int argc, char** argv, char** const envp) { if (TestHeaderData->EnabledHostFeatures & FEATURE_TSO) { // Always disable auto migration. - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_TSOAUTOMIGRATION, "0"); - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_TSOENABLED, "1"); - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_VECTORTSOENABLED, "1"); - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_MEMCPYSETTSOENABLED, "1"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_TSOAUTOMIGRATION, "0"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_TSOENABLED, "1"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_VECTORTSOENABLED, "1"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_MEMCPYSETTSOENABLED, "1"); } // Always enable ARMv8.1 LSE atomics. @@ -610,17 +621,17 @@ int main(int argc, char** argv, char** const envp) { if (TestHeaderData->DisabledHostFeatures & FEATURE_TSO) { // Always disable auto migration. - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_TSOAUTOMIGRATION, "0"); - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_TSOENABLED, "0"); - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_VECTORTSOENABLED, "0"); - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_MEMCPYSETTSOENABLED, "0"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_TSOAUTOMIGRATION, "0"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_TSOENABLED, "0"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_VECTORTSOENABLED, "0"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_MEMCPYSETTSOENABLED, "0"); } // Always enable preserve_all abi. HostFeatureControl |= static_cast(FEXCore::Config::HostFeatures::ENABLEPRESERVEALLABI); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_HOSTFEATURES, fextl::fmt::format("{}", HostFeatureControl)); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_FORCESVEWIDTH, fextl::fmt::format("{}", SVEWidth)); + FEXCore::Config::Set(FEXCore::Config::CONFIG_HOSTFEATURES, fextl::fmt::format("{}", HostFeatureControl)); + FEXCore::Config::Set(FEXCore::Config::CONFIG_FORCESVEWIDTH, fextl::fmt::format("{}", SVEWidth)); // Initialize static tables. FEXCore::Context::InitializeStaticTables(TestHeaderData->Bitness == 64 ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT); diff --git a/Source/Tools/FEXConfig/Main.cpp b/Source/Tools/FEXConfig/Main.cpp index 6deb2250e..4a0f1d778 100644 --- a/Source/Tools/FEXConfig/Main.cpp +++ b/Source/Tools/FEXConfig/Main.cpp @@ -74,7 +74,7 @@ void ConfigModel::Reload() { const char* OptionType = TypeId.data(); Item->setData(OptionType, Qt::UserRole + 1); - Item->setData(QString::fromStdString(Option.second.front().c_str()), Qt::UserRole + 2); + Item->setData(QString::fromStdString(std::get(Option.second).c_str()), Qt::UserRole + 2); appendRow(Item); } endResetModel(); @@ -99,12 +99,12 @@ bool ConfigModel::getBool(const QString& Name, bool) const { } void ConfigModel::setBool(const QString& Name, bool Value) { - LoadedConfig->EraseSet(NameToConfigLookup.at(Name.toStdString()), Value ? "1" : "0"); + LoadedConfig->Set(NameToConfigLookup.at(Name.toStdString()), Value ? "1" : "0"); Reload(); } void ConfigModel::setString(const QString& Name, const QString& Value) { - LoadedConfig->EraseSet(NameToConfigLookup.at(Name.toStdString()), Value.toStdString()); + LoadedConfig->Set(NameToConfigLookup.at(Name.toStdString()), Value.toStdString()); Reload(); } @@ -118,7 +118,7 @@ void ConfigModel::setStringList(const QString& Name, const QStringList& Values) } void ConfigModel::setInt(const QString& Name, int Value) { - LoadedConfig->EraseSet(NameToConfigLookup.at(Name.toStdString()), std::to_string(Value)); + LoadedConfig->Set(NameToConfigLookup.at(Name.toStdString()), std::to_string(Value)); Reload(); } @@ -358,18 +358,18 @@ static bool OpenFile(fextl::string Filename) { LoadedConfig->Load(); // Load default options and only overwrite only if the option didn't exist -#define OPT_BASE(type, group, enum, json, default) \ - if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \ - LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_##enum, std::to_string(default)); \ +#define OPT_BASE(type, group, enum, json, default) \ + if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \ + LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_##enum, std::to_string(default)); \ } #define OPT_STR(group, enum, json, default) \ if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \ - LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_##enum, default); \ + LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_##enum, default); \ } #define OPT_STRARRAY(group, enum, json, default) // Do nothing -#define OPT_STRENUM(group, enum, json, default) \ - if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \ - LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_##enum, std::to_string(FEXCore::ToUnderlying(default))); \ +#define OPT_STRENUM(group, enum, json, default) \ + if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \ + LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_##enum, std::to_string(FEXCore::ToUnderlying(default))); \ } #include diff --git a/Source/Tools/FEXLoader/FEXLoader.cpp b/Source/Tools/FEXLoader/FEXLoader.cpp index d7b4b21c8..e3fdaef08 100644 --- a/Source/Tools/FEXLoader/FEXLoader.cpp +++ b/Source/Tools/FEXLoader/FEXLoader.cpp @@ -324,7 +324,7 @@ int main(int argc, char** argv, char** const envp) { FEXCore::Config::Set(FEXCore::Config::CONFIG_INTERPRETER_INSTALLED, InterpreterInstalled ? "1" : "0"); #ifdef VIXL_SIMULATOR // If running under the vixl simulator, ensure that indirect runtime calls are enabled. - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_DISABLE_VIXL_INDIRECT_RUNTIME_CALLS, "0"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_DISABLE_VIXL_INDIRECT_RUNTIME_CALLS, "0"); #endif // Early check for process stall @@ -442,27 +442,27 @@ int main(int argc, char** argv, char** const envp) { if (ExecutedWithFD) { // Don't need to canonicalize Program.ProgramPath, Config loader will have resolved this already. - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_FILENAME, Program.ProgramPath); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_CONFIG_NAME, Program.ProgramName); + FEXCore::Config::Set(FEXCore::Config::CONFIG_APP_FILENAME, Program.ProgramPath); + FEXCore::Config::Set(FEXCore::Config::CONFIG_APP_CONFIG_NAME, Program.ProgramName); } else if (FEXFD != -1) { // Anonymous program. - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_FILENAME, ""); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_CONFIG_NAME, ""); + FEXCore::Config::Set(FEXCore::Config::CONFIG_APP_FILENAME, ""); + FEXCore::Config::Set(FEXCore::Config::CONFIG_APP_CONFIG_NAME, ""); } else { { char ExistsTempPath[PATH_MAX]; char* RealPath = realpath(Program.ProgramPath.c_str(), ExistsTempPath); if (RealPath) { - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_FILENAME, fextl::string(RealPath)); + FEXCore::Config::Set(FEXCore::Config::CONFIG_APP_FILENAME, fextl::string(RealPath)); } } - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_CONFIG_NAME, Program.ProgramName); + FEXCore::Config::Set(FEXCore::Config::CONFIG_APP_CONFIG_NAME, Program.ProgramName); } // Setup Thread handlers, so FEXCore can create threads. auto StackTracker = FEX::LinuxEmulation::Threads::SetupThreadHandlers(); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode() ? "1" : "0"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode() ? "1" : "0"); fextl::unique_ptr Allocator; fextl::vector Base48Bit; diff --git a/Source/Tools/FEXRootFSFetcher/Main.cpp b/Source/Tools/FEXRootFSFetcher/Main.cpp index 960165434..d5f6c02df 100644 --- a/Source/Tools/FEXRootFSFetcher/Main.cpp +++ b/Source/Tools/FEXRootFSFetcher/Main.cpp @@ -1044,7 +1044,7 @@ void SetRootFSAsDefault(const fextl::string& RootFS) { fextl::string Filename = FEXCore::Config::GetConfigFileLocation(); auto LoadedConfig = FEX::Config::CreateMainLayer(&Filename); LoadedConfig->Load(); - LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_ROOTFS, RootFS); + LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_ROOTFS, RootFS); FEX::Config::SaveLayerToJSON(Filename, LoadedConfig.get()); } } // namespace ConfigSetter diff --git a/Source/Tools/TestHarnessRunner/TestHarnessRunner.cpp b/Source/Tools/TestHarnessRunner/TestHarnessRunner.cpp index f27f0172c..d677ec4a3 100644 --- a/Source/Tools/TestHarnessRunner/TestHarnessRunner.cpp +++ b/Source/Tools/TestHarnessRunner/TestHarnessRunner.cpp @@ -232,7 +232,7 @@ int main(int argc, char** argv, char** const envp) { FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode() ? "1" : "0"); #ifdef VIXL_SIMULATOR // If running under the vixl simulator, ensure that indirect runtime calls are enabled. - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_DISABLE_VIXL_INDIRECT_RUNTIME_CALLS, "0"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_DISABLE_VIXL_INDIRECT_RUNTIME_CALLS, "0"); #endif #ifndef _WIN32 diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index 2fda9567b..47edda815 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -535,10 +535,10 @@ NTSTATUS ProcessInit() { FEXCore::Config::ReloadMetaLayer(); FEX::Windows::Logging::Init(); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_IS64BIT_MODE, "1"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, "1"); // Not applicable to Windows - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_TSOAUTOMIGRATION, "0"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_TSOAUTOMIGRATION, "0"); FEXCore::Profiler::Init("", ""); diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index 176083414..097cd462d 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -455,12 +455,12 @@ void BTCpuProcessInit() { FEXCore::Config::ReloadMetaLayer(); FEX::Windows::Logging::Init(); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_IS_INTERPRETER, "0"); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_INTERPRETER_INSTALLED, "0"); - FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_IS64BIT_MODE, "0"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_IS_INTERPRETER, "0"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_INTERPRETER_INSTALLED, "0"); + FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, "0"); // Not applicable to Windows - FEXCore::Config::EraseSet(FEXCore::Config::ConfigOption::CONFIG_TSOAUTOMIGRATION, "0"); + FEXCore::Config::Set(FEXCore::Config::ConfigOption::CONFIG_TSOAUTOMIGRATION, "0"); FEXCore::Profiler::Init("", "");