mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Add more tests
Reuse threads on gst_run when possible change name of getline to gst_getline
This commit is contained in:
		
							
								
								
									
										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; | ||||
|   | ||||
							
								
								
									
										28
									
								
								core/stl.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								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,9 +903,13 @@ 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); | ||||
|     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))); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /***/ | ||||
| /* Parsing */ | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
							
								
								
									
										16
									
								
								core/vm.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								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; | ||||
|             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) { | ||||
|     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" | ||||
|  | ||||
|   | ||||
| @@ -489,6 +489,7 @@ 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_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);  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose