1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-16 10:19:55 +00:00

Add more tests

Reuse threads on gst_run when possible
change name of getline to gst_getline
This commit is contained in:
Calvin Rose 2017-06-29 21:57:09 -04:00
parent 7e46ead2f4
commit 21bd960865
7 changed files with 73 additions and 26 deletions

View File

@ -39,7 +39,7 @@ debug: $(GST_TARGET)
gdb $(GST_TARGET)
valgrind: $(GST_TARGET)
valgrind --leak-check=full ./$(GST_TARGET)
valgrind --leak-check=full -v ./$(GST_TARGET)
clean:
rm $(GST_TARGET) || true
@ -51,4 +51,7 @@ clean:
test: $(GST_TARGET)
$(GST_TARGET) gsttests/basic.gst
.PHONY: clean install run debug valgrind
valtest: $(GST_TARGET)
valgrind --leak-check=full -v ./$(GST_TARGET) gsttests/basic.gst
.PHONY: clean install run debug valgrind test valtest

View File

@ -25,7 +25,7 @@
#include <gst/gst.h>
/* Simple read line functionality */
char *getline() {
static char *gst_getline() {
char *line = malloc(100);
char *linep = line;
size_t lenmax = 100;
@ -55,7 +55,7 @@ char *getline() {
}
/* Compile and run an ast */
int debug_compile_and_run(Gst *vm, GstValue ast, GstValue last) {
static int debug_compile_and_run(Gst *vm, GstValue ast, GstValue last) {
GstCompiler c;
GstValue func;
/* Try to compile generated AST */
@ -80,7 +80,7 @@ int debug_compile_and_run(Gst *vm, GstValue ast, GstValue last) {
}
/* Parse a file and execute it */
int debug_run(Gst *vm, FILE *in) {
static int debug_run(Gst *vm, FILE *in) {
char buffer[2048] = {0};
const char *reader = buffer;
GstParser p;
@ -123,7 +123,7 @@ int debug_run(Gst *vm, FILE *in) {
}
/* A simple repl */
int debug_repl(Gst *vm) {
static int debug_repl(Gst *vm) {
char *buffer, *reader;
GstParser p;
buffer = reader = NULL;
@ -138,7 +138,7 @@ int debug_repl(Gst *vm) {
printf("\x1B[32m>>\x1B[0m ");
if (buffer)
free(buffer);
buffer = getline();
buffer = gst_getline();
if (!buffer || *buffer == '\0')
return 0;
reader = buffer;

View File

@ -450,13 +450,16 @@ int gst_stl_thread(Gst *vm) {
t->parent = parent.data.thread;
} else if (parent.type != GST_NIL) {
gst_c_throwc(vm, "expected thread/nil as parent");
} else {
t->parent = vm->thread;
}
if (errorParent.type == GST_THREAD) {
t->errorParent = errorParent.data.thread;
} else if (errorParent.type != GST_NIL) {
gst_c_throwc(vm, "expected thread/nil as error parent");
} else {
t->errorParent = vm->thread;
}
t->parent = vm->thread;
gst_c_return(vm, gst_wrap_thread(t));
}
@ -830,9 +833,12 @@ int gst_stl_gcollect(Gst *vm) {
}
/* Static debug print helper */
static GstInteger gst_stl_debugp_helper(Gst *vm, GstBuffer *b, GstTable *seen, GstValue x, GstInteger next) {
static GstInteger gst_stl_debugp_helper(Gst *vm, GstBuffer *b, GstTable *seen, GstValue x, GstInteger next, int depth) {
GstValue check = gst_table_get(seen, x);
const uint8_t *str;
/* Prevent a stack overflow */
if (depth++ > GST_RECURSION_GUARD)
return -1;
if (check.type == GST_INTEGER) {
str = gst_to_string(vm, check);
gst_buffer_append_cstring(vm, b, "<visited ");
@ -870,14 +876,20 @@ static GstInteger gst_stl_debugp_helper(Gst *vm, GstBuffer *b, GstTable *seen, G
isfirst = 0;
else
gst_buffer_push(vm, b, ' ');
next = gst_stl_debugp_helper(vm, b, seen, data[i], next);
next = gst_stl_debugp_helper(vm, b, seen, data[i], next, depth);
if (next == -1)
return -1;
gst_buffer_push(vm, b, ' ');
next = gst_stl_debugp_helper(vm, b, seen, data[i + 1], next);
next = gst_stl_debugp_helper(vm, b, seen, data[i + 1], next, depth);
if (next == -1)
return -1;
}
}
} else if (gst_seq_view(x, &data, &len)) {
for (i = 0; i < len; ++i) {
next = gst_stl_debugp_helper(vm, b, seen, data[i], next);
next = gst_stl_debugp_helper(vm, b, seen, data[i], next, depth);
if (next == -1)
return -1;
if (i != len - 1)
gst_buffer_push(vm, b, ' ');
}
@ -891,8 +903,12 @@ static GstInteger gst_stl_debugp_helper(Gst *vm, GstBuffer *b, GstTable *seen, G
int gst_stl_debugp(Gst *vm) {
GstValue x = gst_arg(vm, 0);
GstBuffer *buf = gst_buffer(vm, 10);
gst_stl_debugp_helper(vm, buf, gst_table(vm, 10), x, 0);
gst_c_return(vm, gst_wrap_string(gst_buffer_to_string(vm, buf)));
GstInteger res = gst_stl_debugp_helper(vm, buf, gst_table(vm, 10), x, 0, 0);
if (res == -1) {
gst_c_throwc(vm, "recursed too deeply in debugp");
} else {
gst_c_return(vm, gst_wrap_string(gst_buffer_to_string(vm, buf)));
}
}
/***/

View File

@ -25,14 +25,18 @@
/* Create a new thread */
GstThread *gst_thread(Gst *vm, GstValue callee, uint32_t capacity) {
GstThread *thread = gst_alloc(vm, sizeof(GstThread));
GstValue *data, *stack;
if (capacity < GST_FRAME_SIZE) capacity = GST_FRAME_SIZE;
data = gst_alloc(vm, sizeof(GstValue) * capacity);
thread->data = gst_alloc(vm, sizeof(GstValue) * capacity);
thread->capacity = capacity;
return gst_thread_reset(vm, thread, callee);
}
/* Clear a thread (reset it) */
GstThread *gst_thread_reset(Gst *vm, GstThread *thread, GstValue callee) {
GstValue *stack;
thread->count = GST_FRAME_SIZE;
thread->data = data;
thread->status = GST_THREAD_PENDING;
stack = data + GST_FRAME_SIZE;
stack = thread->data + GST_FRAME_SIZE;
gst_frame_size(stack) = 0;
gst_frame_prevsize(stack) = 0;
gst_frame_ret(stack) = 0;

View File

@ -299,7 +299,6 @@ int gst_continue(Gst *vm) {
temp = vm->ret;
goto vm_return;
} else {
stack = gst_thread_popframe(vm, vm->thread);
goto vm_error;
}
} else {
@ -377,7 +376,9 @@ int gst_continue(Gst *vm) {
/* Handle returning from stack frame. Expect return value in temp. */
vm_return:
stack = gst_thread_popframe(vm, vm->thread);
while (vm->thread->count < GST_FRAME_SIZE) {
while (vm->thread->count < GST_FRAME_SIZE ||
vm->thread->status == GST_THREAD_DEAD ||
vm->thread->status == GST_THREAD_ERROR) {
vm->thread->status = GST_THREAD_DEAD;
if (vm->thread->parent) {
vm->thread = vm->thread->parent;
@ -387,6 +388,7 @@ int gst_continue(Gst *vm) {
return GST_RETURN_OK;
}
}
vm->thread->status = GST_THREAD_ALIVE;
pc = gst_frame_pc(stack);
stack[gst_frame_ret(stack)] = temp;
continue;
@ -394,9 +396,14 @@ int gst_continue(Gst *vm) {
/* Handle errors from c functions and vm opcodes */
vm_error:
vm->thread->status = GST_THREAD_ERROR;
if (vm->thread->errorParent == NULL)
return GST_RETURN_ERROR;
vm->thread = vm->thread->errorParent;
while (vm->thread->count < GST_FRAME_SIZE ||
vm->thread->status == GST_THREAD_DEAD ||
vm->thread->status == GST_THREAD_ERROR) {
if (vm->thread->errorParent == NULL)
return GST_RETURN_ERROR;
vm->thread = vm->thread->errorParent;
}
vm->thread->status = GST_THREAD_ALIVE;
stack = vm->thread->data + vm->thread->count;
stack[gst_frame_ret(stack)] = vm->ret;
pc = gst_frame_pc(stack);
@ -416,7 +423,12 @@ int gst_continue(Gst *vm) {
/* Run the vm with a given function. This function is
* called to start the vm. */
int gst_run(Gst *vm, GstValue callee) {
vm->thread = gst_thread(vm, callee, 64);
if (vm->thread == NULL) {
vm->thread = gst_thread(vm, callee, 64);
} else {
/* Reuse old thread */
gst_thread_reset(vm, vm->thread, callee);
}
if (vm->thread == NULL)
return GST_RETURN_CRASH;
if (callee.type == GST_CFUNCTION) {

View File

@ -48,6 +48,8 @@
(assert (= accum 65536) "loop")
(assert (= (struct 1 2 3 4 5 6 7 8) (struct 7 8 5 6 3 4 1 2)) "struct order does not matter")
"Serialization tests"
(def scheck (fn [x]
(def dat (serialize x))
@ -64,7 +66,16 @@
(scheck (tuple 1 2 3))
(scheck 123412.12)
(scheck (struct (struct 1 2 3 "a") (struct 1 2 3 "a") false 1 "asdasd" (tuple "a" "b")))
(scheck "psdafoilasdfbiusbdfliasbldfiubaslidufbliausdbfiluasbdfiulbasldiufbalisudhfiasudbfaisuldfbl")
(scheck "qwertyuiopasdfghjklzxcvbnm123456789")
(scheck "qwertyuiopasdfghjklzxcvbnm1234567890!@#$%^&*()")
(def athread (thread (fn [x]
(error (string "hello, " x)))))
(def athread-result (tran athread "world!"))
(assert (= athread-result "hello, world!") "thread error result")
(assert (= (status athread) "error") "thread error status")
"All tests passed"

View File

@ -488,7 +488,8 @@ GstValue gst_table_next(GstTable *o, GstValue key);
/****/
#define gst_thread_stack(t) ((t)->data + (t)->count)
GstThread *gst_thread(Gst *vm, GstValue callee, uint32_t capacity);
GstThread *gst_thread(Gst *vm, GstValue callee, uint32_t capacity);
GstThread *gst_thread_reset(Gst *vm, GstThread *thread, GstValue callee);
void gst_thread_ensure_extra(Gst *vm, GstThread *thread, uint32_t extra);
void gst_thread_push(Gst *vm, GstThread *thread, GstValue x);
void gst_thread_pushnil(Gst *vm, GstThread *thread, uint32_t n);