Skip to content

Commit

Permalink
fix(core): work around alignment problem when using Emscripten
Browse files Browse the repository at this point in the history
The data we read from the KMX file is not in places 32-bit aligned, e.g.
`dpGroupArray` will often start at a 16-bit boundary. Emscripten doesn't
like this and will abort the program if `SAFE_HEAP=1` is defined.

This change works around the problem by calling `CopyKeyboard` and thus
expanding the structure.

See #12844.
  • Loading branch information
ermshiperete committed Dec 20, 2024
1 parent 5dfa27b commit 6bef09f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 9 deletions.
18 changes: 10 additions & 8 deletions core/src/kmx/kmx_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ KMX_BOOL KMX_ProcessEvent::LoadKeyboardFromBlob(

*lpKeyboard = NULL;

#ifdef KMX_64BIT
#if defined(KMX_64BIT) || defined(__EMSCRIPTEN__)
// allocate enough memory for expanded data structure + original data.
// Expanded data structure is double the size of data on disk (8-byte
// pointers) - on disk the "pointers" are relative to the beginning of
// the file.
// Expanded data structure is no more than double the size of data on
// disk (8-byte pointers) - on disk the "pointers" are relative to the
// beginning of the file.
// We save the original data at the end of buf; we don't copy strings, so
// those will remain in the location at the end of the buffer.
buf = new KMX_BYTE[sz * 3];
Expand All @@ -84,7 +84,7 @@ KMX_BOOL KMX_ProcessEvent::LoadKeyboardFromBlob(
DebugLog("Not allocmem");
return FALSE;
}
#ifdef KMX_64BIT
#if defined(KMX_64BIT) || defined(__EMSCRIPTEN__)
filebase = buf + sz * 2;
#else
filebase = buf;
Expand All @@ -103,7 +103,7 @@ KMX_BOOL KMX_ProcessEvent::LoadKeyboardFromBlob(
return FALSE;
}

#ifdef KMX_64BIT
#if defined(KMX_64BIT) || defined(__EMSCRIPTEN__)
kbp = CopyKeyboard(buf, filebase);
#else
kbp = FixupKeyboard(buf, filebase);
Expand Down Expand Up @@ -132,13 +132,15 @@ PKMX_WCHAR KMX_ProcessEvent::StringOffset(PKMX_BYTE base, KMX_DWORD offset)
return (PKMX_WCHAR)(base + offset);
}

#ifdef KMX_64BIT
#if defined(KMX_64BIT) || defined(__EMSCRIPTEN__)
/**
CopyKeyboard will copy the data read into bufp from x86-sized structures into
x64-sized structures starting at `base`
* After this function finishes, we still need to keep the original data because
we don't copy the strings
This method is used on 64-bit architectures.
This method is used on 64-bit architectures as well as with Emscripten.
Emscripten requires 32-bit alignment for pointers which we don't always
have in the KMX data (see #12844).
*/
LPKEYBOARD KMX_ProcessEvent::CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base)
{
Expand Down
2 changes: 1 addition & 1 deletion core/src/kmx/kmx_processevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class KMX_ProcessEvent {
KMX_BOOL LoadKeyboardFromBlob(PKMX_BYTE buf, size_t sz, LPKEYBOARD* lpKeyboard);
KMX_BOOL VerifyKeyboard(PKMX_BYTE filebase, size_t sz);
KMX_BOOL VerifyChecksum(PKMX_BYTE buf, size_t sz);
#ifdef KMX_64BIT
#if defined(KMX_64BIT) || defined(__EMSCRIPTEN__)
LPKEYBOARD CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base);
#else
LPKEYBOARD FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base);
Expand Down

0 comments on commit 6bef09f

Please sign in to comment.