--- /dev/null
+
+int brk (uint8_t* addr);
+uint8_t* sbrk(uintptr_t inc);
+
+int printf(const char* fmt, ...);
+
+uint8_t* memset(uint8_t* dst, int c, uintptr_t n);
+uint8_t* memcpy(uint8_t* dst, uint8_t* src, uintptr_t n);
+
+// min size of block is 64, so low 6 bits can be used for flags
+// flags in prev_size:
+// Free Last First
+// 2 1 0
+struct scf_mblock_t
+{
+ uintptr_t magic;
+ uintptr_t prev_size;
+ uintptr_t cur_size;
+ uintptr_t free;
+};
+
+scf_mblock_t* scf__mblocks[30];
+scf_mblock_t* scf__free_blocks = NULL;
+uint8_t* scf__last_brk = NULL;
+
+uint8_t* scf__malloc(uintptr_t size)
+{
+ scf_mblock_t* b;
+ scf_mblock_t* b2;
+
+ uintptr_t bytes = (sizeof(scf_mblock_t) + size + 63) >> 6 << 6;
+ intptr_t nblocks = sizeof(scf__mblocks) / sizeof(scf__mblocks[0]);
+
+ uintptr_t rest;
+ uint8_t* addr = NULL;
+ uint8_t* p = NULL;
+ intptr_t i;
+
+ for (i = 0; i < nblocks; i++) {
+
+ if ((64 << i) < bytes)
+ continue;
+
+ if (scf__mblocks[i])
+ break;
+ }
+
+ if (i == nblocks) {
+
+ uintptr_t pages = (bytes + 4095) >> 12;
+
+ p = sbrk(pages << 12);
+ if (!p)
+ return NULL;
+ scf__last_brk = p + (pages << 12);
+
+ rest = (pages << 12) - bytes;
+
+ b = (scf_mblock_t*)p;
+
+ b->prev_size = 0x3;
+ b->cur_size = bytes;
+ b->magic = 0x10f0;
+ } else {
+ b = scf__mblocks[i];
+ scf__mblocks[i] = (scf_mblock_t*)b->free;
+
+ p = (uint8_t*)b;
+
+ rest = b->cur_size - bytes;
+
+ b->prev_size &= ~0x4;
+ b->magic = 0x10f0;
+ }
+
+ addr = p + sizeof(scf_mblock_t);
+
+ if (0 == rest) {
+ printf("%s(),%d, b: %p, scf__last_brk: %p\n", __func__, __LINE__, b, scf__last_brk);
+ return addr;
+ }
+
+ p += bytes;
+ b2 = (scf_mblock_t*)p;
+
+ for (; i >= 0; i--) {
+
+ if (rest >= (64 << i)) {
+ b2->free = (uintptr_t)scf__mblocks[i];
+ scf__mblocks[i] = b2;
+ break;
+ }
+ }
+
+ b ->cur_size = bytes;
+ b2->cur_size = rest;
+ b2->prev_size = bytes | 0x4;
+ b2->magic = 0xf010;
+
+ if (b->prev_size & 0x2) {
+ b->prev_size &= ~0x2;
+ b2->prev_size |= 0x2;
+ }
+
+ printf("%s(),%d, b: %p, scf__last_brk: %p\n", __func__, __LINE__, b, scf__last_brk);
+ return addr;
+}
+
+int scf__free(uint8_t* p)
+{
+ p -= sizeof(scf_mblock_t);
+
+ scf_mblock_t* b = (scf_mblock_t*)p;
+ scf_mblock_t* b2;
+ scf_mblock_t* b3;
+ scf_mblock_t** pb;
+
+ uintptr_t bytes = b->cur_size;
+ intptr_t nblocks = sizeof(scf__mblocks) / sizeof(scf__mblocks[0]);
+ intptr_t i;
+
+ if (b->prev_size & 0x4) {
+ printf("%s(), %d, error: double free: %p\n", __func__, __LINE__, p);
+ return -1;
+ }
+
+ if (0x10f0 != b->magic) {
+ printf("%s(), %d, error: corruption free: %p\n", __func__, __LINE__, p);
+ return -1;
+ }
+
+ b->prev_size |= 0x4;
+ b->magic = 0xf010;
+
+ while (!(b->prev_size & 0x2)) {
+
+ b2 = (scf_mblock_t*)((uintptr_t)b + bytes);
+
+ uintptr_t bytes2 = b2->cur_size;
+
+ for (i = nblocks - 1; i >= 0; i--) {
+
+ if (bytes2 >= (64 << i))
+ break;
+ }
+
+ for (pb = &scf__mblocks[i]; *pb; pb = (scf_mblock_t**)&(*pb)->free) {
+
+ if (*pb == b2)
+ break;
+ }
+ if (!*pb)
+ break;
+
+ *pb = (scf_mblock_t*)b2->free;
+
+ bytes += bytes2;
+ b->cur_size = bytes;
+
+ if (b2->prev_size & 0x2)
+ b->prev_size |= 0x2;
+ else {
+ b3 = (scf_mblock_t*)((uintptr_t)b2 + bytes2);
+
+ b3->prev_size = bytes | (b3->prev_size & 0x7);
+ }
+ }
+
+ while (!(b->prev_size & 0x1)) {
+
+ uintptr_t bytes2 = b->prev_size & ~0x7;
+
+ b2 = (scf_mblock_t*)((uintptr_t)b - bytes2);
+
+ bytes2 = b2->cur_size;
+
+ for (i = nblocks - 1; i >= 0; i--) {
+
+ if (bytes2 >= (64 << i))
+ break;
+ }
+
+ for (pb = &scf__mblocks[i]; *pb; pb = (scf_mblock_t**)&(*pb)->free) {
+ if (*pb == b2)
+ break;
+ }
+ if (!*pb)
+ break;
+
+ *pb = (scf_mblock_t*)b2->free;
+
+ bytes += bytes2;
+ b2->cur_size = bytes;
+
+ if (b->prev_size & 0x2)
+ b2->prev_size |= 0x2;
+ else {
+ b3 = (scf_mblock_t*)((uintptr_t)b2 + bytes);
+
+ b3->prev_size = bytes | (b3->prev_size & 0x7);
+ }
+
+ b = b2;
+ }
+
+ bytes = b->cur_size;
+
+ if (0x7 == (b->prev_size) & 0x7) {
+
+ if (scf__last_brk == (uint8_t*)b + bytes) {
+
+ printf("%s(), %d, b: %p, scf__last_brk: %p\n", __func__, __LINE__, b, scf__last_brk);
+ scf__last_brk = (uint8_t*)b;
+ brk((uint8_t*)b);
+
+ int flag = 1;
+ while (flag) {
+ flag = 0;
+
+ pb = &scf__free_blocks;
+ while (*pb) {
+
+ b = *pb;
+ bytes = b->cur_size;
+
+ if (scf__last_brk != (uint8_t*)b + bytes) {
+
+ pb = (scf_mblock_t**)&b->free;
+ continue;
+ }
+ *pb = (scf_mblock_t*)b->free;
+
+ printf("%s(), %d, b: %p, scf__last_brk: %p\n", __func__, __LINE__, b, scf__last_brk);
+ scf__last_brk = (uint8_t*)b;
+ brk((uint8_t*)b);
+ flag = 1;
+ }
+ }
+ } else {
+ b->free = (uintptr_t)scf__free_blocks;
+ scf__free_blocks = b;
+ printf("%s(), %d, b: %p\n", __func__, __LINE__, b);
+ }
+ return 0;
+ }
+
+ for (i = nblocks - 1; i >= 0; i--) {
+ if (bytes >= (64 << i))
+ break;
+ }
+
+ b->free = (uintptr_t)scf__mblocks[i];
+ scf__mblocks[i] = b;
+
+ printf("%s(), %d, b: %p\n", __func__, __LINE__, b);
+ return 0;
+}
+
+uint8_t* scf__calloc(uintptr_t n, uintptr_t size)
+{
+ scf_mblock_t* b;
+ uintptr_t bytes;
+ uint8_t* p;
+
+ size *= n;
+
+ p = scf__malloc(size);
+ if (!p)
+ return NULL;
+
+ b = (scf_mblock_t*)(p - sizeof(scf_mblock_t));
+
+ bytes = b->cur_size;
+ bytes -= sizeof(scf_mblock_t);
+ printf("%s(),%d, calloc, b: %p, bytes: %ld\n", __func__, __LINE__, b, bytes);
+
+ memset(p, 0, bytes);
+
+ return p;
+}
+
+uint8_t* scf__realloc(uint8_t* p, uintptr_t size)
+{
+ scf_mblock_t* b;
+ scf_mblock_t* b2;
+ scf_mblock_t* b3;
+ uintptr_t bytes;
+ uint8_t* p2;
+
+ b = (scf_mblock_t*)(p - sizeof(scf_mblock_t));
+
+ bytes = b->cur_size;
+ bytes -= sizeof(scf_mblock_t);
+
+ if (bytes < size) {
+ p2 = scf__malloc(size);
+ if (!p2)
+ return NULL;
+
+ memcpy(p2, p, bytes);
+ scf__free(p);
+
+ printf("%s(), %d, realloc: %p->%p, size: %ld\n", __func__, __LINE__, p, p2, size);
+ return p2;
+ }
+
+ size = (sizeof(scf_mblock_t) + 63 + size) >> 6 << 6;
+ bytes += sizeof(scf_mblock_t);
+
+ if (bytes < size + 64)
+ return p;
+
+ b2 = (scf_mblock_t*)((uintptr_t)b + size);
+
+ b ->cur_size = size;
+ b2->cur_size = bytes - size;
+
+ if (b->prev_size & 0x2) {
+ b->prev_size &= ~0x2;
+ b2->prev_size = size | 0x2;
+ } else {
+ b3 = (scf_mblock_t*)((uintptr_t)b + bytes);
+
+ b2->prev_size = size;
+ b3->prev_size = (bytes - size) | (b3->prev_size & 0x7);
+ }
+
+ b2->magic = 0x10f0;
+
+ p2 = (uint8_t*)b2 + sizeof(scf_mblock_t);
+ scf__free(p2);
+
+ printf("%s(), %d, realloc: %p, free b2: %p, size: %ld\n", __func__, __LINE__, p, p2, size);
+ return p;
+}
+
+int main()
+{
+ uint8_t* p0 = scf__malloc(1000);
+ uint8_t* p1 = scf__malloc(1320);
+ uint8_t* p2 = scf__malloc(2510);
+ uint8_t* p3 = scf__malloc(4510);
+ uint8_t* p4 = scf__malloc(510);
+ uint8_t* p5 = scf__malloc(6510);
+ uint8_t* p6 = scf__malloc(510);
+ uint8_t* p7 = scf__malloc(11510);
+
+ scf__free(p0);
+
+ *p1 = 1;
+ scf__free(p1);
+
+ *p2 = 2;
+ *p4 = 4;
+
+ scf__free(p4);
+ scf__free(p5);
+ scf__free(p2);
+ scf__free(p6);
+ scf__free(p3);
+
+ scf__free(p7);
+ return 0;
+}
--- /dev/null
+include "../lib/scf_capi.c";
+
+struct string
+{
+ uint8_t* data;
+ int64_t len;
+ int64_t capacity;
+
+ int __init(string* this)
+ {
+ this->data = scf__auto_malloc(16);
+ if (!this->data)
+ return -1;
+
+ this->data[0] = '\0';
+ this->capacity = 16;
+ this->len = 0;
+
+ return 0;
+ }
+
+ int __init(string* this, const char* s)
+ {
+ int64_t len = strlen(s);
+
+ this->data = scf__auto_malloc(len + 1);
+ if (!this->data)
+ return -1;
+
+ memcpy(this->data, s, len);
+
+ this->data[len] = '\0';
+ this->capacity = len;
+ this->len = len;
+
+ return 0;
+ }
+
+ int __init(string* this, const char* s, int64_t len)
+ {
+ this->data = scf__auto_malloc(len + 1);
+ if (!this->data)
+ return -1;
+
+ memcpy(this->data, s, len);
+
+ this->data[len] = '\0';
+ this->capacity = len;
+ this->len = len;
+
+ return 0;
+ }
+
+ int operator+=(string* this, string* that)
+ {
+ int64_t len = this->len + that->len;
+
+ if (len >= this->capacity) {
+ uint8_t* p = scf__auto_malloc(len + 16);
+ if (!p)
+ return -1;
+
+ memcpy(p, this->data, this->len);
+
+ this->data = p;
+ this->capacity = len + 15;
+ }
+
+ memcpy(this->data + this->len, that->data, that->len);
+
+ this->data[len] = '\0';
+ this->len = len;
+
+ return 0;
+ }
+
+ string*, int operator+(string* this, string* that)
+ {
+ string* s;
+
+ s = create string();
+ if (!s)
+ return NULL, -1;
+
+ int64_t len = this->len + that->len;
+
+ if (s->len < len) {
+ s->data = scf__auto_malloc(len + 1);
+ if (!s->data)
+ return NULL, -1;
+ }
+
+ memcpy(s->data, this->data, this->len);
+ memcpy(s->data + this->len, that->data, that->len);
+
+ s->data[len] = '\0';
+ s->capacity = len;
+ s->len = len;
+
+ return s, 0;
+ }
+
+ int operator==(string* this, string* that)
+ {
+ if (this->len < that->len)
+ return -1;
+ else if (this->len > that->len)
+ return 1;
+ return memcmp(this->data, that->data, this->len);
+ }
+
+ void __release(string* this)
+ {
+ if (this->data)
+ scf__auto_freep(&this->data, NULL);
+ }
+};
+
+int main()
+{
+ string* s0;
+ string* s1;
+ string* s2;
+ string* s3;
+ int err;
+
+ s0 = "hello";
+ s1 = " world";
+
+ s2 = s0 + s1;
+ s3 = "hello";
+
+ printf("### s0 == s3: %d, s0->data: %s, s2: %s\n", s0 == s3, s0->data, s2->data);
+ return 0;
+}
+
--- /dev/null
+
+include "../lib/scf_capi.c";
+
+struct complex
+{
+ double real;
+ double imag;
+
+ int __init(complex* this, double real, double imag)
+ {
+ this->real = real;
+ this->imag = imag;
+ return 0;
+ }
+
+ int operator+=(complex* this, complex* that)
+ {
+ if (!this || !that)
+ return -1;
+
+ this->real += that->real;
+ this->imag += that->imag;
+ return 0;
+ }
+
+ int operator-=(complex* this, complex* that)
+ {
+ if (!this || !that)
+ return -1;
+
+ this->real -= that->real;
+ this->imag -= that->imag;
+ return 0;
+ }
+
+ int operator*=(complex* this, complex* that)
+ {
+ if (!this || !that)
+ return -1;
+
+ double a = this->real;
+ double b = this->imag;
+ double c = that->real;
+ double d = that->imag;
+
+ this->real = a * c - b * d;
+ this->imag = a * d + b * c;
+ return 0;
+ }
+
+ int operator/=(complex* this, complex* that)
+ {
+ if (!this || !that)
+ return -1;
+
+ double a = this->real;
+ double b = this->imag;
+ double c = that->real;
+ double d = that->imag;
+
+ this->real = (a * c + b * d) / (c * c + d * d);
+ this->imag = (b * c - a * d) / (c * c + d * d);
+ return 0;
+ }
+
+ complex*, int operator+(complex* this, complex* that)
+ {
+ if (!this || !that)
+ return NULL, -1;
+
+ complex* res;
+
+ res = create complex(0.0, 0.0);
+ if (!res)
+ return NULL, -1;
+
+ res->real = this->real + that->real;
+ res->imag = this->imag + that->imag;
+ return res, 0;
+ }
+
+ complex*, int operator-(complex* this, complex* that)
+ {
+ if (!this || !that)
+ return NULL, -1;
+
+ complex* res;
+
+ res = create complex(0.0, 0.0);
+ if (!res)
+ return NULL, -1;
+
+ res->real = this->real - that->real;
+ res->imag = this->imag - that->imag;
+ return res, 0;
+ }
+
+ complex*, int operator*(complex* this, complex* that)
+ {
+ if (!this || !that)
+ return NULL, -1;
+
+ complex* res;
+
+ res = create complex(0.0, 0.0);
+ if (!res)
+ return NULL, -1;
+
+ double a = this->real;
+ double b = this->imag;
+ double c = that->real;
+ double d = that->imag;
+
+ res->real = a * c - b * d;
+ res->imag = a * d + b * c;
+ return res, 0;
+ }
+
+ complex*, int operator/(complex* this, complex* that)
+ {
+ if (!this || !that)
+ return NULL, -1;
+
+ complex* res;
+
+ res = create complex(0.0, 0.0);
+ if (!res)
+ return NULL, -1;
+
+ double a = this->real;
+ double b = this->imag;
+ double c = that->real;
+ double d = that->imag;
+
+ res->real = (a * c + b * d) / (c * c + d * d);
+ res->imag = (b * c - a * d) / (c * c + d * d);
+ return res, 0;
+ }
+};
+
+