diff --git a/internal/c/common.h b/internal/c/common.h index 177613ada..e190b6de7 100644 --- a/internal/c/common.h +++ b/internal/c/common.h @@ -233,28 +233,6 @@ struct device_struct { # define DEVICETYPE_KEYBOARD 2 # define DEVICETYPE_MOUSE 3 -struct mem_block { - ptrszint offset; - ptrszint size; - int64 lock_id; // 64-bit key, must be present at lock's offset or memory region is invalid - ptrszint lock_offset; // pointer to lock - ptrszint type; // https://qb64phoenix.com/qb64wiki/index.php/MEM - ptrszint elementsize; - int32 image; - int32 sound; -}; - -struct mem_lock { - uint64 id; - int32 type; // required to know what action to take (if any) when a request is made to free the block - // 0=no security (eg. user defined block from _OFFSET) - // 1=C-malloc'ed block - // 2=image - // 3=sub/function scope block - // 4=array - // 5=sound - //---- type specific variables follow ---- - void *offset; // used by malloc'ed blocks to free them -}; +#include "mem.h" #endif // INC_COMMON_CPP diff --git a/internal/c/libqb.cpp b/internal/c/libqb.cpp index 455b79560..c251dd384 100644 --- a/internal/c/libqb.cpp +++ b/internal/c/libqb.cpp @@ -28,6 +28,7 @@ #include "http.h" #include "image.h" #include "keyhandler.h" +#include "mem.h" #include "mutex.h" #include "qbs.h" #include "rounding.h" @@ -1116,42 +1117,6 @@ uint16_t codepage437_to_unicode16[] = { */ -// QB64 memory blocks -uint64 mem_lock_id = 1073741823; // this value should never be 0 or 1 -int32 mem_lock_max = 10000; -int32 mem_lock_next = 0; -mem_lock *mem_lock_base = (mem_lock *)malloc(sizeof(mem_lock) * mem_lock_max); -mem_lock *mem_lock_tmp; - -int32 mem_lock_freed_max = 1000; // number of allocated entries -int32 mem_lock_freed_n = 0; // number of entries -ptrszint *mem_lock_freed = (ptrszint *)malloc(sizeof(ptrszint) * mem_lock_freed_max); - -void new_mem_lock() { - if (mem_lock_freed_n) { - mem_lock_tmp = (mem_lock *)mem_lock_freed[--mem_lock_freed_n]; - } else { - if (mem_lock_next == mem_lock_max) { - mem_lock_base = (mem_lock *)malloc(sizeof(mem_lock) * mem_lock_max); - mem_lock_next = 0; - } - mem_lock_tmp = &mem_lock_base[mem_lock_next++]; - } - mem_lock_tmp->id = ++mem_lock_id; -} - -void free_mem_lock(mem_lock *lock) { - lock->id = 0; // invalidate lock - if (lock->type == 1) - free(lock->offset); // malloc type - // add to freed list - if (mem_lock_freed_n == mem_lock_freed_max) { - mem_lock_freed_max *= 2; - mem_lock_freed = (ptrszint *)realloc(mem_lock_freed, sizeof(ptrszint) * mem_lock_freed_max); - } - mem_lock_freed[mem_lock_freed_n++] = (ptrszint)lock; -} - /* int32 allocated_bytes=0; void *malloc2(int x){ @@ -31543,91 +31508,6 @@ void sub__consoletitle(qbs *s) { #endif } -void sub__memfree(void *mem) { - // 1:malloc: memory will be freed if it still exists - // 2:images: will not be freed, no action will be taken - // exists? - if (((mem_block *)(mem))->lock_offset == NULL) { - error(309); - return; - } - if (((mem_lock *)(((mem_block *)(mem))->lock_offset))->id != ((mem_block *)(mem))->lock_id) { - error(307); - return; - } // memory has been freed - if (((mem_lock *)(((mem_block *)(mem))->lock_offset))->type == 0) { // no security - free_mem_lock((mem_lock *)((mem_block *)(mem))->lock_offset); - } - if (((mem_lock *)(((mem_block *)(mem))->lock_offset))->type == 1) { // malloc - free_mem_lock((mem_lock *)((mem_block *)(mem))->lock_offset); - } - // note: type 2(image) is freed when the image is freed - // invalidate caller's mem structure (avoids misconception that _MEMFREE failed) - ((mem_block *)(mem))->lock_id = 1073741821; -} - -extern mem_block func__mem_at_offset(ptrszint offset, ptrszint size) { - static mem_block b; - new_mem_lock(); - mem_lock_tmp->type = 0; // unsecured - b.lock_offset = (ptrszint)mem_lock_tmp; - b.lock_id = mem_lock_id; - b.offset = offset; - b.size = size; - b.type = 16384; //_MEMNEW type - b.elementsize = 1; - b.image = -1; - if ((size < 0) || is_error_pending()) { - b.type = 0; - b.size = 0; - b.offset = 0; - if (size < 0) - error(301); - } - return b; -} - -mem_block func__memnew(ptrszint bytes) { - static mem_block b; - new_mem_lock(); - b.lock_offset = (ptrszint)mem_lock_tmp; - b.lock_id = mem_lock_id; - b.type = 16384; //_MEMNEW type - b.elementsize = 1; - b.image = -1; - if (is_error_pending()) { - b.type = 0; - b.offset = 0; - b.size = 0; - mem_lock_tmp->type = 0; - return b; - } - - if (bytes < 0) { - // still create a block, but an invalid one and generate an error - error(5); - b.offset = 0; - b.size = 0; - mem_lock_tmp->type = 0; - } else { - if (!bytes) { - b.offset = 1; // non-zero=success - b.size = 0; - } else { - b.offset = (ptrszint)malloc(bytes); - if (!b.offset) { - b.size = 0; - mem_lock_tmp->type = 0; - } else { - b.size = bytes; - mem_lock_tmp->type = 1; - mem_lock_tmp->offset = (void *)b.offset; - } - } - } - return b; -} - mem_block func__memimage(int32 i, int32 passed) { static mem_block b; @@ -31690,166 +31570,6 @@ error: return b; } -int32 func__memexists(void *void_blk) { - static mem_block *blk; - blk = (mem_block *)void_blk; - if (((mem_block *)(blk))->lock_offset == NULL) - return 0; - if (((mem_lock *)(((mem_block *)(blk))->lock_offset))->id == ((mem_block *)(blk))->lock_id) - return -1; - return 0; -} - -void *func__memget(mem_block *blk, ptrszint off, ptrszint bytes) { - // checking A - if (((mem_block *)(blk))->lock_offset == NULL) { - error(309); - goto fail; - } - // checking B - if (off < ((mem_block *)(blk))->offset || (off + bytes) > (((mem_block *)(blk))->offset + ((mem_block *)(blk))->size) || - ((mem_lock *)(((mem_block *)(blk))->lock_offset))->id != ((mem_block *)(blk))->lock_id) { - // error reporting - if (((mem_lock *)(((mem_block *)(blk))->lock_offset))->id != ((mem_block *)(blk))->lock_id) { - error(308); - goto fail; - } - error(300); - goto fail; - } - return (void *)off; -//------------------------------------------------------------ -fail: - static void *fail_buffer; - fail_buffer = calloc(bytes, 1); - if (!fail_buffer) - error(518); // critical error: out of memory - return fail_buffer; -} - -void sub__memfill_nochecks(ptrszint doff, ptrszint dbytes, ptrszint soff, ptrszint sbytes) { - if (sbytes == 1) { - memset((void *)doff, *(uint8 *)soff, dbytes); - return; - } - static ptrszint si; - si = 0; - while (dbytes--) { - *(int8 *)(doff++) = *(int8 *)(soff + si++); - if (si >= sbytes) - si = 0; - } -} - -void sub__memfill(mem_block *dblk, ptrszint doff, ptrszint dbytes, ptrszint soff, ptrszint sbytes) { - if (((mem_block *)(dblk))->lock_offset == NULL) { - error(309); - return; - } - if (((mem_lock *)(((mem_block *)(dblk))->lock_offset))->id != ((mem_block *)(dblk))->lock_id) { - error(308); - return; - } - if ((dbytes < 0) || (sbytes == 0)) { - error(301); - return; - } - if (doff < ((mem_block *)(dblk))->offset || (doff + dbytes) > (((mem_block *)(dblk))->offset + ((mem_block *)(dblk))->size)) { - error(300); - return; - } - sub__memfill_nochecks(doff, dbytes, soff, sbytes); -} - -void sub__memfill_1(mem_block *dblk, ptrszint doff, ptrszint dbytes, int8 val) { sub__memfill(dblk, doff, dbytes, (ptrszint)&val, 1); } -void sub__memfill_nochecks_1(ptrszint doff, ptrszint dbytes, int8 val) { sub__memfill_nochecks(doff, dbytes, (ptrszint)&val, 1); } -void sub__memfill_2(mem_block *dblk, ptrszint doff, ptrszint dbytes, int16 val) { sub__memfill(dblk, doff, dbytes, (ptrszint)&val, 2); } -void sub__memfill_nochecks_2(ptrszint doff, ptrszint dbytes, int16 val) { sub__memfill_nochecks(doff, dbytes, (ptrszint)&val, 2); } -void sub__memfill_4(mem_block *dblk, ptrszint doff, ptrszint dbytes, int32 val) { sub__memfill(dblk, doff, dbytes, (ptrszint)&val, 4); } -void sub__memfill_nochecks_4(ptrszint doff, ptrszint dbytes, int32 val) { sub__memfill_nochecks(doff, dbytes, (ptrszint)&val, 4); } -void sub__memfill_8(mem_block *dblk, ptrszint doff, ptrszint dbytes, int64 val) { sub__memfill(dblk, doff, dbytes, (ptrszint)&val, 8); } -void sub__memfill_nochecks_8(ptrszint doff, ptrszint dbytes, int64 val) { sub__memfill_nochecks(doff, dbytes, (ptrszint)&val, 8); } -void sub__memfill_SINGLE(mem_block *dblk, ptrszint doff, ptrszint dbytes, float val) { sub__memfill(dblk, doff, dbytes, (ptrszint)&val, 4); } -void sub__memfill_nochecks_SINGLE(ptrszint doff, ptrszint dbytes, float val) { sub__memfill_nochecks(doff, dbytes, (ptrszint)&val, 4); } -void sub__memfill_DOUBLE(mem_block *dblk, ptrszint doff, ptrszint dbytes, double val) { sub__memfill(dblk, doff, dbytes, (ptrszint)&val, 8); } -void sub__memfill_nochecks_DOUBLE(ptrszint doff, ptrszint dbytes, double val) { sub__memfill_nochecks(doff, dbytes, (ptrszint)&val, 8); } - -static uint8 memfill_FLOAT_padding[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 32 null bytes -void sub__memfill_FLOAT(mem_block *dblk, ptrszint doff, ptrszint dbytes, long double val) { - *(long double *)memfill_FLOAT_padding = val; - sub__memfill(dblk, doff, dbytes, (ptrszint)memfill_FLOAT_padding, 32); -} -void sub__memfill_nochecks_FLOAT(ptrszint doff, ptrszint dbytes, long double val) { - *(long double *)memfill_FLOAT_padding = val; - sub__memfill_nochecks(doff, dbytes, (ptrszint)memfill_FLOAT_padding, 32); -} - -void sub__memfill_OFFSET(mem_block *dblk, ptrszint doff, ptrszint dbytes, ptrszint val) { sub__memfill(dblk, doff, dbytes, (ptrszint)&val, sizeof(ptrszint)); } -void sub__memfill_nochecks_OFFSET(ptrszint doff, ptrszint dbytes, ptrszint val) { sub__memfill_nochecks(doff, dbytes, (ptrszint)&val, sizeof(ptrszint)); } - -void sub__memcopy(void *sblk, ptrszint soff, ptrszint bytes, void *dblk, ptrszint doff) { - // checking A - if (((mem_block *)(sblk))->lock_offset == NULL || ((mem_block *)(dblk))->lock_offset == NULL) { - // error reporting - if (((mem_block *)(sblk))->lock_offset == NULL && ((mem_block *)(dblk))->lock_offset == NULL) { - error(312); - return; - } - if (((mem_block *)(sblk))->lock_offset == NULL) { - error(310); - return; - } - error(311); - return; - } - // checking B - if (bytes < 0 || soff < ((mem_block *)(sblk))->offset || (soff + bytes) > (((mem_block *)(sblk))->offset + ((mem_block *)(sblk))->size) || - doff < ((mem_block *)(dblk))->offset || (doff + bytes) > (((mem_block *)(dblk))->offset + ((mem_block *)(dblk))->size) || - ((mem_lock *)(((mem_block *)(sblk))->lock_offset))->id != ((mem_block *)(sblk))->lock_id || - ((mem_lock *)(((mem_block *)(dblk))->lock_offset))->id != ((mem_block *)(dblk))->lock_id) { - // error reporting - if (((mem_lock *)(((mem_block *)(sblk))->lock_offset))->id != ((mem_block *)(sblk))->lock_id && - ((mem_lock *)(((mem_block *)(dblk))->lock_offset))->id != ((mem_block *)(dblk))->lock_id) { - error(313); - return; - } - if (((mem_lock *)(((mem_block *)(sblk))->lock_offset))->id != ((mem_block *)(sblk))->lock_id) { - error(305); - return; - } - if (((mem_lock *)(((mem_block *)(dblk))->lock_offset))->id != ((mem_block *)(dblk))->lock_id) { - error(306); - return; - } - if (bytes < 0) { - error(301); - return; - } - if (soff < ((mem_block *)(sblk))->offset || (soff + bytes) > (((mem_block *)(sblk))->offset + ((mem_block *)(sblk))->size)) { - if (doff < ((mem_block *)(dblk))->offset || (doff + bytes) > (((mem_block *)(dblk))->offset + ((mem_block *)(dblk))->size)) { - error(304); - return; - } - error(302); - return; - } - error(303); - return; - } - memmove((char *)doff, (char *)soff, bytes); -} - -mem_block func__mem(ptrszint offset, ptrszint size, int32 type, ptrszint elementsize, mem_lock *lock) { - static mem_block b; - b.lock_offset = (ptrszint)lock; - b.lock_id = lock->id; - b.offset = offset; - b.size = size; - b.type = type; - b.elementsize = elementsize; - b.image = -1; - return b; -} void GLUT_key_ascii(int32 key, int32 down) { #ifdef QB64_GLUT diff --git a/internal/c/libqb/build.mk b/internal/c/libqb/build.mk index 57b5885d5..a6bcb3c87 100644 --- a/internal/c/libqb/build.mk +++ b/internal/c/libqb/build.mk @@ -6,6 +6,7 @@ libqb-objs-y += $(PATH_LIBQB)/src/filepath.o libqb-objs-y += $(PATH_LIBQB)/src/filesystem.o libqb-objs-y += $(PATH_LIBQB)/src/datetime.o libqb-objs-y += $(PATH_LIBQB)/src/error_handle.o +libqb-objs-y += $(PATH_LIBQB)/src/mem.o libqb-objs-y += $(PATH_LIBQB)/src/rounding.o libqb-objs-y += $(PATH_LIBQB)/src/qbs.o libqb-objs-y += $(PATH_LIBQB)/src/qbs_str.o diff --git a/internal/c/libqb/include/mem.h b/internal/c/libqb/include/mem.h new file mode 100644 index 000000000..0876fe4e3 --- /dev/null +++ b/internal/c/libqb/include/mem.h @@ -0,0 +1,74 @@ +#pragma once + +#include + +struct mem_block { + intptr_t offset; + intptr_t size; + int64_t lock_id; // 64-bit key, must be present at lock's offset or memory region is invalid + intptr_t lock_offset; // pointer to lock + intptr_t type; // https://qb64phoenix.com/qb64wiki/index.php/MEM + intptr_t elementsize; + int32_t image; + int32_t sound; +}; + +#define INVALID_MEM_LOCK 1073741821 + +#define MEM_TYPE_NOSECURITY 0 +#define MEM_TYPE_MALLOC 1 +#define MEM_TYPE_IMAGE 2 +#define MEM_TYPE_SUBFUNC 3 +#define MEM_TYPE_ARRAY 4 +#define MEM_TYPE_SOUND 5 + +struct mem_lock { + int64_t id; + int32_t type; // required to know what action to take (if any) when a request is made to free the block + // 0=no security (eg. user defined block from _OFFSET) + // 1=C-malloc'ed block + // 2=image + // 3=sub/function scope block + // 4=array + // 5=sound + //---- type specific variables follow ---- + void *offset; // used by malloc'ed blocks to free them +}; + +extern uint64_t mem_lock_id; +extern mem_lock *mem_lock_tmp; +extern mem_lock *mem_lock_base; + +int32_t func__memexists(void *blk); + +void sub__memfill(mem_block *dblk, intptr_t doff, intptr_t dbytes, intptr_t soff, intptr_t sbytes); +void sub__memfill_nochecks(intptr_t doff, intptr_t dbytes, intptr_t soff, intptr_t sbytes); +void sub__memfill_1(mem_block *dblk, intptr_t doff, intptr_t dbytes, int8_t val); +void sub__memfill_nochecks_1(intptr_t doff, intptr_t dbytes, int8_t val); +void sub__memfill_2(mem_block *dblk, intptr_t doff, intptr_t dbytes, int16_t val); +void sub__memfill_nochecks_2(intptr_t doff, intptr_t dbytes, int16_t val); +void sub__memfill_4(mem_block *dblk, intptr_t doff, intptr_t dbytes, int32_t val); +void sub__memfill_nochecks_4(intptr_t doff, intptr_t dbytes, int32_t val); +void sub__memfill_8(mem_block *dblk, intptr_t doff, intptr_t dbytes, int64_t val); +void sub__memfill_nochecks_8(intptr_t doff, intptr_t dbytes, int64_t val); +void sub__memfill_SINGLE(mem_block *dblk, intptr_t doff, intptr_t dbytes, float val); +void sub__memfill_nochecks_SINGLE(intptr_t doff, intptr_t dbytes, float val); +void sub__memfill_DOUBLE(mem_block *dblk, intptr_t doff, intptr_t dbytes, double val); +void sub__memfill_nochecks_DOUBLE(intptr_t doff, intptr_t dbytes, double val); +void sub__memfill_FLOAT(mem_block *dblk, intptr_t doff, intptr_t dbytes, long double val); +void sub__memfill_nochecks_FLOAT(intptr_t doff, intptr_t dbytes, long double val); +void sub__memfill_OFFSET(mem_block *dblk, intptr_t doff, intptr_t dbytes, intptr_t val); +void sub__memfill_nochecks_OFFSET(intptr_t doff, intptr_t dbytes, intptr_t val); + +void *func__memget(mem_block *blk, intptr_t off, intptr_t bytes); + +void new_mem_lock(); +void free_mem_lock(mem_lock *lock); + +mem_block func__mem(intptr_t offset, intptr_t size, int32_t type, intptr_t elementsize, mem_lock *lock); +mem_block func__mem_at_offset(intptr_t offset, intptr_t size); + +mem_block func__memnew(intptr_t); +void sub__memfree(void *); + +void sub__memcopy(void *sblk, intptr_t soff, intptr_t bytes, void *dblk, intptr_t doff); diff --git a/internal/c/libqb/src/mem.cpp b/internal/c/libqb/src/mem.cpp new file mode 100644 index 000000000..d64b1eec9 --- /dev/null +++ b/internal/c/libqb/src/mem.cpp @@ -0,0 +1,292 @@ + +#include "libqb-common.h" + +#include +#include + +#include "error_handle.h" +#include "mem.h" + +// QB64 memory blocks +uint64_t mem_lock_id = 1073741823; // this value should never be 0 or 1 +int32_t mem_lock_max = 10000; +int32_t mem_lock_next = 0; +mem_lock *mem_lock_base = (mem_lock *)malloc(sizeof(mem_lock) * mem_lock_max); +mem_lock *mem_lock_tmp; + +int32_t mem_lock_freed_max = 1000; // number of allocated entries +int32_t mem_lock_freed_n = 0; // number of entries +intptr_t *mem_lock_freed = (intptr_t *)malloc(sizeof(intptr_t) * mem_lock_freed_max); + +void new_mem_lock() { + if (mem_lock_freed_n) { + mem_lock_tmp = (mem_lock *)mem_lock_freed[--mem_lock_freed_n]; + } else { + if (mem_lock_next == mem_lock_max) { + mem_lock_base = (mem_lock *)malloc(sizeof(mem_lock) * mem_lock_max); + mem_lock_next = 0; + } + mem_lock_tmp = &mem_lock_base[mem_lock_next++]; + } + mem_lock_tmp->id = ++mem_lock_id; +} + +void free_mem_lock(mem_lock *lock) { + lock->id = 0; // invalidate lock + if (lock->type == 1) + free(lock->offset); // malloc type + // add to freed list + if (mem_lock_freed_n == mem_lock_freed_max) { + mem_lock_freed_max *= 2; + mem_lock_freed = (intptr_t *)realloc(mem_lock_freed, sizeof(intptr_t) * mem_lock_freed_max); + } + mem_lock_freed[mem_lock_freed_n++] = (intptr_t)lock; +} + +void sub__memfree(void *mem) { + // 1:malloc: memory will be freed if it still exists + // 2:images: will not be freed, no action will be taken + // exists? + if (((mem_block *)(mem))->lock_offset == NULL) { + error(309); + return; + } + if (((mem_lock *)(((mem_block *)(mem))->lock_offset))->id != ((mem_block *)(mem))->lock_id) { + error(307); + return; + } // memory has been freed + if (((mem_lock *)(((mem_block *)(mem))->lock_offset))->type == 0) { // no security + free_mem_lock((mem_lock *)((mem_block *)(mem))->lock_offset); + } + if (((mem_lock *)(((mem_block *)(mem))->lock_offset))->type == 1) { // malloc + free_mem_lock((mem_lock *)((mem_block *)(mem))->lock_offset); + } + // note: type 2(image) is freed when the image is freed + // invalidate caller's mem structure (avoids misconception that _MEMFREE failed) + ((mem_block *)(mem))->lock_id = 1073741821; +} + +extern mem_block func__mem_at_offset(intptr_t offset, intptr_t size) { + static mem_block b; + new_mem_lock(); + mem_lock_tmp->type = 0; // unsecured + b.lock_offset = (intptr_t)mem_lock_tmp; + b.lock_id = mem_lock_id; + b.offset = offset; + b.size = size; + b.type = 16384; //_MEMNEW type + b.elementsize = 1; + b.image = -1; + if ((size < 0) || is_error_pending()) { + b.type = 0; + b.size = 0; + b.offset = 0; + if (size < 0) + error(301); + } + return b; +} + +mem_block func__memnew(intptr_t bytes) { + static mem_block b; + new_mem_lock(); + b.lock_offset = (intptr_t)mem_lock_tmp; + b.lock_id = mem_lock_id; + b.type = 16384; //_MEMNEW type + b.elementsize = 1; + b.image = -1; + if (is_error_pending()) { + b.type = 0; + b.offset = 0; + b.size = 0; + mem_lock_tmp->type = 0; + return b; + } + + if (bytes < 0) { + // still create a block, but an invalid one and generate an error + error(5); + b.offset = 0; + b.size = 0; + mem_lock_tmp->type = 0; + } else { + if (!bytes) { + b.offset = 1; // non-zero=success + b.size = 0; + } else { + b.offset = (intptr_t)malloc(bytes); + if (!b.offset) { + b.size = 0; + mem_lock_tmp->type = 0; + } else { + b.size = bytes; + mem_lock_tmp->type = 1; + mem_lock_tmp->offset = (void *)b.offset; + } + } + } + return b; +} + +int32_t func__memexists(void *void_blk) { + static mem_block *blk; + blk = (mem_block *)void_blk; + if (((mem_block *)(blk))->lock_offset == NULL) + return 0; + if (((mem_lock *)(((mem_block *)(blk))->lock_offset))->id == ((mem_block *)(blk))->lock_id) + return -1; + return 0; +} + +void *func__memget(mem_block *blk, intptr_t off, intptr_t bytes) { + // checking A + if (((mem_block *)(blk))->lock_offset == NULL) { + error(309); + goto fail; + } + // checking B + if (off < ((mem_block *)(blk))->offset || (off + bytes) > (((mem_block *)(blk))->offset + ((mem_block *)(blk))->size) || + ((mem_lock *)(((mem_block *)(blk))->lock_offset))->id != ((mem_block *)(blk))->lock_id) { + // error reporting + if (((mem_lock *)(((mem_block *)(blk))->lock_offset))->id != ((mem_block *)(blk))->lock_id) { + error(308); + goto fail; + } + error(300); + goto fail; + } + return (void *)off; +//------------------------------------------------------------ +fail: + static void *fail_buffer; + fail_buffer = calloc(bytes, 1); + if (!fail_buffer) + error(518); // critical error: out of memory + return fail_buffer; +} + +void sub__memfill_nochecks(intptr_t doff, intptr_t dbytes, intptr_t soff, intptr_t sbytes) { + if (sbytes == 1) { + memset((void *)doff, *(uint8_t *)soff, dbytes); + return; + } + static intptr_t si; + si = 0; + while (dbytes--) { + *(int8_t *)(doff++) = *(int8_t *)(soff + si++); + if (si >= sbytes) + si = 0; + } +} + +void sub__memfill(mem_block *dblk, intptr_t doff, intptr_t dbytes, intptr_t soff, intptr_t sbytes) { + if (((mem_block *)(dblk))->lock_offset == NULL) { + error(309); + return; + } + if (((mem_lock *)(((mem_block *)(dblk))->lock_offset))->id != ((mem_block *)(dblk))->lock_id) { + error(308); + return; + } + if ((dbytes < 0) || (sbytes == 0)) { + error(301); + return; + } + if (doff < ((mem_block *)(dblk))->offset || (doff + dbytes) > (((mem_block *)(dblk))->offset + ((mem_block *)(dblk))->size)) { + error(300); + return; + } + sub__memfill_nochecks(doff, dbytes, soff, sbytes); +} + +void sub__memfill_1(mem_block *dblk, intptr_t doff, intptr_t dbytes, int8_t val) { sub__memfill(dblk, doff, dbytes, (intptr_t)&val, 1); } +void sub__memfill_nochecks_1(intptr_t doff, intptr_t dbytes, int8_t val) { sub__memfill_nochecks(doff, dbytes, (intptr_t)&val, 1); } +void sub__memfill_2(mem_block *dblk, intptr_t doff, intptr_t dbytes, int16_t val) { sub__memfill(dblk, doff, dbytes, (intptr_t)&val, 2); } +void sub__memfill_nochecks_2(intptr_t doff, intptr_t dbytes, int16_t val) { sub__memfill_nochecks(doff, dbytes, (intptr_t)&val, 2); } +void sub__memfill_4(mem_block *dblk, intptr_t doff, intptr_t dbytes, int32_t val) { sub__memfill(dblk, doff, dbytes, (intptr_t)&val, 4); } +void sub__memfill_nochecks_4(intptr_t doff, intptr_t dbytes, int32_t val) { sub__memfill_nochecks(doff, dbytes, (intptr_t)&val, 4); } +void sub__memfill_8(mem_block *dblk, intptr_t doff, intptr_t dbytes, int64_t val) { sub__memfill(dblk, doff, dbytes, (intptr_t)&val, 8); } +void sub__memfill_nochecks_8(intptr_t doff, intptr_t dbytes, int64_t val) { sub__memfill_nochecks(doff, dbytes, (intptr_t)&val, 8); } +void sub__memfill_SINGLE(mem_block *dblk, intptr_t doff, intptr_t dbytes, float val) { sub__memfill(dblk, doff, dbytes, (intptr_t)&val, 4); } +void sub__memfill_nochecks_SINGLE(intptr_t doff, intptr_t dbytes, float val) { sub__memfill_nochecks(doff, dbytes, (intptr_t)&val, 4); } +void sub__memfill_DOUBLE(mem_block *dblk, intptr_t doff, intptr_t dbytes, double val) { sub__memfill(dblk, doff, dbytes, (intptr_t)&val, 8); } +void sub__memfill_nochecks_DOUBLE(intptr_t doff, intptr_t dbytes, double val) { sub__memfill_nochecks(doff, dbytes, (intptr_t)&val, 8); } + +static uint8_t memfill_FLOAT_padding[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 32 null bytes + +void sub__memfill_FLOAT(mem_block *dblk, intptr_t doff, intptr_t dbytes, long double val) { + *(long double *)memfill_FLOAT_padding = val; + sub__memfill(dblk, doff, dbytes, (intptr_t)memfill_FLOAT_padding, 32); +} + +void sub__memfill_nochecks_FLOAT(intptr_t doff, intptr_t dbytes, long double val) { + *(long double *)memfill_FLOAT_padding = val; + sub__memfill_nochecks(doff, dbytes, (intptr_t)memfill_FLOAT_padding, 32); +} + +void sub__memfill_OFFSET(mem_block *dblk, intptr_t doff, intptr_t dbytes, intptr_t val) { sub__memfill(dblk, doff, dbytes, (intptr_t)&val, sizeof(intptr_t)); } +void sub__memfill_nochecks_OFFSET(intptr_t doff, intptr_t dbytes, intptr_t val) { sub__memfill_nochecks(doff, dbytes, (intptr_t)&val, sizeof(intptr_t)); } + +void sub__memcopy(void *sblk, intptr_t soff, intptr_t bytes, void *dblk, intptr_t doff) { + // checking A + if (((mem_block *)(sblk))->lock_offset == NULL || ((mem_block *)(dblk))->lock_offset == NULL) { + // error reporting + if (((mem_block *)(sblk))->lock_offset == NULL && ((mem_block *)(dblk))->lock_offset == NULL) { + error(312); + return; + } + if (((mem_block *)(sblk))->lock_offset == NULL) { + error(310); + return; + } + error(311); + return; + } + // checking B + if (bytes < 0 || soff < ((mem_block *)(sblk))->offset || (soff + bytes) > (((mem_block *)(sblk))->offset + ((mem_block *)(sblk))->size) || + doff < ((mem_block *)(dblk))->offset || (doff + bytes) > (((mem_block *)(dblk))->offset + ((mem_block *)(dblk))->size) || + ((mem_lock *)(((mem_block *)(sblk))->lock_offset))->id != ((mem_block *)(sblk))->lock_id || + ((mem_lock *)(((mem_block *)(dblk))->lock_offset))->id != ((mem_block *)(dblk))->lock_id) { + // error reporting + if (((mem_lock *)(((mem_block *)(sblk))->lock_offset))->id != ((mem_block *)(sblk))->lock_id && + ((mem_lock *)(((mem_block *)(dblk))->lock_offset))->id != ((mem_block *)(dblk))->lock_id) { + error(313); + return; + } + if (((mem_lock *)(((mem_block *)(sblk))->lock_offset))->id != ((mem_block *)(sblk))->lock_id) { + error(305); + return; + } + if (((mem_lock *)(((mem_block *)(dblk))->lock_offset))->id != ((mem_block *)(dblk))->lock_id) { + error(306); + return; + } + if (bytes < 0) { + error(301); + return; + } + if (soff < ((mem_block *)(sblk))->offset || (soff + bytes) > (((mem_block *)(sblk))->offset + ((mem_block *)(sblk))->size)) { + if (doff < ((mem_block *)(dblk))->offset || (doff + bytes) > (((mem_block *)(dblk))->offset + ((mem_block *)(dblk))->size)) { + error(304); + return; + } + error(302); + return; + } + error(303); + return; + } + memmove((char *)doff, (char *)soff, bytes); +} + +mem_block func__mem(intptr_t offset, intptr_t size, int32_t type, intptr_t elementsize, mem_lock *lock) { + static mem_block b; + b.lock_offset = (intptr_t)lock; + b.lock_id = lock->id; + b.offset = offset; + b.size = size; + b.type = type; + b.elementsize = elementsize; + b.image = -1; + return b; +} diff --git a/internal/c/qbx.cpp b/internal/c/qbx.cpp index b5f0def51..58b993967 100755 --- a/internal/c/qbx.cpp +++ b/internal/c/qbx.cpp @@ -12,6 +12,7 @@ #include "image.h" #include "qbs.h" #include "error_handle.h" +#include "mem.h" #include "rounding.h" extern int32 func__cinp(int32 toggle, @@ -120,49 +121,6 @@ extern void sub__displayorder(int32 method1, int32 method2, int32 method3, extern int64 GetTicks(); -extern int32 func__memexists(void *blk); -extern void sub__memfill(mem_block *dblk, ptrszint doff, ptrszint dbytes, - ptrszint soff, ptrszint sbytes); -extern void sub__memfill_nochecks(ptrszint doff, ptrszint dbytes, ptrszint soff, - ptrszint sbytes); -extern void sub__memfill_1(mem_block *dblk, ptrszint doff, ptrszint dbytes, - int8 val); -extern void sub__memfill_nochecks_1(ptrszint doff, ptrszint dbytes, int8 val); -extern void sub__memfill_2(mem_block *dblk, ptrszint doff, ptrszint dbytes, - int16 val); -extern void sub__memfill_nochecks_2(ptrszint doff, ptrszint dbytes, int16 val); -extern void sub__memfill_4(mem_block *dblk, ptrszint doff, ptrszint dbytes, - int32 val); -extern void sub__memfill_nochecks_4(ptrszint doff, ptrszint dbytes, int32 val); -extern void sub__memfill_8(mem_block *dblk, ptrszint doff, ptrszint dbytes, - int64 val); -extern void sub__memfill_nochecks_8(ptrszint doff, ptrszint dbytes, int64 val); -extern void sub__memfill_SINGLE(mem_block *dblk, ptrszint doff, ptrszint dbytes, - float val); -extern void sub__memfill_nochecks_SINGLE(ptrszint doff, ptrszint dbytes, - float val); -extern void sub__memfill_DOUBLE(mem_block *dblk, ptrszint doff, ptrszint dbytes, - double val); -extern void sub__memfill_nochecks_DOUBLE(ptrszint doff, ptrszint dbytes, - double val); -extern void sub__memfill_FLOAT(mem_block *dblk, ptrszint doff, ptrszint dbytes, - long double val); -extern void sub__memfill_nochecks_FLOAT(ptrszint doff, ptrszint dbytes, - long double val); -extern void sub__memfill_OFFSET(mem_block *dblk, ptrszint doff, ptrszint dbytes, - ptrszint val); -extern void sub__memfill_nochecks_OFFSET(ptrszint doff, ptrszint dbytes, - ptrszint val); -extern void *func__memget(mem_block *blk, ptrszint off, ptrszint bytes); -extern void new_mem_lock(); -extern void free_mem_lock(mem_lock *lock); -extern mem_block func__mem(ptrszint offset, ptrszint size, int32 type, - ptrszint elementsize, mem_lock *lock); -extern mem_block func__mem_at_offset(ptrszint offset, ptrszint size); -extern void sub__memfree(void *); -extern void sub__memcopy(void *sblk, ptrszint soff, ptrszint bytes, void *dblk, - ptrszint doff); -extern mem_block func__memnew(ptrszint); extern mem_block func__memimage(int32, int32); extern int64 func__shellhide(qbs *str); @@ -590,8 +548,6 @@ extern void setbits(uint32 bsize, uint8 *base, ptrszint i, int64 val); // shared global variables extern int32 sleep_break; -extern uint64 mem_lock_id; -extern mem_lock *mem_lock_tmp; extern int64 exit_code; extern int32 lock_mainloop; // 0=unlocked, 1=lock requested, 2=locked extern int64 device_event_index;