3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-08-17 08:42:16 +00:00

Merge pull request #5292 from rocallahan/wasm-varargs

Fix vararg alignment
This commit is contained in:
KrystalDelusion 2025-08-16 10:29:36 +12:00 committed by GitHub
commit 4a324e1da8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -412,6 +412,70 @@ static std::string string_view_stringf(std::string_view spec, ...)
return result; return result;
} }
static int spec_parameter_size(std::string_view spec)
{
// Every valid spec starts with '%' which means the code below
// won't look before the spec start.
switch (spec[spec.size() - 1]) {
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
switch (spec[spec.size() - 2]) {
case 'h':
if (spec[spec.size() - 3] == 'h')
return sizeof(char);
return sizeof(short);
case 'l':
if (spec[spec.size() - 3] == 'l')
return sizeof(long long);
return sizeof(long);
case 'L':
case 'q':
return sizeof(long long);
case 'j':
return sizeof(intmax_t);
case 'z':
case 'Z':
return sizeof(size_t);
case 't':
return sizeof(ptrdiff_t);
}
return sizeof(int);
case 'e':
case 'E':
case 'f':
case 'F':
case 'g':
case 'G':
case 'a':
case 'A':
if (spec[spec.size() - 2] == 'L')
return sizeof(long double);
if (spec[spec.size() - 2] == 'l' && spec[spec.size() - 3] == 'l')
return sizeof(long double);
return sizeof(double);
case 'c':
if (spec[spec.size() - 2] == 'l') {
return sizeof(wchar_t);
}
return sizeof(unsigned char);
case 'C':
return sizeof(wchar_t);
case 's':
case 'p':
case 'S':
case 'n':
return sizeof(void *);
case 'm':
return sizeof(int);
default:
return -1;
}
}
template <typename Arg> template <typename Arg>
static void format_emit_stringf(std::string &result, std::string_view spec, int *dynamic_ints, static void format_emit_stringf(std::string &result, std::string_view spec, int *dynamic_ints,
DynamicIntCount num_dynamic_ints, Arg arg) DynamicIntCount num_dynamic_ints, Arg arg)
@ -439,7 +503,13 @@ void format_emit_long_long(std::string &result, std::string_view spec, int *dyna
result += std::to_string(static_cast<int>(arg)); result += std::to_string(static_cast<int>(arg));
return; return;
} }
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg); if (spec_parameter_size(spec) <= 4) {
// On some platforms (Wasm) we must ensure that the arg is properly aligned
// after the dynamic `int` parameters.
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, (int)arg);
} else {
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg);
}
} }
void format_emit_unsigned_long_long(std::string &result, std::string_view spec, int *dynamic_ints, void format_emit_unsigned_long_long(std::string &result, std::string_view spec, int *dynamic_ints,
@ -454,7 +524,13 @@ void format_emit_unsigned_long_long(std::string &result, std::string_view spec,
result += static_cast<char>(arg); result += static_cast<char>(arg);
return; return;
} }
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg); if (spec_parameter_size(spec) <= 4) {
// On some platforms (Wasm) we must ensure that the arg is properly aligned
// after the dynamic `int` parameters.
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, (unsigned int)arg);
} else {
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg);
}
} }
void format_emit_double(std::string &result, std::string_view spec, int *dynamic_ints, void format_emit_double(std::string &result, std::string_view spec, int *dynamic_ints,