#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);