mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-29 22:53:03 +00:00 
			
		
		
		
	Make some unit tests pass. Fix transfer to new fiber.
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -72,7 +72,7 @@ valgrind: $(DST_TARGET) | ||||
| 	@ valgrind --leak-check=full -v ./$(DST_TARGET) | ||||
|  | ||||
| test: $(DST_TARGET) | ||||
| 	@ ./$(DST_TARGET) dsttest/suite0.dst | ||||
| 	@ ./$(DST_TARGET) --gcinterval=0 dsttest/suite0.dst | ||||
|  | ||||
| valtest: $(DST_TARGET) | ||||
| 	valgrind --leak-check=full -v ./$(DST_TARGET) dsttests/basic.dst | ||||
|   | ||||
| @@ -176,7 +176,7 @@ static void runfile(const uint8_t *src, int32_t len) { | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) { | ||||
|     int status = -1; | ||||
|     int status = 0; | ||||
|     int i; | ||||
|     int fileRead = 0; | ||||
|     uint32_t gcinterval = 0x10000; | ||||
|   | ||||
| @@ -491,6 +491,9 @@ DstSlot dstc_fn(DstFopts opts, int32_t argn, const Dst *argv) { | ||||
|     if (varargs) def->flags |= DST_FUNCDEF_FLAG_VARARG; | ||||
|     defindex = dstc_addfuncdef(c, def); | ||||
|  | ||||
|     /* Ensure enough slots for vararg function. */ | ||||
|     if (arity + varargs > def->slotcount) def->slotcount = arity + varargs; | ||||
|  | ||||
|     /* Instantiate closure */ | ||||
|     ret.flags = 0; | ||||
|     ret.envindex = 0; | ||||
|   | ||||
| @@ -45,7 +45,7 @@ DstFiber *dst_fiber_reset(DstFiber *fiber) { | ||||
|     fiber->frame = 0; | ||||
|     fiber->stackstart = DST_FRAME_SIZE; | ||||
|     fiber->stacktop = DST_FRAME_SIZE; | ||||
|     fiber->status = DST_FIBER_PENDING; | ||||
|     fiber->status = DST_FIBER_NEW; | ||||
|     fiber->parent = NULL; | ||||
|     return fiber; | ||||
| } | ||||
|   | ||||
							
								
								
									
										44
									
								
								core/stl.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								core/stl.c
									
									
									
									
									
								
							| @@ -23,6 +23,15 @@ | ||||
| #include <dst/dst.h> | ||||
| #include <dst/dststl.h> | ||||
|  | ||||
| int dst_stl_exit(int32_t argn, Dst *argv, Dst *ret) { | ||||
|     (void)ret; | ||||
|     int32_t exitcode = 0; | ||||
|     if (argn > 0) { | ||||
|         exitcode = dst_hash(argv[0]); | ||||
|     } | ||||
|     exit(exitcode); | ||||
| } | ||||
|  | ||||
| int dst_stl_print(int32_t argn, Dst *argv, Dst *ret) { | ||||
|     (void)ret; | ||||
|  | ||||
| @@ -210,6 +219,37 @@ int dst_stl_get(int32_t argn, Dst *argv, Dst *ret) { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| int dst_stl_status(int32_t argn, Dst *argv, Dst *ret) { | ||||
|     const char *status; | ||||
|     if (argn != 1) { | ||||
|         *ret = dst_cstringv("expected 1 argument"); | ||||
|         return 1; | ||||
|     } | ||||
|     if (!dst_checktype(argv[0], DST_FIBER)) { | ||||
|         *ret = dst_cstringv("expected fiber"); | ||||
|         return 1; | ||||
|     } | ||||
|     switch(dst_unwrap_fiber(argv[0])->status) { | ||||
|         case DST_FIBER_PENDING: | ||||
|             status = "pending"; | ||||
|             break; | ||||
|         case DST_FIBER_NEW: | ||||
|             status = "new"; | ||||
|             break; | ||||
|         case DST_FIBER_ALIVE: | ||||
|             status = "alive"; | ||||
|             break; | ||||
|         case DST_FIBER_DEAD: | ||||
|             status = "dead"; | ||||
|             break; | ||||
|         case DST_FIBER_ERROR: | ||||
|             status = "error"; | ||||
|             break; | ||||
|     } | ||||
|     *ret = dst_cstringv(status); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| int dst_stl_put(int32_t argn, Dst *argv, Dst *ret) { | ||||
|     Dst ds, key, value; | ||||
|     if (argn < 3) { | ||||
| @@ -284,6 +324,7 @@ static DstReg stl[] = { | ||||
|     {"tuple", dst_stl_tuple}, | ||||
|     {"struct", dst_stl_struct}, | ||||
|     {"fiber", dst_stl_fiber}, | ||||
|     {"status", dst_stl_status}, | ||||
|     {"buffer", dst_stl_buffer}, | ||||
|     {"gensym", dst_stl_gensym}, | ||||
|     {"asm", dst_stl_asm}, | ||||
| @@ -325,7 +366,8 @@ static DstReg stl[] = { | ||||
|     {"fopen", dst_stl_fileopen}, | ||||
|     {"fclose", dst_stl_fileclose}, | ||||
|     {"fwrite", dst_stl_filewrite}, | ||||
|     {"fread", dst_stl_fileread} | ||||
|     {"fread", dst_stl_fileread}, | ||||
|     {"exit!", dst_stl_exit} | ||||
| }; | ||||
|  | ||||
| Dst dst_loadstl(int flags) { | ||||
|   | ||||
| @@ -121,7 +121,7 @@ static const uint8_t *real_to_string(double x) { | ||||
|     return dst_string(buf, real_to_string_impl(buf, x)); | ||||
| } | ||||
|  | ||||
| static int32_t integer_to_string_impl(uint8_t *buf, int64_t x) { | ||||
| static int32_t integer_to_string_impl(uint8_t *buf, int32_t x) { | ||||
|     int neg = 0; | ||||
|     uint8_t *hi, *low; | ||||
|     int32_t count = 0; | ||||
| @@ -151,12 +151,12 @@ static int32_t integer_to_string_impl(uint8_t *buf, int64_t x) { | ||||
|     return count; | ||||
| } | ||||
|  | ||||
| static void integer_to_string_b(DstBuffer *buffer, int64_t x) { | ||||
| static void integer_to_string_b(DstBuffer *buffer, int32_t x) { | ||||
|     dst_buffer_extra(buffer, DST_BUFSIZE); | ||||
|     buffer->count += integer_to_string_impl(buffer->data + buffer->count, x); | ||||
| } | ||||
|  | ||||
| static const uint8_t *integer_to_string(int64_t x) { | ||||
| static const uint8_t *integer_to_string(int32_t x) { | ||||
|     uint8_t buf[DST_BUFSIZE]; | ||||
|     return dst_string(buf, integer_to_string_impl(buf, x)); | ||||
| } | ||||
| @@ -641,7 +641,7 @@ const uint8_t *dst_formatc(const char *format, ...) { | ||||
|                         real_to_string_b(bufp, va_arg(args, double)); | ||||
|                         break; | ||||
|                     case 'd':  | ||||
|                         integer_to_string_b(bufp, va_arg(args, int64_t)); | ||||
|                         integer_to_string_b(bufp, va_arg(args, int32_t)); | ||||
|                         break; | ||||
|                     case 'S': | ||||
|                     { | ||||
| @@ -653,7 +653,7 @@ const uint8_t *dst_formatc(const char *format, ...) { | ||||
|                         dst_buffer_push_cstring(bufp, va_arg(args, const char *)); | ||||
|                         break; | ||||
|                     case 'c': | ||||
|                         dst_buffer_push_u8(bufp, va_arg(args, int64_t)); | ||||
|                         dst_buffer_push_u8(bufp, va_arg(args, long)); | ||||
|                         break; | ||||
|                     case 'v': | ||||
|                     { | ||||
|   | ||||
| @@ -123,7 +123,8 @@ static double convert( | ||||
|         : ldexp(mantissa, exponent2); | ||||
| } | ||||
|  | ||||
| /* Result of scanning a number source */ | ||||
| /* Result of scanning a number source string. Will be further processed | ||||
|  * depending on the desired resultant type. */ | ||||
| struct DstScanRes { | ||||
|     uint64_t mant; | ||||
|     int32_t ex; | ||||
|   | ||||
| @@ -67,9 +67,13 @@ int32_t dst_hash(Dst x) { | ||||
|     int32_t hash = 0; | ||||
|     switch (dst_type(x)) { | ||||
|     case DST_NIL: | ||||
|         hash = 0; | ||||
|         break; | ||||
|     case DST_FALSE: | ||||
|         hash = 1; | ||||
|         break; | ||||
|     case DST_TRUE: | ||||
|         hash = dst_type(x); | ||||
|         hash = 2; | ||||
|         break; | ||||
|     case DST_STRING: | ||||
|     case DST_SYMBOL: | ||||
| @@ -81,6 +85,8 @@ int32_t dst_hash(Dst x) { | ||||
|     case DST_STRUCT: | ||||
|         hash = dst_struct_hash(dst_unwrap_struct(x)); | ||||
|         break; | ||||
|     case DST_INTEGER: | ||||
|         hash = dst_unwrap_integer(x); | ||||
|     default: | ||||
|         if (sizeof(double) == sizeof(void *)) { | ||||
|             /* Assuming 8 byte pointer */ | ||||
|   | ||||
							
								
								
									
										28
									
								
								core/vm.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								core/vm.c
									
									
									
									
									
								
							| @@ -532,6 +532,7 @@ static int dst_continue(Dst *returnreg) { | ||||
|  | ||||
|         case DOP_TRANSFER: | ||||
|         { | ||||
|             int status; | ||||
|             DstFiber *nextfiber; | ||||
|             DstStackFrame *frame = dst_stack_frame(stack); | ||||
|             Dst temp = stack[oparg(2, 0xFF)]; | ||||
| @@ -547,14 +548,31 @@ static int dst_continue(Dst *returnreg) { | ||||
|                 *returnreg = retreg; | ||||
|                 return 0; | ||||
|             } | ||||
|             vm_assert(nextfiber->status == DST_FIBER_PENDING, "can only transfer to pending fiber"); | ||||
|             status = nextfiber->status; | ||||
|             vm_assert(status == DST_FIBER_PENDING || | ||||
|                     status == DST_FIBER_NEW, "can only transfer to new or pending fiber"); | ||||
|             frame->pc = pc; | ||||
|             dst_vm_fiber->status = DST_FIBER_PENDING; | ||||
|             dst_vm_fiber = nextfiber; | ||||
|             vm_init_fiber_state(); | ||||
|             stack[oparg(1, 0xFF)] = retreg; | ||||
|             pc++; | ||||
|             vm_next(); | ||||
|             if (status == DST_FIBER_PENDING) { | ||||
|                 /* The next fiber is currently on a transfer instruction. */ | ||||
|                 stack[oparg(1, 0xFF)] = retreg; | ||||
|                 pc++; | ||||
|             } else { | ||||
|                 /* The next fiber is new and is on the first instruction */ | ||||
|                 if ((func->def->flags & DST_FUNCDEF_FLAG_VARARG) && | ||||
|                         !func->def->arity) { | ||||
|                     /* Fully var arg function */ | ||||
|                     Dst *tup = dst_tuple_begin(1); | ||||
|                     tup[0] = retreg; | ||||
|                     stack[0] = dst_wrap_tuple(dst_tuple_end(tup)); | ||||
|                 } else if (func->def->arity) { | ||||
|                     /* Non zero arity function */ | ||||
|                     stack[0] = retreg; | ||||
|                 } | ||||
|             } | ||||
|             vm_checkgc_next(); | ||||
|         } | ||||
|  | ||||
|         case DOP_PUT: | ||||
| @@ -569,7 +587,7 @@ static int dst_continue(Dst *returnreg) { | ||||
|                 stack[oparg(2, 0xFF)], | ||||
|                 oparg(3, 0xFF)); | ||||
|         ++pc; | ||||
|         vm_next(); | ||||
|         vm_checkgc_next(); | ||||
|  | ||||
|         case DOP_GET: | ||||
|         stack[oparg(1, 0xFF)] = dst_get( | ||||
|   | ||||
| @@ -112,6 +112,13 @@ | ||||
|  | ||||
| # Fiber tests | ||||
|  | ||||
| (def error (asm '{ | ||||
|   arity 1 | ||||
|   bytecode [ | ||||
|     (error 0) | ||||
|   ] | ||||
| })) | ||||
|  | ||||
| (def afiber (fiber (fn [x] | ||||
| 	(error (string "hello, " x))))) | ||||
|  | ||||
| @@ -124,10 +131,10 @@ | ||||
|  | ||||
| (def t (fiber (fn [] (transfer nil 1) (transfer nil 2) 3))) | ||||
|  | ||||
| (assert (= 1 (transfer t)) "initial transfer to new thread") | ||||
| (assert (= 2 (transfer t)) "second transfer to thread") | ||||
| (assert (= 3 (transfer t)) "return from thread") | ||||
| (assert (= (status t) "dead") "finished thread is dead") | ||||
| (assert (= 1 (transfer t)) "initial transfer to new fiber") | ||||
| (assert (= 2 (transfer t)) "second transfer to fiber") | ||||
| (assert (= 3 (transfer t)) "return from fiber") | ||||
| (assert (= (status t) "dead") "finished fiber is dead") | ||||
|  | ||||
| # Var arg tests | ||||
|  | ||||
| @@ -139,13 +146,6 @@ | ||||
|   ]  | ||||
| })) | ||||
|  | ||||
| (def error (asm '{ | ||||
|   arity 1 | ||||
|   bytecode [ | ||||
|     (error 0) | ||||
|   ] | ||||
| })) | ||||
|  | ||||
| (def vargf (fn [more] (apply + more))) | ||||
|  | ||||
| (assert (= 0 (vargf [])) "var arg no arguments") | ||||
| @@ -169,4 +169,4 @@ | ||||
| # report | ||||
|  | ||||
| (print "\n" num-tests-passed " of " num-tests-run " tests passed\n") | ||||
| (if (not (= num-tests-passed num-tests-run)) (exit! 1)) | ||||
| (if (not= num-tests-passed num-tests-run) (exit! 1)) | ||||
|   | ||||
| @@ -319,7 +319,8 @@ struct DstFiber { | ||||
|     int32_t stacktop; /* Top of stack. Where values are pushed and popped from. */ | ||||
|     int32_t capacity; | ||||
|     enum { | ||||
|         DST_FIBER_PENDING = 0, | ||||
|         DST_FIBER_PENDING, | ||||
|         DST_FIBER_NEW, | ||||
|         DST_FIBER_ALIVE, | ||||
|         DST_FIBER_DEAD, | ||||
|         DST_FIBER_ERROR | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bakpakin
					bakpakin