Fixed crash in message dispatcher after 'meta unload'.

Various cosmetic changes.
This commit is contained in:
jeefo 2019-09-14 23:13:55 +03:00
commit ff6c56aeac
37 changed files with 949 additions and 602 deletions

View file

@ -13,14 +13,12 @@
#define CR_NAMESPACE_BEGIN namespace cr {
#define CR_NAMESPACE_END }
// undef base max
#if defined (max)
# undef max
#endif
// undef base min
#if defined (min)
# undef min
// disable microsoft deprecation warning
#if defined (_MSC_VER)
# if !defined (_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE
# define _WINSOCK_DEPRECATED_NO_WARNINGS
# endif
#endif
#include <stdio.h>
@ -34,13 +32,13 @@ CR_NAMESPACE_BEGIN
// some useful type definitions
//
namespace types {
using int8 = signed char;
using int16 = signed short;
using int32 = signed int;
using uint8 = unsigned char;
using uint16 = unsigned short;
using uint32 = unsigned int;
using uint64 = unsigned long long;
using int8 = signed char;
using int16 = signed short;
using int32 = signed int;
using uint8 = unsigned char;
using uint16 = unsigned short;
using uint32 = unsigned int;
using uint64 = unsigned long long;
}
// make types available for our own use

View file

@ -19,7 +19,7 @@ CR_NAMESPACE_BEGIN
// template for hashing our string
template <typename K> struct StringHash {
uint32 operator () (const K &key) const {
char *str = const_cast <char *> (key.chars ());
auto str = const_cast <char *> (key.chars ());
uint32 hash = 0;
while (*str++) {
@ -68,6 +68,7 @@ namespace detail {
template <class K, class V, class H = StringHash <K>, size_t HashSize = 36> class Dictionary final : public DenyCopying {
private:
using DictBucket = detail::DictionaryBucket <K, V>;
using DictList = detail::DictionaryList;
public:
enum : size_t {
@ -75,7 +76,7 @@ public:
};
private:
Array <detail::DictionaryList *> m_table;
Array <DictList *> m_table;
Array <DictBucket> m_buckets;
H m_hasher;
@ -98,7 +99,7 @@ private:
size_t created = m_buckets.length ();
m_buckets.resize (created + 1);
auto allocated = alloc.allocate <detail::DictionaryList> ();
auto allocated = alloc.allocate <DictList> ();
allocated->index = created;
allocated->next = m_table[pos];
@ -163,7 +164,7 @@ public:
auto pos = hashed % m_table.length ();
auto *bucket = m_table[pos];
detail::DictionaryList *next = nullptr;
DictList *next = nullptr;
while (bucket != nullptr) {
if (m_buckets[bucket->index].hash == hashed) {

View file

@ -35,6 +35,10 @@ public:
public:
bool open (const String &file, const String &mode) {
if (*this) {
close ();
}
if ((m_handle = fopen (file.chars (), mode.chars ())) == nullptr) {
return false;
}

View file

@ -20,15 +20,25 @@ CR_NAMESPACE_BEGIN
class SimpleHook : DenyCopying {
private:
enum : uint32 {
CodeLength = 12
#if defined (CR_ARCH_X64)
CodeLength = 14
#else
CodeLength = 6
#endif
};
#if defined (CR_ARCH_X64)
using uint = uint64;
#else
using uint = uint32;
#endif
private:
bool m_patched;
uint32 m_pageSize;
uint32 m_origFunc;
uint32 m_hookFunc;
uint m_pageSize;
uint m_origFunc;
uint m_hookFunc;
uint8 m_origBytes[CodeLength] {};
uint8 m_hookBytes[CodeLength] {};
@ -43,11 +53,13 @@ private:
#else
m_pageSize = sysconf (_SC_PAGESIZE);
#endif
}
}
inline void *align (void *address) {
#if !defined (CR_WINDOWS)
void *align (void *address) {
return reinterpret_cast <void *> ((reinterpret_cast <long> (address) & ~(m_pageSize - 1)));
}
#endif
bool unprotect () {
auto orig = reinterpret_cast <void *> (m_origFunc);
@ -74,25 +86,36 @@ public:
public:
bool patch (void *address, void *replacement) {
if (plat.isArm) {
const uint16 jmp = 0x25ff;
if (plat.arm) {
return false;
}
uint8 *ptr = reinterpret_cast <uint8 *> (address);
auto ptr = reinterpret_cast <uint8 *> (address);
while (*reinterpret_cast <uint16 *> (ptr) == 0x25ff) {
ptr = **reinterpret_cast <uint8 * **> ((ptr + 2));
while (*reinterpret_cast <uint16 *> (ptr) == jmp) {
ptr = **reinterpret_cast <uint8 * **> (ptr + 2);
}
m_origFunc = reinterpret_cast <uint32> (ptr);
m_origFunc = reinterpret_cast <uint> (address);
if (!m_origFunc) {
return false;
}
m_hookFunc = reinterpret_cast <uint32> (replacement);
m_hookFunc = reinterpret_cast <uint> (replacement);
m_hookBytes[0] = 0x68;
m_hookBytes[5] = 0xc3;
if (plat.x64) {
const uint16 nop = 0x00000000;
*reinterpret_cast <uint32 *> (&m_hookBytes[1]) = m_hookFunc;
memcpy (&m_hookBytes[0], &jmp, sizeof (uint16));
memcpy (&m_hookBytes[2], &nop, sizeof (uint16));
memcpy (&m_hookBytes[6], &replacement, sizeof (uint));
}
else {
m_hookBytes[0] = 0x68;
m_hookBytes[5] = 0xc3;
memcpy (&m_hookBytes[1], &m_hookFunc, sizeof (uint));
}
if (unprotect ()) {
memcpy (m_origBytes, reinterpret_cast <void *> (m_origFunc), CodeLength);
@ -130,6 +153,6 @@ public:
bool enabled () const {
return m_patched;
}
};
};
CR_NAMESPACE_END

View file

@ -374,19 +374,19 @@ public:
if (boundarySlash != String::InvalidIndex) {
boundaryName = localPath.substr (boundarySlash + 1);
}
const String &kBoundary = "---crlib_upload_boundary_1337";
const String &boundaryLine = "---crlib_upload_boundary_1337";
String request, start, end;
start.appendf ("--%s\r\n", kBoundary.chars ());
start.appendf ("--%s\r\n", boundaryLine.chars ());
start.appendf ("Content-Disposition: form-data; name='file'; filename='%s'\r\n", boundaryName.chars ());
start.append ("Content-Type: application/octet-stream\r\n\r\n");
end.appendf ("\r\n--%s--\r\n\r\n", kBoundary.chars ());
end.appendf ("\r\n--%s--\r\n\r\n", boundaryLine.chars ());
request.appendf ("POST /%s HTTP/1.1\r\n", uri.path.chars ());
request.appendf ("Host: %s\r\n", uri.host.chars ());
request.appendf ("User-Agent: %s\r\n", m_userAgent.chars ());
request.appendf ("Content-Type: multipart/form-data; boundary=%s\r\n", kBoundary.chars ());
request.appendf ("Content-Type: multipart/form-data; boundary=%s\r\n", boundaryLine.chars ());
request.appendf ("Content-Length: %d\r\n\r\n", file.length () + start.length () + end.length ());
// send the main request

View file

@ -67,7 +67,7 @@ private:
}
UniquePtr <LambdaFunctorWrapper> clone () const override {
return createUniqueBase <LambdaFunctor <T>, LambdaFunctorWrapper> (m_callable);
return makeUnique <LambdaFunctor <T>> (m_callable);
}
};
@ -93,7 +93,7 @@ private:
}
public:
Lambda () noexcept : Lambda (nullptr)
explicit Lambda () noexcept : Lambda (nullptr)
{ }
Lambda (decltype (nullptr)) noexcept : m_functor (nullptr), m_smallObject (false)
@ -124,7 +124,7 @@ public:
template <typename F> Lambda (F function) {
if (cr::fix (sizeof (function) > LamdaSmallBufferLength)) {
m_smallObject = false;
new (m_small) UniquePtr <LambdaFunctorWrapper> (createUniqueBase <LambdaFunctor <F>, LambdaFunctorWrapper> (cr::move (function)));
new (m_small) UniquePtr <LambdaFunctorWrapper> (makeUnique <LambdaFunctor <F>> (cr::move (function)));
}
else {
m_smallObject = true;

View file

@ -18,12 +18,8 @@
# include <fcntl.h>
# include <sys/stat.h>
# include <unistd.h>
#elif defined (CR_WINDOWS)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
CR_NAMESPACE_BEGIN
// handling dynamic library loading
@ -47,6 +43,10 @@ public:
public:
bool load (const String &file) noexcept {
if (*this) {
unload ();
}
#if defined (CR_WINDOWS)
m_handle = LoadLibraryA (file.chars ());
#else

View file

@ -14,11 +14,6 @@
#include <crlib/cr-files.h>
#include <crlib/cr-lambda.h>
#if defined (CR_WINDOWS)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
CR_NAMESPACE_BEGIN
class SimpleLogger final : public Singleton <SimpleLogger> {

View file

@ -70,6 +70,15 @@ CR_NAMESPACE_END
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <direct.h>
# if defined (max)
# undef max
# endif
# if defined (min)
# undef min
# endif
#else
# include <unistd.h>
# include <strings.h>
@ -77,8 +86,10 @@ CR_NAMESPACE_END
# include <sys/time.h>
#endif
#include <stdio.h>
#include <assert.h>
#include <locale.h>
#include <stdarg.h>
#if defined (CR_ANDROID)
# include <android/log.h>
@ -88,42 +99,42 @@ CR_NAMESPACE_BEGIN
// helper struct for platform detection
struct Platform : public Singleton <Platform> {
bool isWindows = false;
bool isLinux = false;
bool isOSX = false;
bool isAndroid = false;
bool isAndroidHardFP = false;
bool isX64 = false;
bool isArm = false;
bool win32 = false;
bool linux = false;
bool osx = false;
bool android = false;
bool hfp = false;
bool x64 = false;
bool arm = false;
Platform () {
#if defined(CR_WINDOWS)
isWindows = true;
win32 = true;
#endif
#if defined(CR_ANDROID)
isAndroid = true;
android = true;
# if defined (CR_ANDROID_HARD_FP)
isAndroidHardFP = true;
hfp = true;
# endif
#endif
#if defined(CR_LINUX)
isLinux = true;
linux = true;
#endif
#if defined(CR_OSX)
isOSX = true;
osx = true;
#endif
#if defined(CR_ARCH_X64) || defined(CR_ARCH_ARM64)
isX64 = true;
x64 = true;
#endif
#if defined(CR_ARCH_ARM)
isArm = true;
isAndroid = true;
arm = true;
android = true;
#endif
}

View file

@ -20,6 +20,38 @@
CR_NAMESPACE_BEGIN
namespace detail {
template <typename T> uint8 &getMostSignificantByte (T &object) {
return *(reinterpret_cast <uint8 *> (&object) + sizeof (object) - 1);
}
template <size_t N> bool getLeastSignificantBit (uint8 byte) {
return byte & cr::bit (N);
}
template <size_t N> bool getMostSignificantBit (uint8 byte) {
return byte & cr::bit (CHAR_BIT - N - 1);
}
template <size_t N> void setLeastSignificantBit (uint8 &byte, bool bit) {
if (bit) {
byte |= cr::bit (N);
}
else {
byte &= ~cr::bit (N);
}
}
template <size_t N> void setMostSignificantBit (uint8 &byte, bool bit) {
if (bit) {
byte |= cr::bit (CHAR_BIT - N - 1);
}
else {
byte &= ~cr::bit (CHAR_BIT - N - 1);
}
}
}
// small-string optimized string class, sso stuff based on: https://github.com/elliotgoodrich/SSO-23/
class String final {
public:
@ -30,7 +62,6 @@ public:
private:
enum : size_t {
ExcessSpace = 32,
CharBit = CHAR_BIT
};
private:
@ -77,8 +108,7 @@ public:
assign (ch);
}
String (String &&rhs) noexcept {
m_data = rhs.m_data;
String (String &&rhs) noexcept : m_data (rhs.m_data) {
rhs.setMoved ();
}
@ -87,35 +117,6 @@ public:
}
private:
template <typename T> static uint8 &getMostSignificantByte (T &object) {
return *(reinterpret_cast <uint8 *> (&object) + sizeof (object) - 1);
}
template <size_t N> static bool getLeastSignificantBit (uint8 byte) {
return byte & cr::bit (N);
}
template <size_t N> static bool getMostSignificantBit (uint8 byte) {
return byte & cr::bit (CharBit - N - 1);
}
template <size_t N> static void setLeastSignificantBit (uint8 &byte, bool bit) {
if (bit) {
byte |= cr::bit (N);
}
else {
byte &= ~cr::bit (N);
}
}
template <size_t N> static void setMostSignificantBit (uint8 &byte, bool bit) {
if (bit) {
byte |= cr::bit (CharBit - N - 1);
}
else {
byte &= ~cr::bit (CharBit - N - 1);
}
}
void destroy () {
if (!isSmall ()) {
@ -162,7 +163,7 @@ private:
}
bool isSmall () const {
return !getLeastSignificantBit <0> (m_data.small.length) && !getLeastSignificantBit <1> (m_data.small.length);
return !detail::getLeastSignificantBit <0> (m_data.small.length) && !detail::getLeastSignificantBit <1> (m_data.small.length);
}
void setSmallLength (uint8 length) {
@ -174,18 +175,18 @@ private:
}
void setDataNonSmall (size_t length, size_t capacity) {
uint8 &lengthHighByte = getMostSignificantByte (length);
uint8 &capacityHighByte = getMostSignificantByte (capacity);
uint8 &lengthHighByte = detail::getMostSignificantByte (length);
uint8 &capacityHighByte = detail::getMostSignificantByte (capacity);
const bool lengthHasHighBit = getMostSignificantBit <0> (lengthHighByte);
const bool capacityHasHighBit = getMostSignificantBit <0> (capacityHighByte);
const bool capacityHasSecHighBit = getMostSignificantBit <1> (capacityHighByte);
const bool lengthHasHighBit = detail::getMostSignificantBit <0> (lengthHighByte);
const bool capacityHasHighBit = detail::getMostSignificantBit <0> (capacityHighByte);
const bool capacityHasSecHighBit = detail::getMostSignificantBit <1> (capacityHighByte);
setMostSignificantBit <0> (lengthHighByte, capacityHasSecHighBit);
detail::setMostSignificantBit <0> (lengthHighByte, capacityHasSecHighBit);
capacityHighByte <<= 2;
setLeastSignificantBit <0> (capacityHighByte, capacityHasHighBit);
setLeastSignificantBit <1> (capacityHighByte, !lengthHasHighBit);
detail::setLeastSignificantBit <0> (capacityHighByte, capacityHasHighBit);
detail::setLeastSignificantBit <1> (capacityHighByte, !lengthHasHighBit);
m_data.big.length = length;
m_data.big.capacity = capacity;
@ -195,18 +196,18 @@ private:
size_t length = m_data.big.length;
size_t capacity = m_data.big.capacity;
uint8 &lengthHighByte = getMostSignificantByte (length);
uint8 &capacityHighByte = getMostSignificantByte (capacity);
uint8 &lengthHighByte = detail::getMostSignificantByte (length);
uint8 &capacityHighByte = detail::getMostSignificantByte (capacity);
const bool capacityHasHighBit = getLeastSignificantBit <0> (capacityHighByte);
const bool lengthHasHighBit = !getLeastSignificantBit <1> (capacityHighByte);
const bool capacityHasSecHighBit = getMostSignificantBit <0> (lengthHighByte);
const bool capacityHasHighBit = detail::getLeastSignificantBit <0> (capacityHighByte);
const bool lengthHasHighBit = !detail::getLeastSignificantBit <1> (capacityHighByte);
const bool capacityHasSecHighBit = detail::getMostSignificantBit <0> (lengthHighByte);
setMostSignificantBit <0> (lengthHighByte, lengthHasHighBit);
detail::setMostSignificantBit <0> (lengthHighByte, lengthHasHighBit);
capacityHighByte >>= 2;
setMostSignificantBit <0> (capacityHighByte, capacityHasHighBit);
setMostSignificantBit <1> (capacityHighByte, capacityHasSecHighBit);
detail::setMostSignificantBit <0> (capacityHighByte, capacityHasHighBit);
detail::setMostSignificantBit <1> (capacityHighByte, capacityHasSecHighBit);
return { length, capacity };
}

View file

@ -15,7 +15,7 @@
CR_NAMESPACE_BEGIN
// simple pair (twin)
template <typename A, typename B> class Twin {
template <typename A, typename B> class Twin final {
public:
A first;
B second;
@ -55,13 +55,4 @@ public:
}
};
// creating pairs
template <typename A, typename B> constexpr Twin <A, B> makeTwin (A &&a, B &&b) {
return Twin <A, B> (cr::forward <A> (a), cr::forward <B> (b));
}
template <typename A, typename B> constexpr Twin <A, B> makeTwin (const A &a, const B &b) {
return Twin <A, B> (a, b);
}
CR_NAMESPACE_END

View file

@ -41,10 +41,11 @@ private:
SmallArray <int32> m_prevTable;
public:
ULZ () {
explicit ULZ () {
m_hashTable.resize (HashLength);
m_prevTable.resize (WindowSize);
}
~ULZ () = default;
public:

View file

@ -21,12 +21,15 @@ private:
public:
UniquePtr () = default;
explicit UniquePtr (T *ptr) : m_ptr (ptr)
{ }
UniquePtr (UniquePtr &&rhs) noexcept : m_ptr (rhs.m_ptr) {
rhs.m_ptr = nullptr;
}
UniquePtr (UniquePtr &&rhs) noexcept : m_ptr (rhs.release ())
{ }
template <typename U> UniquePtr (UniquePtr <U> &&rhs) noexcept : m_ptr (rhs.release ())
{ }
~UniquePtr () {
destroy ();
@ -60,10 +63,14 @@ private:
public:
UniquePtr &operator = (UniquePtr &&rhs) noexcept {
if (this != &rhs) {
destroy ();
reset (rhs.release ());
}
return *this;
}
m_ptr = rhs.m_ptr;
rhs.m_ptr = nullptr;
template <typename U> UniquePtr &operator = (UniquePtr <U> &&rhs) noexcept {
if (this != &rhs) {
reset (rhs.release ());
}
return *this;
}
@ -87,13 +94,8 @@ public:
};
// create unique
template <typename T, typename... Args> UniquePtr <T> createUnique (Args &&... args) {
template <typename T, typename... Args> UniquePtr <T> makeUnique (Args &&... args) {
return UniquePtr <T> (alloc.create <T> (cr::forward <Args> (args)...));
}
// create unique (base class)
template <typename D, typename B, typename... Args> UniquePtr <B> createUniqueBase (Args &&... args) {
return UniquePtr <B> (alloc.create <D> (cr::forward <Args> (args)...));
}
CR_NAMESPACE_END