mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-17 20:43:07 -04:00
Mod API: Aggregate-initialize import/export records
Starting with VS 18 / cl 14.51, MSVC's constant evaluator rejects a pointer-to-member in a constant initializer that also contains any computed data, a consteval call or even a copy of a constexpr object (C2127). Hook records are now aggregate-initialized from literals only: the computed name bytes (vtable symbol + display name) are baked into char... template arguments and sizes/kinds are spelled inline.
This commit is contained in:
@@ -288,7 +288,7 @@ static bool parse_meta(NativeMod& native, LoadedMod& mod) {
|
||||
return invalid("truncated import record");
|
||||
}
|
||||
auto* record = reinterpret_cast<ModMetaImport*>(const_cast<uint8_t*>(cursor));
|
||||
if (!terminated_within(record->service_id, sizeof(record->service_id))) {
|
||||
if (!terminated_within(record->service_id.chars, sizeof(record->service_id.chars))) {
|
||||
return invalid("unterminated import service id");
|
||||
}
|
||||
parsed.imports.push_back(record);
|
||||
@@ -299,7 +299,7 @@ static bool parse_meta(NativeMod& native, LoadedMod& mod) {
|
||||
return invalid("truncated export record");
|
||||
}
|
||||
auto* record = reinterpret_cast<ModMetaExport*>(const_cast<uint8_t*>(cursor));
|
||||
if (!terminated_within(record->service_id, sizeof(record->service_id))) {
|
||||
if (!terminated_within(record->service_id.chars, sizeof(record->service_id.chars))) {
|
||||
return invalid("unterminated export service id");
|
||||
}
|
||||
parsed.exports.push_back(record);
|
||||
@@ -552,18 +552,18 @@ static ModManifestInfo build_manifest_info(const ModMetaParsed& parsed) {
|
||||
ModManifestInfo info;
|
||||
info.imports.reserve(parsed.imports.size());
|
||||
for (const auto* record : parsed.imports) {
|
||||
if (!svc::valid_service_id(record->service_id)) {
|
||||
if (!svc::valid_service_id(record->service_id.chars)) {
|
||||
continue;
|
||||
}
|
||||
info.imports.push_back({record->service_id, record->major_version,
|
||||
info.imports.push_back({record->service_id.chars, record->major_version,
|
||||
(record->rec.flags & SERVICE_IMPORT_OPTIONAL) == 0});
|
||||
}
|
||||
info.exports.reserve(parsed.exports.size());
|
||||
for (const auto* record : parsed.exports) {
|
||||
if (!svc::valid_service_id(record->service_id)) {
|
||||
if (!svc::valid_service_id(record->service_id.chars)) {
|
||||
continue;
|
||||
}
|
||||
info.exports.push_back({record->service_id, record->major_version});
|
||||
info.exports.push_back({record->service_id.chars, record->major_version});
|
||||
}
|
||||
return info;
|
||||
}
|
||||
@@ -608,11 +608,11 @@ static void warn_unpublished_deferred_exports(const LoadedMod& mod) {
|
||||
continue;
|
||||
}
|
||||
const auto* record =
|
||||
svc::find_service_record(serviceExport->service_id, serviceExport->major_version);
|
||||
svc::find_service_record(serviceExport->service_id.chars, serviceExport->major_version);
|
||||
if (record != nullptr && record->service == nullptr) {
|
||||
log::write(mod.metadata.id, LOG_LEVEL_WARN,
|
||||
"declared deferred service '{}@{}' but never published it during initialization",
|
||||
serviceExport->service_id, serviceExport->major_version);
|
||||
serviceExport->service_id.chars, serviceExport->major_version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ bool ModLoader::register_static_service_exports(LoadedMod& mod) {
|
||||
}
|
||||
|
||||
for (const auto* serviceExport : mod.native->parsed.exports) {
|
||||
if (!svc::valid_service_id(serviceExport->service_id)) {
|
||||
if (!svc::valid_service_id(serviceExport->service_id.chars)) {
|
||||
fail_mod(mod, MOD_INVALID_ARGUMENT, "Invalid service export descriptor");
|
||||
return false;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ bool ModLoader::register_static_service_exports(LoadedMod& mod) {
|
||||
}
|
||||
|
||||
const auto result =
|
||||
svc::register_service(serviceExport->service_id, serviceExport->major_version,
|
||||
svc::register_service(serviceExport->service_id.chars, serviceExport->major_version,
|
||||
serviceExport->minor_version, serviceExport->service, &mod, deferred);
|
||||
if (result != MOD_OK) {
|
||||
fail_mod(mod, result, "Service export registration failed");
|
||||
@@ -262,8 +262,8 @@ std::string ModLoader::describe_missing_import(
|
||||
continue;
|
||||
}
|
||||
for (const auto* serviceExport : other.native->parsed.exports) {
|
||||
if (svc::valid_service_id(serviceExport->service_id) &&
|
||||
std::string_view{serviceExport->service_id} == serviceId &&
|
||||
if (svc::valid_service_id(serviceExport->service_id.chars) &&
|
||||
std::string_view{serviceExport->service_id.chars} == serviceId &&
|
||||
serviceExport->major_version == majorVersion)
|
||||
{
|
||||
return fmt::format("Required service {}@{} unavailable: provider '{}' {}",
|
||||
@@ -282,12 +282,14 @@ bool ModLoader::resolve_service_imports(LoadedMod& mod) {
|
||||
}
|
||||
|
||||
for (const auto* serviceImport : mod.native->parsed.imports) {
|
||||
if (!svc::valid_service_id(serviceImport->service_id) || serviceImport->slot == nullptr) {
|
||||
if (!svc::valid_service_id(serviceImport->service_id.chars) ||
|
||||
serviceImport->slot == nullptr)
|
||||
{
|
||||
fail_mod(mod, MOD_INVALID_ARGUMENT, "Invalid service import descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto* service = svc::find_service(serviceImport->service_id,
|
||||
const auto* service = svc::find_service(serviceImport->service_id.chars,
|
||||
serviceImport->major_version, serviceImport->min_minor_version);
|
||||
if (service == nullptr) {
|
||||
*static_cast<const void**>(serviceImport->slot) = nullptr;
|
||||
@@ -296,8 +298,8 @@ bool ModLoader::resolve_service_imports(LoadedMod& mod) {
|
||||
}
|
||||
|
||||
fail_mod(mod, MOD_UNAVAILABLE,
|
||||
describe_missing_import(serviceImport->service_id, serviceImport->major_version,
|
||||
serviceImport->min_minor_version));
|
||||
describe_missing_import(serviceImport->service_id.chars,
|
||||
serviceImport->major_version, serviceImport->min_minor_version));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user