1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-24 17:27:18 +00:00

Make some unit tests pass. Fix transfer to new fiber.

This commit is contained in:
bakpakin 2018-01-12 16:25:24 -05:00
parent f8174f192c
commit 59bed71a2c
11 changed files with 100 additions and 29 deletions

View File

@ -72,7 +72,7 @@ valgrind: $(DST_TARGET)
@ valgrind --leak-check=full -v ./$(DST_TARGET) @ valgrind --leak-check=full -v ./$(DST_TARGET)
test: $(DST_TARGET) test: $(DST_TARGET)
@ ./$(DST_TARGET) dsttest/suite0.dst @ ./$(DST_TARGET) --gcinterval=0 dsttest/suite0.dst
valtest: $(DST_TARGET) valtest: $(DST_TARGET)
valgrind --leak-check=full -v ./$(DST_TARGET) dsttests/basic.dst valgrind --leak-check=full -v ./$(DST_TARGET) dsttests/basic.dst

View File

@ -176,7 +176,7 @@ static void runfile(const uint8_t *src, int32_t len) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
int status = -1; int status = 0;
int i; int i;
int fileRead = 0; int fileRead = 0;
uint32_t gcinterval = 0x10000; uint32_t gcinterval = 0x10000;

View File

@ -491,6 +491,9 @@ DstSlot dstc_fn(DstFopts opts, int32_t argn, const Dst *argv) {
if (varargs) def->flags |= DST_FUNCDEF_FLAG_VARARG; if (varargs) def->flags |= DST_FUNCDEF_FLAG_VARARG;
defindex = dstc_addfuncdef(c, def); defindex = dstc_addfuncdef(c, def);
/* Ensure enough slots for vararg function. */
if (arity + varargs > def->slotcount) def->slotcount = arity + varargs;
/* Instantiate closure */ /* Instantiate closure */
ret.flags = 0; ret.flags = 0;
ret.envindex = 0; ret.envindex = 0;

View File

@ -45,7 +45,7 @@ DstFiber *dst_fiber_reset(DstFiber *fiber) {
fiber->frame = 0; fiber->frame = 0;
fiber->stackstart = DST_FRAME_SIZE; fiber->stackstart = DST_FRAME_SIZE;
fiber->stacktop = DST_FRAME_SIZE; fiber->stacktop = DST_FRAME_SIZE;
fiber->status = DST_FIBER_PENDING; fiber->status = DST_FIBER_NEW;
fiber->parent = NULL; fiber->parent = NULL;
return fiber; return fiber;
} }

View File

@ -23,6 +23,15 @@
#include <dst/dst.h> #include <dst/dst.h>
#include <dst/dststl.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) { int dst_stl_print(int32_t argn, Dst *argv, Dst *ret) {
(void)ret; (void)ret;
@ -210,6 +219,37 @@ int dst_stl_get(int32_t argn, Dst *argv, Dst *ret) {
return 0; 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) { int dst_stl_put(int32_t argn, Dst *argv, Dst *ret) {
Dst ds, key, value; Dst ds, key, value;
if (argn < 3) { if (argn < 3) {
@ -284,6 +324,7 @@ static DstReg stl[] = {
{"tuple", dst_stl_tuple}, {"tuple", dst_stl_tuple},
{"struct", dst_stl_struct}, {"struct", dst_stl_struct},
{"fiber", dst_stl_fiber}, {"fiber", dst_stl_fiber},
{"status", dst_stl_status},
{"buffer", dst_stl_buffer}, {"buffer", dst_stl_buffer},
{"gensym", dst_stl_gensym}, {"gensym", dst_stl_gensym},
{"asm", dst_stl_asm}, {"asm", dst_stl_asm},
@ -325,7 +366,8 @@ static DstReg stl[] = {
{"fopen", dst_stl_fileopen}, {"fopen", dst_stl_fileopen},
{"fclose", dst_stl_fileclose}, {"fclose", dst_stl_fileclose},
{"fwrite", dst_stl_filewrite}, {"fwrite", dst_stl_filewrite},
{"fread", dst_stl_fileread} {"fread", dst_stl_fileread},
{"exit!", dst_stl_exit}
}; };
Dst dst_loadstl(int flags) { Dst dst_loadstl(int flags) {

View File

@ -121,7 +121,7 @@ static const uint8_t *real_to_string(double x) {
return dst_string(buf, real_to_string_impl(buf, 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; int neg = 0;
uint8_t *hi, *low; uint8_t *hi, *low;
int32_t count = 0; int32_t count = 0;
@ -151,12 +151,12 @@ static int32_t integer_to_string_impl(uint8_t *buf, int64_t x) {
return count; 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); dst_buffer_extra(buffer, DST_BUFSIZE);
buffer->count += integer_to_string_impl(buffer->data + buffer->count, x); 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]; uint8_t buf[DST_BUFSIZE];
return dst_string(buf, integer_to_string_impl(buf, x)); 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)); real_to_string_b(bufp, va_arg(args, double));
break; break;
case 'd': case 'd':
integer_to_string_b(bufp, va_arg(args, int64_t)); integer_to_string_b(bufp, va_arg(args, int32_t));
break; break;
case 'S': case 'S':
{ {
@ -653,7 +653,7 @@ const uint8_t *dst_formatc(const char *format, ...) {
dst_buffer_push_cstring(bufp, va_arg(args, const char *)); dst_buffer_push_cstring(bufp, va_arg(args, const char *));
break; break;
case 'c': case 'c':
dst_buffer_push_u8(bufp, va_arg(args, int64_t)); dst_buffer_push_u8(bufp, va_arg(args, long));
break; break;
case 'v': case 'v':
{ {

View File

@ -123,7 +123,8 @@ static double convert(
: ldexp(mantissa, exponent2); : 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 { struct DstScanRes {
uint64_t mant; uint64_t mant;
int32_t ex; int32_t ex;

View File

@ -67,9 +67,13 @@ int32_t dst_hash(Dst x) {
int32_t hash = 0; int32_t hash = 0;
switch (dst_type(x)) { switch (dst_type(x)) {
case DST_NIL: case DST_NIL:
hash = 0;
break;
case DST_FALSE: case DST_FALSE:
hash = 1;
break;
case DST_TRUE: case DST_TRUE:
hash = dst_type(x); hash = 2;
break; break;
case DST_STRING: case DST_STRING:
case DST_SYMBOL: case DST_SYMBOL:
@ -81,6 +85,8 @@ int32_t dst_hash(Dst x) {
case DST_STRUCT: case DST_STRUCT:
hash = dst_struct_hash(dst_unwrap_struct(x)); hash = dst_struct_hash(dst_unwrap_struct(x));
break; break;
case DST_INTEGER:
hash = dst_unwrap_integer(x);
default: default:
if (sizeof(double) == sizeof(void *)) { if (sizeof(double) == sizeof(void *)) {
/* Assuming 8 byte pointer */ /* Assuming 8 byte pointer */

View File

@ -532,6 +532,7 @@ static int dst_continue(Dst *returnreg) {
case DOP_TRANSFER: case DOP_TRANSFER:
{ {
int status;
DstFiber *nextfiber; DstFiber *nextfiber;
DstStackFrame *frame = dst_stack_frame(stack); DstStackFrame *frame = dst_stack_frame(stack);
Dst temp = stack[oparg(2, 0xFF)]; Dst temp = stack[oparg(2, 0xFF)];
@ -547,14 +548,31 @@ static int dst_continue(Dst *returnreg) {
*returnreg = retreg; *returnreg = retreg;
return 0; 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; frame->pc = pc;
dst_vm_fiber->status = DST_FIBER_PENDING; dst_vm_fiber->status = DST_FIBER_PENDING;
dst_vm_fiber = nextfiber; dst_vm_fiber = nextfiber;
vm_init_fiber_state(); vm_init_fiber_state();
if (status == DST_FIBER_PENDING) {
/* The next fiber is currently on a transfer instruction. */
stack[oparg(1, 0xFF)] = retreg; stack[oparg(1, 0xFF)] = retreg;
pc++; pc++;
vm_next(); } 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: case DOP_PUT:
@ -569,7 +587,7 @@ static int dst_continue(Dst *returnreg) {
stack[oparg(2, 0xFF)], stack[oparg(2, 0xFF)],
oparg(3, 0xFF)); oparg(3, 0xFF));
++pc; ++pc;
vm_next(); vm_checkgc_next();
case DOP_GET: case DOP_GET:
stack[oparg(1, 0xFF)] = dst_get( stack[oparg(1, 0xFF)] = dst_get(

View File

@ -112,6 +112,13 @@
# Fiber tests # Fiber tests
(def error (asm '{
arity 1
bytecode [
(error 0)
]
}))
(def afiber (fiber (fn [x] (def afiber (fiber (fn [x]
(error (string "hello, " x))))) (error (string "hello, " x)))))
@ -124,10 +131,10 @@
(def t (fiber (fn [] (transfer nil 1) (transfer nil 2) 3))) (def t (fiber (fn [] (transfer nil 1) (transfer nil 2) 3)))
(assert (= 1 (transfer t)) "initial transfer to new thread") (assert (= 1 (transfer t)) "initial transfer to new fiber")
(assert (= 2 (transfer t)) "second transfer to thread") (assert (= 2 (transfer t)) "second transfer to fiber")
(assert (= 3 (transfer t)) "return from thread") (assert (= 3 (transfer t)) "return from fiber")
(assert (= (status t) "dead") "finished thread is dead") (assert (= (status t) "dead") "finished fiber is dead")
# Var arg tests # Var arg tests
@ -139,13 +146,6 @@
] ]
})) }))
(def error (asm '{
arity 1
bytecode [
(error 0)
]
}))
(def vargf (fn [more] (apply + more))) (def vargf (fn [more] (apply + more)))
(assert (= 0 (vargf [])) "var arg no arguments") (assert (= 0 (vargf [])) "var arg no arguments")
@ -169,4 +169,4 @@
# report # report
(print "\n" num-tests-passed " of " num-tests-run " tests passed\n") (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))

View File

@ -319,7 +319,8 @@ struct DstFiber {
int32_t stacktop; /* Top of stack. Where values are pushed and popped from. */ int32_t stacktop; /* Top of stack. Where values are pushed and popped from. */
int32_t capacity; int32_t capacity;
enum { enum {
DST_FIBER_PENDING = 0, DST_FIBER_PENDING,
DST_FIBER_NEW,
DST_FIBER_ALIVE, DST_FIBER_ALIVE,
DST_FIBER_DEAD, DST_FIBER_DEAD,
DST_FIBER_ERROR DST_FIBER_ERROR