From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- js/src/zydis/Zycore/Format.c | 507 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 507 insertions(+) create mode 100644 js/src/zydis/Zycore/Format.c (limited to 'js/src/zydis/Zycore/Format.c') diff --git a/js/src/zydis/Zycore/Format.c b/js/src/zydis/Zycore/Format.c new file mode 100644 index 0000000000..0988247eff --- /dev/null +++ b/js/src/zydis/Zycore/Format.c @@ -0,0 +1,507 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + Original Author : Florian Bernd + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +#include "zydis/Zycore/Format.h" +#include "zydis/Zycore/LibC.h" + +/* ============================================================================================== */ +/* Constants */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Defines */ +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYCORE_MAXCHARS_DEC_32 10 +#define ZYCORE_MAXCHARS_DEC_64 20 +#define ZYCORE_MAXCHARS_HEX_32 8 +#define ZYCORE_MAXCHARS_HEX_64 16 + +/* ---------------------------------------------------------------------------------------------- */ +/* Lookup Tables */ +/* ---------------------------------------------------------------------------------------------- */ + +static const char* const DECIMAL_LOOKUP = + "00010203040506070809" + "10111213141516171819" + "20212223242526272829" + "30313233343536373839" + "40414243444546474849" + "50515253545556575859" + "60616263646566676869" + "70717273747576777879" + "80818283848586878889" + "90919293949596979899"; + +/* ---------------------------------------------------------------------------------------------- */ +/* Static strings */ +/* ---------------------------------------------------------------------------------------------- */ + +static const ZyanStringView STR_ADD = ZYAN_DEFINE_STRING_VIEW("+"); +static const ZyanStringView STR_SUB = ZYAN_DEFINE_STRING_VIEW("-"); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Internal macros */ +/* ============================================================================================== */ + +/** + * Writes a terminating '\0' character at the end of the string data. + */ +#define ZYCORE_STRING_NULLTERMINATE(string) \ + *(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) = '\0'; + +/* ============================================================================================== */ +/* Internal functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Decimal */ +/* ---------------------------------------------------------------------------------------------- */ + +#if defined(ZYAN_X86) || defined(ZYAN_ARM) || defined(ZYAN_EMSCRIPTEN) || defined(ZYAN_WASM) || defined(ZYAN_PPC) +ZyanStatus ZyanStringAppendDecU32(ZyanString* string, ZyanU32 value, ZyanU8 padding_length) +{ + if (!string) + { + return ZYAN_STATUS_INVALID_ARGUMENT; + } + + char buffer[ZYCORE_MAXCHARS_DEC_32]; + char *buffer_end = &buffer[ZYCORE_MAXCHARS_DEC_32]; + char *buffer_write_pointer = buffer_end; + while (value >= 100) + { + const ZyanU32 value_old = value; + buffer_write_pointer -= 2; + value /= 100; + ZYAN_MEMCPY(buffer_write_pointer, &DECIMAL_LOOKUP[(value_old - (value * 100)) * 2], 2); + } + buffer_write_pointer -= 2; + ZYAN_MEMCPY(buffer_write_pointer, &DECIMAL_LOOKUP[value * 2], 2); + + const ZyanUSize offset_odd = (ZyanUSize)(value < 10); + const ZyanUSize length_number = buffer_end - buffer_write_pointer - offset_odd; + const ZyanUSize length_total = ZYAN_MAX(length_number, padding_length); + const ZyanUSize length_target = string->vector.size; + + if (string->vector.size + length_total > string->vector.capacity) + { + ZYAN_CHECK(ZyanStringResize(string, string->vector.size + length_total - 1)); + } + + ZyanUSize offset_write = 0; + if (padding_length > length_number) + { + offset_write = padding_length - length_number; + ZYAN_MEMSET((char*)string->vector.data + length_target - 1, '0', offset_write); + } + + ZYAN_MEMCPY((char*)string->vector.data + length_target + offset_write - 1, + buffer_write_pointer + offset_odd, length_number); + string->vector.size = length_target + length_total; + ZYCORE_STRING_NULLTERMINATE(string); + + return ZYAN_STATUS_SUCCESS; +} +#endif + +ZyanStatus ZyanStringAppendDecU64(ZyanString* string, ZyanU64 value, ZyanU8 padding_length) +{ + if (!string) + { + return ZYAN_STATUS_INVALID_ARGUMENT; + } + + char buffer[ZYCORE_MAXCHARS_DEC_64]; + char *buffer_end = &buffer[ZYCORE_MAXCHARS_DEC_64]; + char *buffer_write_pointer = buffer_end; + while (value >= 100) + { + const ZyanU64 value_old = value; + buffer_write_pointer -= 2; + value /= 100; + ZYAN_MEMCPY(buffer_write_pointer, &DECIMAL_LOOKUP[(value_old - (value * 100)) * 2], 2); + } + buffer_write_pointer -= 2; + ZYAN_MEMCPY(buffer_write_pointer, &DECIMAL_LOOKUP[value * 2], 2); + + const ZyanUSize offset_odd = (ZyanUSize)(value < 10); + const ZyanUSize length_number = buffer_end - buffer_write_pointer - offset_odd; + const ZyanUSize length_total = ZYAN_MAX(length_number, padding_length); + const ZyanUSize length_target = string->vector.size; + + if (string->vector.size + length_total > string->vector.capacity) + { + ZYAN_CHECK(ZyanStringResize(string, string->vector.size + length_total - 1)); + } + + ZyanUSize offset_write = 0; + if (padding_length > length_number) + { + offset_write = padding_length - length_number; + ZYAN_MEMSET((char*)string->vector.data + length_target - 1, '0', offset_write); + } + + ZYAN_MEMCPY((char*)string->vector.data + length_target + offset_write - 1, + buffer_write_pointer + offset_odd, length_number); + string->vector.size = length_target + length_total; + ZYCORE_STRING_NULLTERMINATE(string); + + return ZYAN_STATUS_SUCCESS; +} + +/* ---------------------------------------------------------------------------------------------- */ +/* Hexadecimal */ +/* ---------------------------------------------------------------------------------------------- */ + +#if defined(ZYAN_X86) || defined(ZYAN_ARM) || defined(ZYAN_EMSCRIPTEN) || defined(ZYAN_WASM) || defined(ZYAN_PPC) +ZyanStatus ZyanStringAppendHexU32(ZyanString* string, ZyanU32 value, ZyanU8 padding_length, + ZyanBool uppercase) +{ + if (!string) + { + return ZYAN_STATUS_INVALID_ARGUMENT; + } + + const ZyanUSize len = string->vector.size; + ZyanUSize remaining = string->vector.capacity - string->vector.size; + + if (remaining < (ZyanUSize)padding_length) + { + ZYAN_CHECK(ZyanStringResize(string, len + padding_length - 1)); + remaining = padding_length; + } + + if (!value) + { + const ZyanU8 n = (padding_length ? padding_length : 1); + + if (remaining < (ZyanUSize)n) + { + ZYAN_CHECK(ZyanStringResize(string, string->vector.size + n - 1)); + } + + ZYAN_MEMSET((char*)string->vector.data + len - 1, '0', n); + string->vector.size = len + n; + ZYCORE_STRING_NULLTERMINATE(string); + + return ZYAN_STATUS_SUCCESS; + } + + ZyanU8 n = 0; + char* buffer = ZYAN_NULL; + for (ZyanI8 i = ZYCORE_MAXCHARS_HEX_32 - 1; i >= 0; --i) + { + const ZyanU8 v = (value >> i * 4) & 0x0F; + if (!n) + { + if (!v) + { + continue; + } + if (remaining <= (ZyanU8)i) + { + ZYAN_CHECK(ZyanStringResize(string, string->vector.size + i)); + } + buffer = (char*)string->vector.data + len - 1; + if (padding_length > i) + { + n = padding_length - i - 1; + ZYAN_MEMSET(buffer, '0', n); + } + } + ZYAN_ASSERT(buffer); + if (uppercase) + { + buffer[n++] = "0123456789ABCDEF"[v]; + } else + { + buffer[n++] = "0123456789abcdef"[v]; + } + } + string->vector.size = len + n; + ZYCORE_STRING_NULLTERMINATE(string); + + return ZYAN_STATUS_SUCCESS; +} +#endif + +ZyanStatus ZyanStringAppendHexU64(ZyanString* string, ZyanU64 value, ZyanU8 padding_length, + ZyanBool uppercase) +{ + if (!string) + { + return ZYAN_STATUS_INVALID_ARGUMENT; + } + + const ZyanUSize len = string->vector.size; + ZyanUSize remaining = string->vector.capacity - string->vector.size; + + if (remaining < (ZyanUSize)padding_length) + { + ZYAN_CHECK(ZyanStringResize(string, len + padding_length - 1)); + remaining = padding_length; + } + + if (!value) + { + const ZyanU8 n = (padding_length ? padding_length : 1); + + if (remaining < (ZyanUSize)n) + { + ZYAN_CHECK(ZyanStringResize(string, string->vector.size + n - 1)); + } + + ZYAN_MEMSET((char*)string->vector.data + len - 1, '0', n); + string->vector.size = len + n; + ZYCORE_STRING_NULLTERMINATE(string); + + return ZYAN_STATUS_SUCCESS; + } + + ZyanU8 n = 0; + char* buffer = ZYAN_NULL; + for (ZyanI8 i = ((value & 0xFFFFFFFF00000000) ? + ZYCORE_MAXCHARS_HEX_64 : ZYCORE_MAXCHARS_HEX_32) - 1; i >= 0; --i) + { + const ZyanU8 v = (value >> i * 4) & 0x0F; + if (!n) + { + if (!v) + { + continue; + } + if (remaining <= (ZyanU8)i) + { + ZYAN_CHECK(ZyanStringResize(string, string->vector.size + i)); + } + buffer = (char*)string->vector.data + len - 1; + if (padding_length > i) + { + n = padding_length - i - 1; + ZYAN_MEMSET(buffer, '0', n); + } + } + ZYAN_ASSERT(buffer); + if (uppercase) + { + buffer[n++] = "0123456789ABCDEF"[v]; + } else + { + buffer[n++] = "0123456789abcdef"[v]; + } + } + string->vector.size = len + n; + ZYCORE_STRING_NULLTERMINATE(string); + + return ZYAN_STATUS_SUCCESS; +} + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Insertion */ +/* ---------------------------------------------------------------------------------------------- */ + +//ZyanStatus ZyanStringInsertFormat(ZyanString* string, ZyanUSize index, const char* format, ...) +//{ +// +//} +// +///* ---------------------------------------------------------------------------------------------- */ +// +//ZyanStatus ZyanStringInsertDecU(ZyanString* string, ZyanUSize index, ZyanU64 value, +// ZyanUSize padding_length) +//{ +// +//} +// +//ZyanStatus ZyanStringInsertDecS(ZyanString* string, ZyanUSize index, ZyanI64 value, +// ZyanUSize padding_length, ZyanBool force_sign, const ZyanString* prefix) +//{ +// +//} +// +//ZyanStatus ZyanStringInsertHexU(ZyanString* string, ZyanUSize index, ZyanU64 value, +// ZyanUSize padding_length, ZyanBool uppercase) +//{ +// +//} +// +//ZyanStatus ZyanStringInsertHexS(ZyanString* string, ZyanUSize index, ZyanI64 value, +// ZyanUSize padding_length, ZyanBool uppercase, ZyanBool force_sign, const ZyanString* prefix) +//{ +// +//} + +/* ---------------------------------------------------------------------------------------------- */ +/* Appending */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +ZyanStatus ZyanStringAppendFormat(ZyanString* string, const char* format, ...) +{ + if (!string || !format) + { + return ZYAN_STATUS_INVALID_ARGUMENT; + } + + ZyanVAList arglist; + ZYAN_VA_START(arglist, format); + + const ZyanUSize len = string->vector.size; + + ZyanI32 w = ZYAN_VSNPRINTF((char*)string->vector.data + len - 1, + string->vector.capacity - len + 1, format, arglist); + if (w < 0) + { + ZYAN_VA_END(arglist); + return ZYAN_STATUS_FAILED; + } + if (w <= (ZyanI32)(string->vector.capacity - len)) + { + string->vector.size = len + w; + + ZYAN_VA_END(arglist); + return ZYAN_STATUS_SUCCESS; + } + + // The remaining capacity was not sufficent to fit the formatted string. Trying to resize .. + const ZyanStatus status = ZyanStringResize(string, string->vector.size + w - 1); + if (!ZYAN_SUCCESS(status)) + { + ZYAN_VA_END(arglist); + return status; + } + + w = ZYAN_VSNPRINTF((char*)string->vector.data + len - 1, + string->vector.capacity - string->vector.size + 1, format, arglist); + if (w < 0) + { + ZYAN_VA_END(arglist); + return ZYAN_STATUS_FAILED; + } + ZYAN_ASSERT(w <= (ZyanI32)(string->vector.capacity - string->vector.size)); + + ZYAN_VA_END(arglist); + return ZYAN_STATUS_SUCCESS; +} + +#endif // ZYAN_NO_LIBC + +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZyanStringAppendDecU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length) +{ +#if defined(ZYAN_X64) || defined(ZYAN_AARCH64) || defined(ZYAN_PPC64) || defined(ZYAN_RISCV64) + return ZyanStringAppendDecU64(string, value, padding_length); +#else + // Working with 64-bit values is slow on non 64-bit systems + if (value & 0xFFFFFFFF00000000) + { + return ZyanStringAppendDecU64(string, value, padding_length); + } + return ZyanStringAppendDecU32(string, (ZyanU32)value, padding_length); +#endif +} + +ZyanStatus ZyanStringAppendDecS(ZyanString* string, ZyanI64 value, ZyanU8 padding_length, + ZyanBool force_sign, const ZyanStringView* prefix) +{ + if (value < 0) + { + ZYAN_CHECK(ZyanStringAppend(string, &STR_SUB)); + if (prefix) + { + ZYAN_CHECK(ZyanStringAppend(string, prefix)); + } + return ZyanStringAppendDecU(string, ZyanAbsI64(value), padding_length); + } + + if (force_sign) + { + ZYAN_ASSERT(value >= 0); + ZYAN_CHECK(ZyanStringAppend(string, &STR_ADD)); + } + + if (prefix) + { + ZYAN_CHECK(ZyanStringAppend(string, prefix)); + } + return ZyanStringAppendDecU(string, value, padding_length); +} + +ZyanStatus ZyanStringAppendHexU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length, + ZyanBool uppercase) +{ +#if defined(ZYAN_X64) || defined(ZYAN_AARCH64) || defined(ZYAN_PPC64) || defined(ZYAN_RISCV64) + return ZyanStringAppendHexU64(string, value, padding_length, uppercase); +#else + // Working with 64-bit values is slow on non 64-bit systems + if (value & 0xFFFFFFFF00000000) + { + return ZyanStringAppendHexU64(string, value, padding_length, uppercase); + } + return ZyanStringAppendHexU32(string, (ZyanU32)value, padding_length, uppercase); +#endif +} + +ZyanStatus ZyanStringAppendHexS(ZyanString* string, ZyanI64 value, ZyanU8 padding_length, + ZyanBool uppercase, ZyanBool force_sign, const ZyanStringView* prefix) +{ + if (value < 0) + { + ZYAN_CHECK(ZyanStringAppend(string, &STR_SUB)); + if (prefix) + { + ZYAN_CHECK(ZyanStringAppend(string, prefix)); + } + return ZyanStringAppendHexU(string, ZyanAbsI64(value), padding_length, uppercase); + } + + if (force_sign) + { + ZYAN_ASSERT(value >= 0); + ZYAN_CHECK(ZyanStringAppend(string, &STR_ADD)); + } + + if (prefix) + { + ZYAN_CHECK(ZyanStringAppend(string, prefix)); + } + return ZyanStringAppendHexU(string, value, padding_length, uppercase); +} + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ -- cgit v1.2.3