From d9faea4c1c90b56f0ea406abaaf529444e095b2d Mon Sep 17 00:00:00 2001 From: modeco80 Date: Tue, 26 Nov 2024 23:57:23 -0500 Subject: [PATCH] msagent.js/core: Clean up C++/WASM decompression code mostly just removing C-style casts and replacing the win32 LO* macros with constexpr functions, because they suck (also, add a gitignore scoped to msagent.js to ignore the obj/ of building the WASM decompression code) --- msagent.js/.gitignore | 1 + msagent.js/core/src/decompress.cpp | 50 +++++++++++++++++------------- msagent.js/core/src/decompress.ts | 5 ++- 3 files changed, 32 insertions(+), 24 deletions(-) create mode 100644 msagent.js/.gitignore diff --git a/msagent.js/.gitignore b/msagent.js/.gitignore new file mode 100644 index 0000000..65dcce3 --- /dev/null +++ b/msagent.js/.gitignore @@ -0,0 +1 @@ +core/obj diff --git a/msagent.js/core/src/decompress.cpp b/msagent.js/core/src/decompress.cpp index e6aefca..6ebe438 100644 --- a/msagent.js/core/src/decompress.cpp +++ b/msagent.js/core/src/decompress.cpp @@ -2,17 +2,25 @@ // Integer types from WASI-libc using usize = unsigned int; using u32 = unsigned int; +using u16 = unsigned short; using u8 = unsigned char; -#define LOWORD(x) (x & 0xffff) -#define LOBYTE(x) (x & 0xff) +template +constexpr auto LowOrderShortOf(T item) { + return static_cast(item & 0xffff); +} -#define PUBLIC __attribute__((visibility("default"))) extern "C" +template +constexpr auto LowOrderByteOf(T item) { + return static_cast(item & 0xff); +} -PUBLIC usize agentDecompressWASM(const void* pSrcData, usize pSrcSize, void* pTrgData, usize pTrgSize) { - const u8* lSrcPtr = (const u8*)pSrcData; +#define PUBLIC extern "C" __attribute__((visibility("default"))) + +PUBLIC usize agentDecompressWASM(const u8* pSrcData, usize pSrcSize, u8* pTrgData, usize pTrgSize) { + const u8* lSrcPtr = pSrcData; const u8* lSrcEnd = lSrcPtr + pSrcSize; - u8* lTrgPtr = (u8*)pTrgData; + u8* lTrgPtr = pTrgData; u8* lTrgEnd = lTrgPtr + pTrgSize; u32 lSrcQuad; u8 lTrgByte; @@ -38,15 +46,15 @@ PUBLIC usize agentDecompressWASM(const void* pSrcData, usize pSrcSize, void* pTr lSrcPtr += 5; while((lSrcPtr < lSrcEnd) && (lTrgPtr < lTrgEnd)) { - lSrcQuad = *(const u32*)(lSrcPtr - sizeof(u32)); + lSrcQuad = *reinterpret_cast(lSrcPtr - sizeof(u32)); - if(lSrcQuad & (1 << LOWORD(lBitCount))) { + if(lSrcQuad & (1 << LowOrderShortOf(lBitCount))) { lSrcOffset = 1; - if(lSrcQuad & (1 << LOWORD(lBitCount + 1))) { - if(lSrcQuad & (1 << LOWORD(lBitCount + 2))) { - if(lSrcQuad & (1 << LOWORD(lBitCount + 3))) { - lSrcQuad >>= LOWORD(lBitCount + 4); + if(lSrcQuad & (1 << LowOrderShortOf(lBitCount + 1))) { + if(lSrcQuad & (1 << LowOrderShortOf(lBitCount + 2))) { + if(lSrcQuad & (1 << LowOrderShortOf(lBitCount + 3))) { + lSrcQuad >>= LowOrderShortOf(lBitCount + 4); lSrcQuad &= 0x000FFFFF; if(lSrcQuad == 0x000FFFFF) { break; @@ -56,19 +64,19 @@ PUBLIC usize agentDecompressWASM(const void* pSrcData, usize pSrcSize, void* pTr lSrcOffset = 2; } else { - lSrcQuad >>= LOWORD(lBitCount + 4); + lSrcQuad >>= LowOrderShortOf(lBitCount + 4); lSrcQuad &= 0x00000FFF; lSrcQuad += 577; lBitCount += 16; } } else { - lSrcQuad >>= LOWORD(lBitCount + 3); + lSrcQuad >>= LowOrderShortOf(lBitCount + 3); lSrcQuad &= 0x000001FF; lSrcQuad += 65; lBitCount += 12; } } else { - lSrcQuad >>= LOWORD(lBitCount + 2); + lSrcQuad >>= LowOrderShortOf(lBitCount + 2); lSrcQuad &= 0x0000003F; lSrcQuad += 1; lBitCount += 8; @@ -76,16 +84,16 @@ PUBLIC usize agentDecompressWASM(const void* pSrcData, usize pSrcSize, void* pTr lSrcPtr += (lBitCount / 8); lBitCount &= 7; - lRunLgth = *(const u32*)(lSrcPtr - sizeof(u32)); + lRunLgth = *reinterpret_cast(lSrcPtr - sizeof(u32)); lRunCount = 0; - while(lRunLgth & (1 << LOWORD(lBitCount + lRunCount))) { + while(lRunLgth & (1 << LowOrderShortOf(lBitCount + lRunCount))) { lRunCount++; if(lRunCount > 11) { break; } } - lRunLgth >>= LOWORD(lBitCount + lRunCount + 1); + lRunLgth >>= LowOrderShortOf(lBitCount + lRunCount + 1); lRunLgth &= (1 << lRunCount) - 1; lRunLgth += 1 << lRunCount; lRunLgth += lSrcOffset; @@ -103,10 +111,10 @@ PUBLIC usize agentDecompressWASM(const void* pSrcData, usize pSrcSize, void* pTr lRunLgth--; } } else { - lSrcQuad >>= LOWORD(lBitCount + 1); + lSrcQuad >>= LowOrderShortOf(lBitCount + 1); lBitCount += 9; - lTrgByte = LOBYTE(lSrcQuad); + lTrgByte = LowOrderByteOf(lSrcQuad); *(lTrgPtr++) = lTrgByte; } @@ -114,5 +122,5 @@ PUBLIC usize agentDecompressWASM(const void* pSrcData, usize pSrcSize, void* pTr lBitCount &= 7; } - return (usize)(lTrgPtr - (u8*)pTrgData); + return static_cast(lTrgPtr - pTrgData); } diff --git a/msagent.js/core/src/decompress.ts b/msagent.js/core/src/decompress.ts index 449adcd..5da3b64 100644 --- a/msagent.js/core/src/decompress.ts +++ b/msagent.js/core/src/decompress.ts @@ -28,8 +28,7 @@ function compressWASMGetMemory(): WebAssembly.Memory { // Decompress Agent compressed data. This compression algorithm sucks. // [dest] is to be preallocated to the decompressed data size. export function compressDecompress(src: Uint8Array, dest: Uint8Array) { - // Grow the WASM heap if needed. Funnily enough, this code is never hit in most - // ACSes, so IDK if it's even needed + // Grow the WASM heap if needed. compressWasm.growHeapTo(src.length + dest.length); let memory = compressWASMGetMemory(); @@ -41,7 +40,7 @@ export function compressDecompress(src: Uint8Array, dest: Uint8Array) { // Call the WASM compression routine let nrBytesDecompressed = compressWasmGetExports().agentDecompressWASM(0, src.length, src.length, dest.length); - if (nrBytesDecompressed != dest.length) throw new Error(`decompression failed: ${nrBytesDecompressed} != ${dest.length}`); + if (nrBytesDecompressed != dest.length) throw new Error(`Decompression failed: Output ${nrBytesDecompressed} != expected ${dest.length}`); // The uncompressed data is located at memory[src.length..dest.length]. // Copy it into the destination buffer.