mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 11:09:54 +00:00
Add more tests
Reuse threads on gst_run when possible change name of getline to gst_getline
This commit is contained in:
parent
7e46ead2f4
commit
21bd960865
7
Makefile
7
Makefile
@ -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
|
||||
|
@ -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;
|
||||
|
30
core/stl.c
30
core/stl.c
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
/***/
|
||||
|
@ -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;
|
||||
|
24
core/vm.c
24
core/vm.c
@ -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) {
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user