Browse Source

Garbage collector and arrays work!

main
Ludovic 'Archivist' Lagouardette 7 months ago
parent
commit
b97b33c471
4 changed files with 128 additions and 35 deletions
  1. +114
    -32
      lib.c
  2. +1
    -1
      test/test01.nk
  3. +0
    -2
      test/test02.nk
  4. +13
    -0
      test/test05.nk

+ 114
- 32
lib.c View File

@ -876,7 +876,7 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) {
ctx->types[type_id].elements = ctx->inner_malloc(sizeof(struct element_slab) * 8);
ctx->types[type_id].elements_top = 0;
ctx->types[type_id].elements_capacity = 8;
memset(ctx->types[type_id].elements + ctx->types[type_id].elements_top, 0, ctx->types[type_id].elements_capacity - ctx->types[type_id].elements_top);
memset(ctx->types[type_id].elements + ctx->types[type_id].elements_top, 0, k">sizeof(struct element_slab)*(ctx->types[type_id].elements_capacity - ctx->types[type_id].elements_top));
} else if(ctx->types[type_id].elements_top == ctx->types[type_id].elements_capacity) {
int new_count = (ctx->types[type_id].elements_capacity + ctx->types[type_id].elements_capacity/2);
void* renewed = ctx->inner_realloc(ctx->types[type_id].elements, sizeof(struct element_slab) * new_count);
@ -888,7 +888,7 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) {
} else {
ctx->types[type_id].elements = renewed;
ctx->types[type_id].elements_capacity = new_count;
memset(ctx->types[type_id].elements + ctx->types[type_id].elements_top, 0, ctx->types[type_id].elements_capacity - ctx->types[type_id].elements_top);
memset(ctx->types[type_id].elements + ctx->types[type_id].elements_top, 0, k">sizeof(struct element_slab)*(ctx->types[type_id].elements_capacity - ctx->types[type_id].elements_top));
}
}
int g = ctx->types[type_id].elements_capacity;
@ -908,9 +908,9 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) {
return ret;
}
memcpy(new_ptr, ptr, ctx->types[type_id].element_size);
ctx->types[type_id].elements[i].data = ptr;
ctx->types[type_id].elements[i].data = new_ptr;
}
ctx->types[type_id].elements_top = max(ctx->types[type_id].elements_topo">+1, i+1);
ctx->types[type_id].elements_top = max(ctx->types[type_id].elements_top, i+1);
struct elem ret;
ret.type = type;
ret.value = i;
@ -930,27 +930,37 @@ void ink_gc(struct context* ctx) {
ctx->types[i].elements[j].uses = 0;
}
}
for(i = 0; i < ctx->routines_top; ++i) {
for(j = 0; j < ctx->routines[i].top; ++j) {
struct element_slab* v = ink_get_value_link(ctx, ctx->routines[i].stack[j]);
if(v != NULL) ++v->uses;
}
}
int marked;
do {
marked = 0;
for (i = 0; i < ctx->types_top; ++i) {
for (j = 0; j < ctx->types[i].elements_top; ++j) {
if (ctx->types[i].elements[j].in_use && ctx->types[i].elements[j].uses) {
struct ink_collection_list c = ctx->types[i].gc(ctx, ctx->types[i].elements[j].data);
for (k = 0; k < c.count; ++k) {
struct element_slab *v = ink_get_value_link(ctx, c.elements[k]);
if (v != NULL && !v->uses) {
++v->uses;
marked = 1;
}
}
if (c.elements != NULL) ctx->inner_free(c.elements);
}
}
}
} while(marked);
for(i = 0; i < ctx->types_top; ++i) {
for(j = 0; j < ctx->types[i].elements_top; ++j) {
struct ink_collection_list c = ctx->types[i].gc(ctx, ctx->types[i].elements[j].data);
for(k = 0; k < c.count; ++k) {
struct element_slab* v = ink_get_value_link(ctx, c.elements[k]);
if(v != NULL) ++v->uses;
}
if(c.elements != NULL) ctx->inner_free(c.elements);
}
}
for(i = 0; i < ctx->routines_top; ++i) {
for(j = 0; j < ctx->routines[i].top; ++j) {
struct element_slab* v = ink_get_value_link(ctx, ctx->routines[i].stack[j]);
if(v != NULL) ++v->uses;
}
}
for(i = 0; i < ctx->types_top; ++i) {
for(j = 0; j < ctx->types[i].elements_top; ++j) {
if(ctx->types[i].elements[j].uses == 0) {
if(ctx->types[i].elements[j].uses == 0 && ctx->types[i].elements[j].in_use) {
ctx->collections++;
ctx->types[i].collect(ctx, ctx->types[i].elements[j].data);
if(ctx->types[i].element_size > 0) {
@ -1260,7 +1270,7 @@ static int get_type_by_name(struct context* ctx, const char* name) {
static void collect_array(struct context* ctx, void* array) {
struct ink_array* ary = array;
ctx->free(ary->elements);
k">if(ary->elements != NULL) ctx->free(ary->elements);
}
static struct ink_collection_list gc_array(struct context* ctx, void* array) {
@ -1273,23 +1283,95 @@ static struct ink_collection_list gc_array(struct context* ctx, void* array) {
}
static void new_array(struct context* ctx) {
int tid = get_type_by_name(ctx, "array");
struct ink_array ary;
ary.elements = NULL;
ary.top = 0;
ary.capacity = 0;
struct elem e = ink_make_native(ctx, tid, &ary);
ink_push(ctx, e);
int tid = get_type_by_name(ctx, "array");
struct ink_array ary;
ary.elements = NULL;
ary.top = 0;
ary.capacity = 0;
struct elem e = ink_make_native(ctx, tid, &ary);
ink_push(ctx, e);
}
static void push_array(struct context* ctx) {
int tid = get_type_by_name(ctx, "array");
struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current;
if(currentRoutine->top < 2 || currentRoutine->stack[currentRoutine->top-1].type != tid) {
currentRoutine->panic = 1;
return;
}
struct elem a;
a = currentRoutine->stack[currentRoutine->top-1];
struct ink_array* ary= ink_get_value(ctx, a);
if(ary == NULL) {
currentRoutine->panic = 1;
return;
}
ink_pop(ctx);
if(ary->elements == NULL) {
ary->elements = ctx->malloc(sizeof(struct elem) * 8);
ary->top = 0;
ary->capacity = 8;
} else if(ary->top == ary->capacity) {
int new_count = (ary->capacity + ary->capacity/2);
void* renewed = ctx->realloc(ary->elements, sizeof(struct elem) * new_count);
if(renewed == NULL) {
currentRoutine->panic = 1;
return;
} else {
ary->elements = renewed;
ary->capacity = new_count;
}
}
ary->elements[ary->top] = currentRoutine->stack[currentRoutine->top-1];
ary->top++;
ink_pop(ctx);
}
static void index_array(struct context* ctx) {
int tid = get_type_by_name(ctx, "array");
struct ink_routine *currentRoutine = ctx->routines + ctx->routine_current;
if (currentRoutine->top < 2 || currentRoutine->stack[currentRoutine->top - 1].type != tid || currentRoutine->stack[currentRoutine->top - 2].type != INK_INTEGER) {
currentRoutine->panic = 1;
return;
}
struct elem a;
a = currentRoutine->stack[currentRoutine->top - 1];
struct ink_array *ary = ink_get_value(ctx, a);
if (ary == NULL) {
currentRoutine->panic = 1;
return;
}
ink_pop(ctx);
struct elem idx;
idx = currentRoutine->stack[currentRoutine->top - 1];
ink_pop(ctx);
if(ary->top <= idx.value) {
currentRoutine->panic = 1;
return;
}
ink_push(ctx, ary->elements[idx.value]);
}
static void run_gc(struct context* ctx) {
ink_gc(ctx);
}
int ink_std_library(struct context* ctx) {
int v;
v = 0;
int array_t = ink_new_type(ctx, "array", sizeof(struct ink_array), collect_array, gc_array);
v += ink_add_native(ctx, "array", new_array);
v += ink_add_native(ctx, "trace", print_stacktrace);
v += ink_add_native(ctx, "array.new", new_array);
v += ink_add_native(ctx, "array.push", push_array);
v += ink_add_native(ctx, "array.index", index_array);
v += ink_add_native(ctx, "sys.trace", print_stacktrace);
v += ink_add_native(ctx, "sys.gc", run_gc);
v += ink_add_native(ctx, "print_int", print_int);
v += ink_add_native(ctx, "print_utf8", print_as_utf8);
v += ink_add_native(ctx, "+", add_int);

+ 1
- 1
test/test01.nk View File

@ -1,5 +1,5 @@
fn potato do
trace return
sys.trace return
end
fn print_n_utf8_impl do

+ 0
- 2
test/test02.nk View File

@ -1,5 +1,3 @@
fn print_n_utf8 do
print_n_utf8_impl drop
end
array drop array drop

+ 13
- 0
test/test05.nk View File

@ -0,0 +1,13 @@
array.new drop
array.new drop
array.new drop
array.new drop
sys.gc
array.new dup 1 swap array.push dup 0 swap array.index print_int dup 2 swap array.push dup 1 swap array.index print_int drop
sys.gc
array.new dup array.push

Loading…
Cancel
Save