63 #error "C++ header is not supported, please use native OOP instead!"
75#if defined(__unix__) || defined(__unix) || defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
78#define __OBJ_ACTIV(ptr, size) \
79 (mprotect((void *)(((size_t)ptr >> PAGE_SHIFT) << PAGE_SHIFT), size, PROT_READ | PROT_EXEC | PROT_WRITE) == 0)
82#pragma warning(disable : 4996)
83#pragma comment(lib, "kernel32.lib")
84#if ((defined(DEBUG) || defined(_DEBUG)) && _MSC_VER >= 1915)
85#pragma message ("warning: On Visual Studio 2017 15.8+, please disable Just My Code debugging!")
88#if !(defined(_WINDOWS_) || defined(_INC_WINDOWS) || defined(_WINDOWS_H) || defined(_MEMORYAPI_H_))
89extern int __stdcall VirtualProtect(
void *addr,
size_t size,
unsigned long newprot,
unsigned long *oldprot);
91#ifndef PAGE_EXECUTE_READWRITE
92#define PAGE_EXECUTE_READWRITE 0x40
94#define __OBJ_ACTIV(ptr, size) \
95 (VirtualProtect(ptr, size, PAGE_EXECUTE_READWRITE, &((unsigned long){ 0 })) != 0)
97#error "This OS is not supported!"
100#if defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
102#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
105#error This architecture is not supported!
108#define __OBJ_ERR(...) \
110 fprintf(stderr, "[obj.h] error: "); \
111 fprintf(stderr, __VA_ARGS__); \
112 fprintf(stderr, "\n"); \
115#define __OBJ_MAXPHSIZE 1024
117#define __OBJ_CLOFNNUM 0x58ffffbffdffffafULL
119#define __OBJ_CLOFNNUM 0x58ffffbfU
122static void *__OBJ_clofn(
void *prototype,
size_t *phsize,
void *data) {
130 for (; offset < __OBJ_MAXPHSIZE; offset++) {
131 if (*(
size_t *)((uintptr_t)prototype + offset) == (
size_t)__OBJ_CLOFNNUM) {
132 if (*phsize == 0) *phsize = offset;
137 fprintf(stderr,
"could't find closure declaration at prototype function (%p)!", prototype);
155 .mov_rax = { 0x48, 0xB8 },
156 .jmp_rax = { 0xFF, 0xE0 }
172 ihsize = offset +
sizeof(asmc);
173 code = (uint8_t *)malloc(ihsize);
175 if (!__OBJ_ACTIV(code, ihsize)) {
176 __OBJ_ERR(
"could't change memory type of C.malloc allocated!");
182 asmc.addr = (uintptr_t)prototype + offset +
sizeof(uintptr_t) - 1;
184 asmc.addr = ((uintptr_t)prototype + offset +
sizeof(uintptr_t)) - ((uintptr_t)code + ihsize);
187 asmc.data = (uintptr_t)data;
188 memcpy(code, prototype, offset);
189 memcpy(code + offset, &asmc,
sizeof(asmc));
229#define __OBJ_ROOT obj_use
231#define __OBJ_ROOT self
247 void *(*alloc)(size_t);
248 void *(*realloc)(
void *, size_t);
249 void (*free)(
void *);
257static struct __OBJ_pool *__OBJ_pool_create() {
265static void __OBJ_pool_destroy(
struct __OBJ_pool *p) {
266 if (p ==
NULL)
return;
268 for (
int i = 0; i < p->space; i++) {
269 free(p->entries[i].ptr);
277 size_t index = (uintptr_t)ptr % (space - 1);
283 if (entry->ptr ==
NULL) {
285 return tombstone !=
NULL ? tombstone : entry;
288 if (tombstone ==
NULL) tombstone = entry;
291 else if (entry->ptr == ptr) {
295 index = (index + 1) % space;
299static void __OBJ_pool_resize(
struct __OBJ_pool *p,
int space) {
301 memset(entries,
'\0', space *
sizeof(
struct __OBJ_entry));
304 for (
int i = 0; i < p->space; i++) {
306 if (entry->ptr ==
NULL)
continue;
308 *__OBJ_pool_find(entries, space, entry->ptr) = *entry;
314 p->entries = entries;
317static void *__OBJ_pool_add(
struct __OBJ_pool *p,
void *ptr) {
320 int space = p->space;
321 if (p->count >= space * 0.75) {
322 __OBJ_pool_resize(p, space < 8 ? 8 : space * 2);
325 struct __OBJ_entry *entry = __OBJ_pool_find(p->entries, p->space, ptr);
326 if (entry->ptr ==
NULL) {
330 return entry->ptr = ptr;
333static int __OBJ_pool_remove(
struct __OBJ_pool *p,
void *ptr) {
334 if (p->count == 0 || ptr ==
NULL)
return 0;
335 int space = p->space;
337 if (space > 8 && p->count < space / 2) {
338 __OBJ_pool_resize(p, space /= 2);
341 struct __OBJ_entry *entry = __OBJ_pool_find(p->entries, space, ptr);
342 if (entry->ptr ==
NULL)
return 0;
350static void *__OBJ_pool_alloc(
struct __OBJ_pool *p,
size_t size) {
351 void *ptr = malloc(size);
352 return __OBJ_pool_add(p, ptr);
355static void *__OBJ_pool_realloc(
struct __OBJ_pool *p,
void *ptr,
size_t size) {
356 __OBJ_pool_remove(p, ptr);
357 ptr = realloc(ptr, size);
358 return __OBJ_pool_add(p, ptr);
361static void __OBJ_pool_free(
struct __OBJ_pool *p,
void *ptr) {
362 if (__OBJ_pool_remove(p, ptr)) free(ptr);
365static void __OBJ_freebase(
struct __OBJ_base *base) {
370 __OBJ_pool_destroy(base->reserved.p);
375static size_t __OBJ_alloc_s = 0;
376static void *__OBJ_alloc(
size_t size) {
377 volatile size_t closn = __OBJ_CLOFNNUM;
380 return __OBJ_pool_alloc(base->reserved.p, size);
384static size_t __OBJ_realloc_s = 0;
385static void *__OBJ_realloc(
void *ptr,
size_t size) {
386 volatile size_t closn = __OBJ_CLOFNNUM;
389 return __OBJ_pool_realloc(base->reserved.p, ptr, size);
393static size_t __OBJ_free_s = 0;
394static void __OBJ_free(
void *ptr) {
395 volatile size_t closn = __OBJ_CLOFNNUM;
398 __OBJ_pool_free(base->reserved.p, ptr);
402static size_t __OBJ_release_s = 0;
403static void __OBJ_release() {
404 volatile size_t closn = __OBJ_CLOFNNUM;
407 void (*release)() = base->release;
408 base->release =
NULL;
410 if (base->reserved.d !=
NULL) {
411 base->reserved.d(base);
414 base->release = release;
415 __OBJ_freebase(base);
419#define __OBJ_PUB(n) struct __OBJ__##n
420#define __OBJ_PRV(n) struct __OBJ_PRV_##n
421#define __OBJ_INF(n) struct __OBJ_INF_##n
423#define __OBJ_M(n, f) __OBJ__##n##_##f
424#define __OBJ_S(n, f) __OBJ_S_##n##_##f
425#define __OBJ_H(n, f) __OBJ_H_##n##_##f
427#define __OBJ_CON(n) __OBJ_C_##n
428#define __OBJ_DES(n) __OBJ_D_##n
431#define public(...) __VA_ARGS__
433#define private(...) __VA_ARGS__
436#define extend(super_name) \
437 __OBJ_PUB(super_name) super_name
440#define classdef(name) \
441 typedef __OBJ_PUB(name) *name
444#define class(name, public_members, ...) \
446 struct __OBJ_base base; \
447 struct { char : 0; public_members }; \
450 struct __OBJ_base base; \
451 struct { char : 0; public_members }; \
452 struct { char : 0; __VA_ARGS__ }; \
456#define ctor(class_name) \
457 __OBJ_PUB(class_name) *class_name##_new
460#define dtor(class_name) \
461 void __OBJ_DES(class_name)(__OBJ_PRV(class_name) *__OBJ_ROOT)
464#define method(class_name, return_type, name) \
465 static size_t __OBJ_S(class_name, name); \
466 static return_type __OBJ_M(class_name, name)
469#define new(class_name) \
473#define obj_prepare(class_name) \
474 volatile size_t __closn = (size_t)__OBJ_CLOFNNUM; \
475 __OBJ_PRV(class_name) *__OBJ_ROOT = (__OBJ_PRV(class_name)*)__closn
477#define __OBJ_IMPL(class_name, method_name) \
479 void *__pf = __OBJ_clofn(__OBJ_M(class_name, method_name), \
480 &__OBJ_S(class_name, method_name), (void*)__OBJ_ROOT); \
482 __OBJ_ROOT->method_name = __OBJ_pool_add(__OBJ_ROOT->base.reserved.p, __pf); \
485 __OBJ_ERR("could't implement the method '%s'!", #method_name); \
490#define __OBJ_S2(n, _1) \
492#define __OBJ_S3(n, _1, _2) \
493 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2)
494#define __OBJ_S4(n, _1, _2, _3) \
495 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3)
496#define __OBJ_S5(n, _1, _2, _3, _4) \
497 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
499#define __OBJ_S6(n, _1, _2, _3, _4, _5) \
500 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
501 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5)
502#define __OBJ_S7(n, _1, _2, _3, _4, _5, _6) \
503 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
504 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5); __OBJ_IMPL(n, _6)
505#define __OBJ_S8(n, _1, _2, _3, _4, _5, _6, _7) \
506 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
507 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5); __OBJ_IMPL(n, _6); \
509#define __OBJ_S9(n, _1, _2, _3, _4, _5, _6, _7, _8) \
510 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
511 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5); __OBJ_IMPL(n, _6), \
512 __OBJ_IMPL(n, _7); __OBJ_IMPL(n, _8)
513#define __OBJ_S10(n, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
514 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
515 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5); __OBJ_IMPL(n, _6); \
516 __OBJ_IMPL(n, _7); __OBJ_IMPL(n, _8); __OBJ_IMPL(n, _9)
517#define __OBJ_S11(n, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
518 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
519 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5); __OBJ_IMPL(n, _6); \
520 __OBJ_IMPL(n, _7); __OBJ_IMPL(n, _8); __OBJ_IMPL(n, _9); \
522#define __OBJ_S12(n, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
523 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
524 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5); __OBJ_IMPL(n, _6); \
525 __OBJ_IMPL(n, _7); __OBJ_IMPL(n, _8); __OBJ_IMPL(n, _9); \
526 __OBJ_IMPL(n, _10); __OBJ_IMPL(n, _11)
527#define __OBJ_S13(n, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
528 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
529 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5); __OBJ_IMPL(n, _6); \
530 __OBJ_IMPL(n, _7); __OBJ_IMPL(n, _8); __OBJ_IMPL(n, _9); \
531 __OBJ_IMPL(n, _10); __OBJ_IMPL(n, _11); __OBJ_IMPL(n, _12)
532#define __OBJ_S14(n, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
533 __OBJ_IMPL(n, _1); __OBJ_IMPL(n, _2); __OBJ_IMPL(n, _3); \
534 __OBJ_IMPL(n, _4); __OBJ_IMPL(n, _5); __OBJ_IMPL(n, _6); \
535 __OBJ_IMPL(n, _7); __OBJ_IMPL(n, _8); __OBJ_IMPL(n, _9); \
536 __OBJ_IMPL(n, _10); __OBJ_IMPL(n, _11); __OBJ_IMPL(n, _12); \
539#define __OBJ_FC(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15
540#define __OBJ_FR(args) __OBJ_FC args
541#define __OBJ_CFA(...) __OBJ_FR((__VA_ARGS__, \
542 __OBJ_S14, __OBJ_S13, __OBJ_S12, \
543 __OBJ_S11, __OBJ_S10, __OBJ_S9, __OBJ_S8, \
544 __OBJ_S7, __OBJ_S6, __OBJ_S5, __OBJ_S4, \
545 __OBJ_S3, __OBJ_S2, , ))
546#define __OBJ_MC(...) __OBJ_CFA(__VA_ARGS__ ())
549#define obj_bind(class_name, ...) __EXPAND(__OBJ_MC(class_name, __VA_ARGS__)(class_name, __VA_ARGS__))
552#define obj_setup(class_name) \
553 __OBJ_PRV(class_name) *__OBJ_ROOT = (__OBJ_PRV(class_name) *)malloc(sizeof(__OBJ_PRV(class_name))); \
556 __OBJ_ERR("could't create new class '%s' instance!", #class_name); \
559 __OBJ_ROOT->base.reserved.d = NULL; \
560 __OBJ_ROOT->base.reserved.p = __OBJ_pool_create(); \
561 __OBJ_ROOT->base.alloc = __OBJ_clofn((void *)__OBJ_alloc, &__OBJ_alloc_s, (void *)__OBJ_ROOT); \
562 __OBJ_ROOT->base.realloc = __OBJ_clofn((void *)__OBJ_realloc, &__OBJ_realloc_s, (void *)__OBJ_ROOT); \
563 __OBJ_ROOT->base.free = __OBJ_clofn((void *)__OBJ_free, &__OBJ_free_s, (void *)__OBJ_ROOT); \
564 __OBJ_ROOT->base.release = __OBJ_clofn((void *)__OBJ_release, &__OBJ_release_s, (void *)__OBJ_ROOT); \
572#define obj_done(class_name) \
573 return (class_name)__OBJ_ROOT; \
575 __OBJ_freebase(&__OBJ_ROOT->base); \
579#define obj_dtor(class_name) \
580 __OBJ_ROOT->base.reserved.d = (void *)__OBJ_DES(class_name)
583#define obj_override(class_name, super_name, method_name) \
585 void *__pf = __OBJ_clofn(__OBJ_M(class_name, method_name), &__OBJ_S(class_name, method_name), (void*)__OBJ_ROOT); \
586 if (__pf) { __OBJ_ROOT->super_name.method_name = __OBJ_pool_add(__OBJ_ROOT->base.reserved.p, __pf); } \
587 else { __OBJ_ERR("could't override the method '%s.%s'!", #super_name, #method_name); goto __err__; } \
591#define const_cast(type, prop) \
592 *(type *)&__OBJ_ROOT->prop
#define NULL
Definition list.h:22