|
@ -116,14 +116,14 @@ int ink_add_native(struct context* ctx, const char* name, void(*value)(struct co |
|
|
int len; |
|
|
int len; |
|
|
char* copy; |
|
|
char* copy; |
|
|
if(ctx->native_words == NULL) { |
|
|
if(ctx->native_words == NULL) { |
|
|
ctx->native_words = ctx->inner_malloc(sizeof(struct native_fn) * 8); |
|
|
|
|
|
|
|
|
ctx->native_words = ctx->inner_malloc(n">ctx, sizeof(struct native_fn) * 8); |
|
|
ctx->native_words_top = 0; |
|
|
ctx->native_words_top = 0; |
|
|
ctx->native_words_capacity = 8; |
|
|
ctx->native_words_capacity = 8; |
|
|
} else if(ctx->native_words_top == ctx->native_words_capacity) { |
|
|
} else if(ctx->native_words_top == ctx->native_words_capacity) { |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (ctx->native_words_capacity + ctx->native_words_capacity/2); |
|
|
new_count = (ctx->native_words_capacity + ctx->native_words_capacity/2); |
|
|
renewed = ctx->inner_realloc(ctx->native_words, sizeof(struct native_fn) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->inner_realloc(ctxp">, ctx->native_words, sizeof(struct native_fn) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
return -3; |
|
|
return -3; |
|
|
} else { |
|
|
} else { |
|
@ -132,7 +132,7 @@ int ink_add_native(struct context* ctx, const char* name, void(*value)(struct co |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
len = strlen(name); |
|
|
len = strlen(name); |
|
|
copy = ctx->inner_malloc(len+1); |
|
|
|
|
|
|
|
|
copy = ctx->inner_malloc(ctx, len+1); |
|
|
if(copy == NULL) { |
|
|
if(copy == NULL) { |
|
|
return -4; |
|
|
return -4; |
|
|
} |
|
|
} |
|
@ -149,14 +149,14 @@ static int ink_add_indigenous(struct context* ctx, const char* name, struct elem |
|
|
char* copy; |
|
|
char* copy; |
|
|
|
|
|
|
|
|
if(ctx->words == NULL) { |
|
|
if(ctx->words == NULL) { |
|
|
ctx->words = ctx->malloc(sizeof(struct fn) * 8); |
|
|
|
|
|
|
|
|
ctx->words = ctx->malloc(n">ctx, sizeof(struct fn) * 8); |
|
|
ctx->words_top = 0; |
|
|
ctx->words_top = 0; |
|
|
ctx->words_capacity = 8; |
|
|
ctx->words_capacity = 8; |
|
|
} else if(ctx->words_top == ctx->words_capacity) { |
|
|
} else if(ctx->words_top == ctx->words_capacity) { |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (ctx->words_capacity + ctx->words_capacity/2); |
|
|
new_count = (ctx->words_capacity + ctx->words_capacity/2); |
|
|
renewed = ctx->realloc(ctx->words, sizeof(struct fn) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->realloc(ctxp">, ctx->words, sizeof(struct fn) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
return -1; |
|
|
return -1; |
|
|
} else { |
|
|
} else { |
|
@ -166,21 +166,21 @@ static int ink_add_indigenous(struct context* ctx, const char* name, struct elem |
|
|
} |
|
|
} |
|
|
for(i = 0; i < ctx->words_top; ++i) { |
|
|
for(i = 0; i < ctx->words_top; ++i) { |
|
|
if(strcmp(name, ctx->words[i].name) == 0) { |
|
|
if(strcmp(name, ctx->words[i].name) == 0) { |
|
|
ctx->free(ctx->words[i].things); |
|
|
|
|
|
ctx->words[i].things = ctx->malloc(sizeof(struct elem) * count); |
|
|
|
|
|
|
|
|
ctx->free(ctxp">, ctx->words[i].things); |
|
|
|
|
|
ctx->words[i].things = ctx->malloc(n">ctx, sizeof(struct elem) * count); |
|
|
memcpy(ctx->words[i].things, m, sizeof(struct elem) * count); |
|
|
memcpy(ctx->words[i].things, m, sizeof(struct elem) * count); |
|
|
ctx->words[i].size = count; |
|
|
ctx->words[i].size = count; |
|
|
return i; |
|
|
return i; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
len = strlen(name); |
|
|
len = strlen(name); |
|
|
copy = ctx->malloc(len+1); |
|
|
|
|
|
|
|
|
copy = ctx->malloc(ctx, len+1); |
|
|
if(copy == NULL) { |
|
|
if(copy == NULL) { |
|
|
return -2; |
|
|
return -2; |
|
|
} |
|
|
} |
|
|
memcpy(copy, name, len); |
|
|
memcpy(copy, name, len); |
|
|
copy[len] = 0; |
|
|
copy[len] = 0; |
|
|
ctx->words[ctx->words_top].things = ctx->malloc(sizeof(struct elem) * count); |
|
|
|
|
|
|
|
|
ctx->words[ctx->words_top].things = ctx->malloc(n">ctx, sizeof(struct elem) * count); |
|
|
memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count); |
|
|
memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count); |
|
|
ctx->words[ctx->words_top].size = count; |
|
|
ctx->words[ctx->words_top].size = count; |
|
|
ctx->words[ctx->words_top].name = copy; |
|
|
ctx->words[ctx->words_top].name = copy; |
|
@ -198,14 +198,14 @@ static int ink_add_lex_string(struct context* ctx, const char* name) { |
|
|
int i; |
|
|
int i; |
|
|
int len; |
|
|
int len; |
|
|
if(ctx->lex_reserved_words == NULL) { |
|
|
if(ctx->lex_reserved_words == NULL) { |
|
|
ctx->lex_reserved_words = ctx->inner_malloc(sizeof(char*) * 8); |
|
|
|
|
|
|
|
|
ctx->lex_reserved_words = ctx->inner_malloc(n">ctx, sizeof(char*) * 8); |
|
|
ctx->lex_reserved_words_top = 0; |
|
|
ctx->lex_reserved_words_top = 0; |
|
|
ctx->lex_reserved_words_capacity = 8; |
|
|
ctx->lex_reserved_words_capacity = 8; |
|
|
} else if(ctx->lex_reserved_words_top == ctx->lex_reserved_words_capacity) { |
|
|
} else if(ctx->lex_reserved_words_top == ctx->lex_reserved_words_capacity) { |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (ctx->lex_reserved_words_capacity + ctx->lex_reserved_words_capacity/2); |
|
|
new_count = (ctx->lex_reserved_words_capacity + ctx->lex_reserved_words_capacity/2); |
|
|
renewed = ctx->inner_realloc(ctx->lex_reserved_words, sizeof(struct native_fn) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->inner_realloc(ctxp">, ctx->lex_reserved_words, sizeof(struct native_fn) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
return -5; |
|
|
return -5; |
|
|
} else { |
|
|
} else { |
|
@ -220,7 +220,7 @@ static int ink_add_lex_string(struct context* ctx, const char* name) { |
|
|
} |
|
|
} |
|
|
len = strlen(name); |
|
|
len = strlen(name); |
|
|
i = ctx->lex_reserved_words_top; |
|
|
i = ctx->lex_reserved_words_top; |
|
|
ctx->lex_reserved_words[i] = ctx->malloc(len+1); |
|
|
|
|
|
|
|
|
ctx->lex_reserved_words[i] = ctx->malloc(ctx, len+1); |
|
|
memcpy(ctx->lex_reserved_words[i], name, len); |
|
|
memcpy(ctx->lex_reserved_words[i], name, len); |
|
|
ctx->lex_reserved_words[i][len] = 0; |
|
|
ctx->lex_reserved_words[i][len] = 0; |
|
|
ctx->lex_reserved_words_top++; |
|
|
ctx->lex_reserved_words_top++; |
|
@ -232,14 +232,14 @@ int ink_push(struct context* ctx, struct elem value) { |
|
|
if(ctx->routine_current >= ctx->routines_top) return -65; |
|
|
if(ctx->routine_current >= ctx->routines_top) return -65; |
|
|
current = ctx->routines + ctx->routine_current; |
|
|
current = ctx->routines + ctx->routine_current; |
|
|
if(current->stack == NULL) { |
|
|
if(current->stack == NULL) { |
|
|
current->stack = ctx->malloc(sizeof(struct elem) * 8); |
|
|
|
|
|
|
|
|
current->stack = ctx->malloc(n">ctx, sizeof(struct elem) * 8); |
|
|
current->top = 0; |
|
|
current->top = 0; |
|
|
current->capacity = 8; |
|
|
current->capacity = 8; |
|
|
} else if(current->top == current->capacity) { |
|
|
} else if(current->top == current->capacity) { |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (current->capacity + current->capacity/2); |
|
|
new_count = (current->capacity + current->capacity/2); |
|
|
renewed = ctx->realloc(current->stack, sizeof(struct elem) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->realloc(ctx, current->stack, sizeof(struct elem) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
return -18; |
|
|
return -18; |
|
|
} else { |
|
|
} else { |
|
@ -259,14 +259,14 @@ int ink_push_fn(struct context* ctx, struct stack_frame value) { |
|
|
current = ctx->routines + ctx->routine_current; |
|
|
current = ctx->routines + ctx->routine_current; |
|
|
if(current->panic) return -56; |
|
|
if(current->panic) return -56; |
|
|
if(current->function_stack == NULL) { |
|
|
if(current->function_stack == NULL) { |
|
|
current->function_stack = ctx->malloc(sizeof(struct stack_frame) * 8); |
|
|
|
|
|
|
|
|
current->function_stack = ctx->malloc(n">ctx, sizeof(struct stack_frame) * 8); |
|
|
current->function_stack_top = 0; |
|
|
current->function_stack_top = 0; |
|
|
current->function_stack_capacity = 8; |
|
|
current->function_stack_capacity = 8; |
|
|
} else if(current->function_stack_top == current->function_stack_capacity) { |
|
|
} else if(current->function_stack_top == current->function_stack_capacity) { |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (current->function_stack_capacity + current->function_stack_capacity/2); |
|
|
new_count = (current->function_stack_capacity + current->function_stack_capacity/2); |
|
|
renewed = ctx->realloc(current->function_stack, sizeof(struct stack_frame) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->realloc(ctx, current->function_stack, sizeof(struct stack_frame) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
return -9; |
|
|
return -9; |
|
|
} else { |
|
|
} else { |
|
@ -295,23 +295,23 @@ void ink_pop(struct context* ctx) { |
|
|
ctx->routines[ctx->routine_current].top--; |
|
|
ctx->routines[ctx->routine_current].top--; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, size_t), void(*free)(void*), int(*putchar)(int)) { |
|
|
|
|
|
|
|
|
struct context* ink_make_context(void*(*malloc)(k">struct context*, size_t), void*(*realloc)(struct context*, void*, size_t), void(*free)(">struct context*, void*), int(*putchar)(struct context*, int)) { |
|
|
struct context* ctx; |
|
|
struct context* ctx; |
|
|
ctx = (struct context*)malloc(sizeof(struct context)); |
|
|
|
|
|
ctx->malloc = malloc; |
|
|
|
|
|
ctx->realloc = realloc; |
|
|
|
|
|
ctx->free = free; |
|
|
|
|
|
ctx->inner_malloc = malloc; |
|
|
|
|
|
ctx->inner_realloc = realloc; |
|
|
|
|
|
ctx->inner_free = free; |
|
|
|
|
|
ctx->putchar = putchar; |
|
|
|
|
|
|
|
|
ctx = (struct context*)malloc(nb">NULL, sizeof(struct context)); |
|
|
|
|
|
ctx->malloc = malloc; |
|
|
|
|
|
ctx->realloc = realloc; |
|
|
|
|
|
ctx->free = free; |
|
|
|
|
|
ctx->inner_malloc = malloc; |
|
|
|
|
|
ctx->inner_realloc = realloc; |
|
|
|
|
|
ctx->inner_free = free; |
|
|
|
|
|
ctx->putchar = putchar; |
|
|
ctx->panic = 0; |
|
|
ctx->panic = 0; |
|
|
ctx->routines = NULL; |
|
|
ctx->routines = NULL; |
|
|
ctx->routines_capacity = 0; |
|
|
ctx->routines_capacity = 0; |
|
|
ctx->routines_top = 0; |
|
|
ctx->routines_top = 0; |
|
|
ctx->types = NULL; |
|
|
|
|
|
ctx->types_capacity = 0; |
|
|
|
|
|
ctx->types_top = 0; |
|
|
|
|
|
|
|
|
ctx->types = NULL; |
|
|
|
|
|
ctx->types_capacity = 0; |
|
|
|
|
|
ctx->types_top = 0; |
|
|
ctx->native_words = NULL; |
|
|
ctx->native_words = NULL; |
|
|
ctx->native_words_capacity = 0; |
|
|
ctx->native_words_capacity = 0; |
|
|
ctx->native_words_top = 0; |
|
|
ctx->native_words_top = 0; |
|
@ -321,11 +321,40 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, |
|
|
ctx->lex_reserved_words = NULL; |
|
|
ctx->lex_reserved_words = NULL; |
|
|
ctx->lex_reserved_words_capacity = 0; |
|
|
ctx->lex_reserved_words_capacity = 0; |
|
|
ctx->lex_reserved_words_top = 0; |
|
|
ctx->lex_reserved_words_top = 0; |
|
|
ctx->collections = 0; |
|
|
|
|
|
ctx->steps = 0; |
|
|
|
|
|
|
|
|
ctx->collections = 0; |
|
|
|
|
|
ctx->steps = 0; |
|
|
return ctx; |
|
|
return ctx; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ink_make_context_inplace(struct context* location, void*(*malloc)(struct context*, size_t), void*(*realloc)(struct context*, void*, size_t), void(*free)(struct context*, void*), int(*putchar)(struct context*, int)) { |
|
|
|
|
|
struct context* ctx = location; |
|
|
|
|
|
ctx->malloc = malloc; |
|
|
|
|
|
ctx->realloc = realloc; |
|
|
|
|
|
ctx->free = free; |
|
|
|
|
|
ctx->inner_malloc = malloc; |
|
|
|
|
|
ctx->inner_realloc = realloc; |
|
|
|
|
|
ctx->inner_free = free; |
|
|
|
|
|
ctx->putchar = putchar; |
|
|
|
|
|
ctx->panic = 0; |
|
|
|
|
|
ctx->routines = NULL; |
|
|
|
|
|
ctx->routines_capacity = 0; |
|
|
|
|
|
ctx->routines_top = 0; |
|
|
|
|
|
ctx->types = NULL; |
|
|
|
|
|
ctx->types_capacity = 0; |
|
|
|
|
|
ctx->types_top = 0; |
|
|
|
|
|
ctx->native_words = NULL; |
|
|
|
|
|
ctx->native_words_capacity = 0; |
|
|
|
|
|
ctx->native_words_top = 0; |
|
|
|
|
|
ctx->words = NULL; |
|
|
|
|
|
ctx->words_capacity = 0; |
|
|
|
|
|
ctx->words_top = 0; |
|
|
|
|
|
ctx->lex_reserved_words = NULL; |
|
|
|
|
|
ctx->lex_reserved_words_capacity = 0; |
|
|
|
|
|
ctx->lex_reserved_words_top = 0; |
|
|
|
|
|
ctx->collections = 0; |
|
|
|
|
|
ctx->steps = 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Allocates a string that contains the integer |
|
|
* Allocates a string that contains the integer |
|
|
* @param _ context (used to allocate) |
|
|
* @param _ context (used to allocate) |
|
@ -336,7 +365,7 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, |
|
|
static char* ink_itoa(struct context* _, int cpy) { |
|
|
static char* ink_itoa(struct context* _, int cpy) { |
|
|
char* n; |
|
|
char* n; |
|
|
char* it; |
|
|
char* it; |
|
|
n = _->malloc(16); |
|
|
|
|
|
|
|
|
n = _->malloc(n">_, 16); |
|
|
n[15] = 0; |
|
|
n[15] = 0; |
|
|
it = n+15; |
|
|
it = n+15; |
|
|
do { |
|
|
do { |
|
@ -349,9 +378,26 @@ static char* ink_itoa(struct context* _, int cpy) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#ifndef NOSTDLIB |
|
|
#ifndef NOSTDLIB |
|
|
|
|
|
static void* ink_malloc(struct context* _, size_t sz) { |
|
|
|
|
|
_=_; |
|
|
|
|
|
return malloc(sz); |
|
|
|
|
|
} |
|
|
|
|
|
static void* ink_realloc(struct context* _, void* ptr, size_t sz) { |
|
|
|
|
|
_=_; |
|
|
|
|
|
return realloc(ptr, sz); |
|
|
|
|
|
} |
|
|
|
|
|
static void ink_free(struct context* _, void* ptr) { |
|
|
|
|
|
_=_; |
|
|
|
|
|
free(ptr); |
|
|
|
|
|
} |
|
|
|
|
|
static int ink_putchar(struct context* _, int c) { |
|
|
|
|
|
_=_; |
|
|
|
|
|
return putchar(c); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
struct context* ink_make_default_context(void) { |
|
|
struct context* ink_make_default_context(void) { |
|
|
struct context* ctx; |
|
|
struct context* ctx; |
|
|
ctx = ink_make_context(malloc, realloc, free, putchar); |
|
|
|
|
|
|
|
|
ctx = ink_make_context(ink_malloc, ink_realloc, ink_free, ink_putchar); |
|
|
ink_std_library(ctx); |
|
|
ink_std_library(ctx); |
|
|
return ctx; |
|
|
return ctx; |
|
|
} |
|
|
} |
|
@ -584,7 +630,7 @@ int ink_make_routine(struct context* ctx) { |
|
|
|
|
|
|
|
|
/* Allocate space if needed */ |
|
|
/* Allocate space if needed */ |
|
|
if(ctx->routines == NULL) { |
|
|
if(ctx->routines == NULL) { |
|
|
ctx->routines = ctx->inner_malloc(sizeof(struct ink_routine) * 8); |
|
|
|
|
|
|
|
|
ctx->routines = ctx->inner_malloc(n">ctx, sizeof(struct ink_routine) * 8); |
|
|
ctx->routines_top = 0; |
|
|
ctx->routines_top = 0; |
|
|
ctx->routines_capacity = 8; |
|
|
ctx->routines_capacity = 8; |
|
|
it = ctx->routines; |
|
|
it = ctx->routines; |
|
@ -600,7 +646,7 @@ int ink_make_routine(struct context* ctx) { |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (ctx->routines_capacity + ctx->routines_capacity/2); |
|
|
new_count = (ctx->routines_capacity + ctx->routines_capacity/2); |
|
|
renewed = ctx->inner_realloc(ctx->routines, sizeof(struct ink_routine) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->inner_realloc(ctxp">, ctx->routines, sizeof(struct ink_routine) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
return -99; |
|
|
return -99; |
|
|
} else { |
|
|
} else { |
|
@ -649,11 +695,11 @@ int ink_kill_routine(struct context* ctx, int routine){ |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
if(curr->stack != NULL) { |
|
|
if(curr->stack != NULL) { |
|
|
ctx->free(curr->stack); |
|
|
|
|
|
|
|
|
ctx->free(ctx, curr->stack); |
|
|
curr->stack = NULL; |
|
|
curr->stack = NULL; |
|
|
} |
|
|
} |
|
|
if(curr->function_stack != NULL) { |
|
|
if(curr->function_stack != NULL) { |
|
|
ctx->free(curr->function_stack); |
|
|
|
|
|
|
|
|
ctx->free(ctx, curr->function_stack); |
|
|
curr->function_stack = NULL; |
|
|
curr->function_stack = NULL; |
|
|
} |
|
|
} |
|
|
curr->panic = INK_ROUTINE_CAN_REUSE; |
|
|
curr->panic = INK_ROUTINE_CAN_REUSE; |
|
@ -932,7 +978,7 @@ int ink_compile(struct context *pContext, const char* buffer) { |
|
|
integer = ink_itoa(pContext, routine); |
|
|
integer = ink_itoa(pContext, routine); |
|
|
integer_size = strlen(integer); |
|
|
integer_size = strlen(integer); |
|
|
memcpy(main_fn + 10, integer, integer_size); |
|
|
memcpy(main_fn + 10, integer, integer_size); |
|
|
pContext->free(integer); |
|
|
|
|
|
|
|
|
pContext->free(pContext, integer); |
|
|
main_fn[10 + integer_size] = 0; |
|
|
main_fn[10 + integer_size] = 0; |
|
|
frame.executing.value = ink_add_indigenous(pContext, main_fn, executable_buffer, executable_buffer_top); |
|
|
frame.executing.value = ink_add_indigenous(pContext, main_fn, executable_buffer, executable_buffer_top); |
|
|
if (frame.executing.value < 0) { |
|
|
if (frame.executing.value < 0) { |
|
@ -1023,14 +1069,14 @@ int ink_new_type( |
|
|
if(ctx->panic) return -128; |
|
|
if(ctx->panic) return -128; |
|
|
/* Resize for push */ |
|
|
/* Resize for push */ |
|
|
if(ctx->types == NULL) { |
|
|
if(ctx->types == NULL) { |
|
|
ctx->types = ctx->inner_malloc(sizeof(struct ink_type) * 8); |
|
|
|
|
|
|
|
|
ctx->types = ctx->inner_malloc(n">ctx, sizeof(struct ink_type) * 8); |
|
|
ctx->types_top = 0; |
|
|
ctx->types_top = 0; |
|
|
ctx->types_capacity = 8; |
|
|
ctx->types_capacity = 8; |
|
|
} else if(ctx->types_top == ctx->types_capacity) { |
|
|
} else if(ctx->types_top == ctx->types_capacity) { |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (ctx->types_capacity + ctx->types_capacity/2); |
|
|
new_count = (ctx->types_capacity + ctx->types_capacity/2); |
|
|
renewed = ctx->inner_realloc(ctx->types, sizeof(struct ink_type) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->inner_realloc(ctxp">, ctx->types, sizeof(struct ink_type) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
return -129; |
|
|
return -129; |
|
|
} else { |
|
|
} else { |
|
@ -1099,7 +1145,7 @@ struct elem ink_make_native_unsafe(struct context* ctx, int type, void* ptr, int |
|
|
|
|
|
|
|
|
/* Resize for push of value in store */ |
|
|
/* Resize for push of value in store */ |
|
|
if(ctx->types[type_id].elements == NULL) { |
|
|
if(ctx->types[type_id].elements == NULL) { |
|
|
ctx->types[type_id].elements = ctx->inner_malloc(sizeof(struct element_slab) * 8); |
|
|
|
|
|
|
|
|
ctx->types[type_id].elements = ctx->inner_malloc(n">ctx, 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, sizeof(struct element_slab)*(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, sizeof(struct element_slab)*(ctx->types[type_id].elements_capacity - ctx->types[type_id].elements_top)); |
|
@ -1107,7 +1153,7 @@ struct elem ink_make_native_unsafe(struct context* ctx, int type, void* ptr, int |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (ctx->types[type_id].elements_capacity + ctx->types[type_id].elements_capacity/2); |
|
|
new_count = (ctx->types[type_id].elements_capacity + ctx->types[type_id].elements_capacity/2); |
|
|
renewed = ctx->inner_realloc(ctx->types[type_id].elements, sizeof(struct element_slab) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->inner_realloc(ctxp">, ctx->types[type_id].elements, sizeof(struct element_slab) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
ret.type = 0; |
|
|
ret.type = 0; |
|
|
ret.value = -129; |
|
|
ret.value = -129; |
|
@ -1129,7 +1175,7 @@ struct elem ink_make_native_unsafe(struct context* ctx, int type, void* ptr, int |
|
|
if(ctx->types[type_id].element_size < 0) { |
|
|
if(ctx->types[type_id].element_size < 0) { |
|
|
ctx->types[type_id].elements[i].data = ptr; |
|
|
ctx->types[type_id].elements[i].data = ptr; |
|
|
} else { |
|
|
} else { |
|
|
void* new_ptr = ctx->malloc(ctx->types[type_id].element_size); |
|
|
|
|
|
|
|
|
void* new_ptr = ctx->malloc(ctxp">, ctx->types[type_id].element_size); |
|
|
if(new_ptr == NULL) { |
|
|
if(new_ptr == NULL) { |
|
|
ret.type = 0; |
|
|
ret.type = 0; |
|
|
ret.value = -139; |
|
|
ret.value = -139; |
|
@ -1183,8 +1229,8 @@ void ink_gc(struct context* ctx) { |
|
|
/* Start by marking the roots of the routines, Clear the routines if possible */ |
|
|
/* Start by marking the roots of the routines, Clear the routines if possible */ |
|
|
for(i = 0; i < ctx->routines_top; ++i) { |
|
|
for(i = 0; i < ctx->routines_top; ++i) { |
|
|
if(ctx->routines[i].panic == INK_ROUTINE_SUCCESS) { |
|
|
if(ctx->routines[i].panic == INK_ROUTINE_SUCCESS) { |
|
|
ctx->free(ctx->routines[i].stack); |
|
|
|
|
|
ctx->free(ctx->routines[i].function_stack); |
|
|
|
|
|
|
|
|
ctx->free(ctxp">, ctx->routines[i].stack); |
|
|
|
|
|
ctx->free(ctxp">, ctx->routines[i].function_stack); |
|
|
ctx->routines[i].panic = INK_ROUTINE_CAN_REUSE; |
|
|
ctx->routines[i].panic = INK_ROUTINE_CAN_REUSE; |
|
|
} |
|
|
} |
|
|
if(ctx->routines[i].panic == INK_ROUTINE_CAN_REUSE) { |
|
|
if(ctx->routines[i].panic == INK_ROUTINE_CAN_REUSE) { |
|
@ -1215,7 +1261,7 @@ void ink_gc(struct context* ctx) { |
|
|
marked = 1; |
|
|
marked = 1; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if (c.elements != NULL) ctx->inner_free(c.elements); |
|
|
|
|
|
|
|
|
if (c.elements != NULL) ctx->inner_free(ctx, c.elements); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1228,7 +1274,7 @@ void ink_gc(struct context* ctx) { |
|
|
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) { |
|
|
ctx->free(ctx->types[i].elements[j].data); |
|
|
|
|
|
|
|
|
ctx->free(ctxp">, ctx->types[i].elements[j].data); |
|
|
} |
|
|
} |
|
|
ctx->types[i].elements[j].data = NULL; |
|
|
ctx->types[i].elements[j].data = NULL; |
|
|
ctx->types[i].elements[j].uses = 0; |
|
|
ctx->types[i].elements[j].uses = 0; |
|
@ -1253,25 +1299,25 @@ static void print_stacktrace(struct context* _) { |
|
|
case INK_NATIVE_FUNCTION: { |
|
|
case INK_NATIVE_FUNCTION: { |
|
|
n = _->native_words[thing.value].name; |
|
|
n = _->native_words[thing.value].name; |
|
|
while (*n) { |
|
|
while (*n) { |
|
|
_->putchar(*n); |
|
|
|
|
|
|
|
|
_->putchar(n">_, *n); |
|
|
++n; |
|
|
++n; |
|
|
} |
|
|
} |
|
|
_->putchar(10); |
|
|
|
|
|
|
|
|
_->putchar(n">_, 10); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case INK_FUNCTION:{ |
|
|
case INK_FUNCTION:{ |
|
|
n = _->words[thing.value].name; |
|
|
n = _->words[thing.value].name; |
|
|
while (*n) { |
|
|
while (*n) { |
|
|
_->putchar(*n); |
|
|
|
|
|
|
|
|
_->putchar(n">_, *n); |
|
|
++n; |
|
|
++n; |
|
|
} |
|
|
} |
|
|
_->putchar(':'); |
|
|
|
|
|
|
|
|
_->putchar(n">_, ':'); |
|
|
n = ink_itoa(_, currentRoutine->function_stack[i].index); |
|
|
n = ink_itoa(_, currentRoutine->function_stack[i].index); |
|
|
while (*n) { |
|
|
while (*n) { |
|
|
_->putchar(*n); |
|
|
|
|
|
|
|
|
_->putchar(n">_, *n); |
|
|
++n; |
|
|
++n; |
|
|
} |
|
|
} |
|
|
_->putchar(10); |
|
|
|
|
|
|
|
|
_->putchar(n">_, 10); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
default: |
|
|
default: |
|
@ -1636,10 +1682,10 @@ static void print_int(struct context* ctx) { |
|
|
n = ink_itoa(ctx, a.value); |
|
|
n = ink_itoa(ctx, a.value); |
|
|
str = n; |
|
|
str = n; |
|
|
while (*str) { |
|
|
while (*str) { |
|
|
ctx->putchar(*str); |
|
|
|
|
|
|
|
|
ctx->putchar(n">ctx, *str); |
|
|
++str; |
|
|
++str; |
|
|
} |
|
|
} |
|
|
ctx->free(n); |
|
|
|
|
|
|
|
|
ctx->free(ctx, n); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void print_as_utf8(struct context* ctx) { |
|
|
static void print_as_utf8(struct context* ctx) { |
|
@ -1652,19 +1698,19 @@ static void print_as_utf8(struct context* ctx) { |
|
|
} |
|
|
} |
|
|
a = currentRoutine->stack[currentRoutine->top-1]; |
|
|
a = currentRoutine->stack[currentRoutine->top-1]; |
|
|
if(a.value <= 0x7F) { |
|
|
if(a.value <= 0x7F) { |
|
|
ctx->putchar(a.value); |
|
|
|
|
|
|
|
|
ctx->putchar(ctx, a.value); |
|
|
} else if(a.value <= 0x7FF) { |
|
|
} else if(a.value <= 0x7FF) { |
|
|
ctx->putchar(((a.value & 0xFC0) >> 6) | 192); |
|
|
|
|
|
ctx->putchar((a.value & 0x3F) | 128); |
|
|
|
|
|
|
|
|
ctx->putchar(n">ctx, ((a.value & 0xFC0) >> 6) | 192); |
|
|
|
|
|
ctx->putchar(n">ctx, (a.value & 0x3F) | 128); |
|
|
} else if(a.value <= 0xFFFF) { |
|
|
} else if(a.value <= 0xFFFF) { |
|
|
ctx->putchar(((a.value & 0x3F000) >> 12) | 224); |
|
|
|
|
|
ctx->putchar(((a.value & 0xFC0) >> 6) | 128); |
|
|
|
|
|
ctx->putchar((a.value & 0x3F) | 128); |
|
|
|
|
|
|
|
|
ctx->putchar(n">ctx, ((a.value & 0x3F000) >> 12) | 224); |
|
|
|
|
|
ctx->putchar(n">ctx, ((a.value & 0xFC0) >> 6) | 128); |
|
|
|
|
|
ctx->putchar(n">ctx, (a.value & 0x3F) | 128); |
|
|
} else if(a.value <= 0x10FFFF) { |
|
|
} else if(a.value <= 0x10FFFF) { |
|
|
ctx->putchar(((a.value & 0x3C0000) >> 18) | 240); |
|
|
|
|
|
ctx->putchar(((a.value & 0x3F000) >> 12) | 128); |
|
|
|
|
|
ctx->putchar(((a.value & 0xFC0) >> 6) | 128); |
|
|
|
|
|
ctx->putchar((a.value & 0x3F) | 128); |
|
|
|
|
|
|
|
|
ctx->putchar(n">ctx, ((a.value & 0x3C0000) >> 18) | 240); |
|
|
|
|
|
ctx->putchar(n">ctx, ((a.value & 0x3F000) >> 12) | 128); |
|
|
|
|
|
ctx->putchar(n">ctx, ((a.value & 0xFC0) >> 6) | 128); |
|
|
|
|
|
ctx->putchar(n">ctx, (a.value & 0x3F) | 128); |
|
|
} else { |
|
|
} else { |
|
|
ctx->panic = -1; |
|
|
ctx->panic = -1; |
|
|
return; |
|
|
return; |
|
@ -1709,15 +1755,15 @@ static void dump_stack(struct context* ctx) { |
|
|
idx = ink_itoa(ctx,index); |
|
|
idx = ink_itoa(ctx,index); |
|
|
type = ink_itoa(ctx, currentRoutine->stack[index].type); |
|
|
type = ink_itoa(ctx, currentRoutine->stack[index].type); |
|
|
value = ink_itoa(ctx,currentRoutine->stack[index].value); |
|
|
value = ink_itoa(ctx,currentRoutine->stack[index].value); |
|
|
for(it = idx; *it; ++it) ctx->putchar(*it); |
|
|
|
|
|
ctx->putchar(' ');ctx->putchar('|');ctx->putchar(' '); |
|
|
|
|
|
for(it = type; *it; ++it) ctx->putchar(*it); |
|
|
|
|
|
ctx->putchar(' ');ctx->putchar('|');ctx->putchar(' '); |
|
|
|
|
|
for(it = value; *it; ++it) ctx->putchar(*it); |
|
|
|
|
|
ctx->putchar('\n'); |
|
|
|
|
|
ctx->free(value); |
|
|
|
|
|
ctx->free(type); |
|
|
|
|
|
ctx->free(idx); |
|
|
|
|
|
|
|
|
for(it = idx; *it; ++it) ctx->putchar(n">ctx, *it); |
|
|
|
|
|
ctx->putchar(n">ctx, ' ');ctx->putchar(n">ctx, '|');ctx->putchar(ctx, ' '); |
|
|
|
|
|
for(it = type; *it; ++it) ctx->putchar(n">ctx, *it); |
|
|
|
|
|
ctx->putchar(n">ctx, ' ');ctx->putchar(n">ctx, '|');ctx->putchar(ctx, ' '); |
|
|
|
|
|
for(it = value; *it; ++it) ctx->putchar(n">ctx, *it); |
|
|
|
|
|
ctx->putchar(n">ctx, '\n'); |
|
|
|
|
|
ctx->free(ctx, value); |
|
|
|
|
|
ctx->free(ctx, type); |
|
|
|
|
|
ctx->free(ctx, idx); |
|
|
} |
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
@ -1736,14 +1782,14 @@ static struct ink_collection_list gc_noop() { |
|
|
static void collect_array(struct context* ctx, void* array) { |
|
|
static void collect_array(struct context* ctx, void* array) { |
|
|
struct ink_array* ary; |
|
|
struct ink_array* ary; |
|
|
ary = array; |
|
|
ary = array; |
|
|
if(ary->elements != NULL) ctx->free(ary->elements); |
|
|
|
|
|
|
|
|
if(ary->elements != NULL) ctx->free(ctx, 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) { |
|
|
struct ink_array* ary; |
|
|
struct ink_array* ary; |
|
|
struct ink_collection_list c; |
|
|
struct ink_collection_list c; |
|
|
ary = array; |
|
|
ary = array; |
|
|
c.elements = ctx->inner_malloc(sizeof(struct elem)*ary->top); |
|
|
|
|
|
|
|
|
c.elements = ctx->inner_malloc(n">ctx, sizeof(struct elem)*ary->top); |
|
|
c.count = ary->top; |
|
|
c.count = ary->top; |
|
|
memcpy(c.elements, ary->elements, sizeof(struct elem)*ary->top); |
|
|
memcpy(c.elements, ary->elements, sizeof(struct elem)*ary->top); |
|
|
return c; |
|
|
return c; |
|
@ -1787,14 +1833,14 @@ static void push_array_stack_delim(struct context* ctx) { |
|
|
|
|
|
|
|
|
int array_push_s(struct context* ctx, struct ink_array* ary, struct elem value) { |
|
|
int array_push_s(struct context* ctx, struct ink_array* ary, struct elem value) { |
|
|
if(ary->elements == NULL) { |
|
|
if(ary->elements == NULL) { |
|
|
ary->elements = ctx->malloc(sizeof(struct elem) * 8); |
|
|
|
|
|
|
|
|
ary->elements = ctx->malloc(n">ctx, sizeof(struct elem) * 8); |
|
|
ary->top = 0; |
|
|
ary->top = 0; |
|
|
ary->capacity = 8; |
|
|
ary->capacity = 8; |
|
|
} else if(ary->top == ary->capacity) { |
|
|
} else if(ary->top == ary->capacity) { |
|
|
int new_count; |
|
|
int new_count; |
|
|
void* renewed; |
|
|
void* renewed; |
|
|
new_count = (ary->capacity + ary->capacity/2); |
|
|
new_count = (ary->capacity + ary->capacity/2); |
|
|
renewed = ctx->realloc(ary->elements, sizeof(struct elem) * new_count); |
|
|
|
|
|
|
|
|
renewed = ctx->realloc(ctx, ary->elements, sizeof(struct elem) * new_count); |
|
|
if(renewed == NULL) { |
|
|
if(renewed == NULL) { |
|
|
return 1; |
|
|
return 1; |
|
|
} else { |
|
|
} else { |
|
|