|
@ -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 = ctx->inner_malloc(sizeof(struct element_slab) * 8); |
|
|
ctx->types[type_id].elements_top = 0; |
|
|
ctx->types[type_id].elements_top = 0; |
|
|
ctx->types[type_id].elements_capacity = 8; |
|
|
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) { |
|
|
} 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); |
|
|
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); |
|
|
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 { |
|
|
} else { |
|
|
ctx->types[type_id].elements = renewed; |
|
|
ctx->types[type_id].elements = renewed; |
|
|
ctx->types[type_id].elements_capacity = new_count; |
|
|
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; |
|
|
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; |
|
|
return ret; |
|
|
} |
|
|
} |
|
|
memcpy(new_ptr, ptr, ctx->types[type_id].element_size); |
|
|
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; |
|
|
struct elem ret; |
|
|
ret.type = type; |
|
|
ret.type = type; |
|
|
ret.value = i; |
|
|
ret.value = i; |
|
@ -930,27 +930,37 @@ void ink_gc(struct context* ctx) { |
|
|
ctx->types[i].elements[j].uses = 0; |
|
|
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(i = 0; i < ctx->types_top; ++i) { |
|
|
for(j = 0; j < ctx->types[i].elements_top; ++j) { |
|
|
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->collections++; |
|
|
ctx->types[i].collect(ctx, ctx->types[i].elements[j].data); |
|
|
ctx->types[i].collect(ctx, ctx->types[i].elements[j].data); |
|
|
if(ctx->types[i].element_size > 0) { |
|
|
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) { |
|
|
static void collect_array(struct context* ctx, void* array) { |
|
|
struct ink_array* ary = 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) { |
|
|
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) { |
|
|
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 ink_std_library(struct context* ctx) { |
|
|
int v; |
|
|
int v; |
|
|
v = 0; |
|
|
v = 0; |
|
|
int array_t = ink_new_type(ctx, "array", sizeof(struct ink_array), collect_array, gc_array); |
|
|
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_int", print_int); |
|
|
v += ink_add_native(ctx, "print_utf8", print_as_utf8); |
|
|
v += ink_add_native(ctx, "print_utf8", print_as_utf8); |
|
|
v += ink_add_native(ctx, "+", add_int); |
|
|
v += ink_add_native(ctx, "+", add_int); |
|
|