From f4ac73574cf08e809889109be8ecacf131d48c07 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Mon, 27 Nov 2023 12:52:30 +0800 Subject: [PATCH] 1, fix: core dump when multi-include same file in '../examples/complex.c', 2, add some examples --- examples/complex.c | 22 +++ examples/list_test.c | 39 +++++ examples/scf_malloc.c | 364 ++++++++++++++++++++++++++++++++++++++++ examples/string.c | 136 +++++++++++++++ lib/scf_complex.c | 141 ++++++++++++++++ parse/scf_dfa_include.c | 3 +- 6 files changed, 704 insertions(+), 1 deletion(-) create mode 100644 examples/complex.c create mode 100644 examples/list_test.c create mode 100644 examples/scf_malloc.c create mode 100644 examples/string.c create mode 100644 lib/scf_complex.c diff --git a/examples/complex.c b/examples/complex.c new file mode 100644 index 0000000..611e02b --- /dev/null +++ b/examples/complex.c @@ -0,0 +1,22 @@ +include "../lib/scf_capi.c"; +include "../lib/scf_complex.c"; + +int main() +{ + complex* c1; + complex* c2; + complex* c3; + + complex* c0 = create complex(1.0, 2.0); + + c1 = create complex(3.0, 4.0); + + c2 = c0 + c1; + c3 = c0 * c1; + + printf("c2: %lf,%lf\n", c2->real, c2->imag); + printf("c3: %lf,%lf\n", c3->real, c3->imag); + + return 0; +} + diff --git a/examples/list_test.c b/examples/list_test.c new file mode 100644 index 0000000..f5d179c --- /dev/null +++ b/examples/list_test.c @@ -0,0 +1,39 @@ +include "../lib/scf_list.c"; +include "../lib/scf_capi.c"; + +struct Data +{ + list list; + int a; +}; + +int main() +{ + Data* d; + list h; + int i; + + list_init(&h); + + for (i = 0; i < 10; i++) { + d = malloc(sizeof(Data)); + + d->a = i; + list_add_tail(&h, &d->list); + } + + list* l; + + for (l = list_head(&h); l != list_sentinel(&h); ) { + + d = container(l, Data, list); + l = list_next(l); + + printf("%d\n", d->a); + + list_del(&d->list); + free(d); + } + + return 0; +} diff --git a/examples/scf_malloc.c b/examples/scf_malloc.c new file mode 100644 index 0000000..bf204b0 --- /dev/null +++ b/examples/scf_malloc.c @@ -0,0 +1,364 @@ + +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; +} diff --git a/examples/string.c b/examples/string.c new file mode 100644 index 0000000..81b522b --- /dev/null +++ b/examples/string.c @@ -0,0 +1,136 @@ +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; +} + diff --git a/lib/scf_complex.c b/lib/scf_complex.c new file mode 100644 index 0000000..430b600 --- /dev/null +++ b/lib/scf_complex.c @@ -0,0 +1,141 @@ + +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; + } +}; + + diff --git a/parse/scf_dfa_include.c b/parse/scf_dfa_include.c index acfe16c..1367eea 100644 --- a/parse/scf_dfa_include.c +++ b/parse/scf_dfa_include.c @@ -41,7 +41,8 @@ static int _include_action_path(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } - scf_lex_close(parse->lex); + if (parse->lex) + scf_lex_close(parse->lex); parse->lex = lex; parse->ast->current_block = cur; -- 2.25.1