Skip to content

Commit

Permalink
Merge pull request #12845 from keymanapp/fix/core/alignment
Browse files Browse the repository at this point in the history
fix(core): work around alignment problem when using Emscripten 🎼
  • Loading branch information
ermshiperete authored Jan 6, 2025
2 parents 5dfa27b + 69cb2fd commit 0176aa8
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
12 changes: 10 additions & 2 deletions common/include/km_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,20 @@

#if defined(__LP64__) || defined(_LP64)
/* 64-bit, g++ */
#define KMX_64BIT
#define KMX_REQUIRES_REALIGNMENT
#endif

#if defined(_WIN64) && !defined(USE_64)
/* 64-bit, Windows */
#define KMX_64BIT
#define KMX_REQUIRES_REALIGNMENT
#endif

#if defined(__EMSCRIPTEN__)
// Emscripten/WASM. Emscripten even though it uses 32-bit (and not 64-bit
// pointers like the 64-bit architectures above) requires 32-bit alignment
// for pointers which we don't always have in the KMX data from file
// (see #12844).
#define KMX_REQUIRES_REALIGNMENT
#endif

typedef uint32_t KMX_DWORD;
Expand Down
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
#ifdef KMX_REQUIRES_REALIGNMENT
// 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 for 64-bit architectures) - 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
#ifdef KMX_REQUIRES_REALIGNMENT
filebase = buf + sz * 2;
#else
filebase = buf;
Expand All @@ -103,7 +103,7 @@ KMX_BOOL KMX_ProcessEvent::LoadKeyboardFromBlob(
return FALSE;
}

#ifdef KMX_64BIT
#ifdef KMX_REQUIRES_REALIGNMENT
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
#ifdef KMX_REQUIRES_REALIGNMENT
/**
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
#ifdef KMX_REQUIRES_REALIGNMENT
LPKEYBOARD CopyKeyboard(PKMX_BYTE bufp, PKMX_BYTE base);
#else
LPKEYBOARD FixupKeyboard(PKMX_BYTE bufp, PKMX_BYTE base);
Expand Down

0 comments on commit 0176aa8

Please sign in to comment.