diff --git a/src/core/inttypes.c b/src/core/inttypes.c index 14956b02..fad40bf8 100644 --- a/src/core/inttypes.c +++ b/src/core/inttypes.c @@ -256,7 +256,7 @@ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \ #define DIVMETHODINVERT_SIGNED(T, type, name, oper) \ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \ - janet_arity(argc, 2, -1); \ + janet_fixarity(argc, 2); \ T *box = janet_abstract(&it_##type##_type, sizeof(T)); \ *box = janet_unwrap_##type(argv[1]); \ T value = janet_unwrap_##type(argv[0]); \ diff --git a/src/core/io.c b/src/core/io.c index edaefef6..01948ed4 100644 --- a/src/core/io.c +++ b/src/core/io.c @@ -157,36 +157,6 @@ static Janet cfun_io_fopen(int32_t argc, Janet *argv) { return f ? makef(f, flags) : janet_wrap_nil(); } -static Janet cfun_io_fdopen(int32_t argc, Janet *argv) { - janet_arity(argc, 1, 2); - const int fd = janet_getinteger(argv, 0); - const uint8_t *fmode; - int flags; - if (argc == 2) { - fmode = janet_getkeyword(argv, 1); - flags = checkflags(fmode); - } else { - fmode = (const uint8_t *)"r"; - flags = JANET_FILE_READ; - } -#ifdef JANET_WINDOWS -#define fdopen _fdopen -#endif - FILE *f = fdopen(fd, (const char *)fmode); - return f ? makef(f, flags) : janet_wrap_nil(); -} - -static Janet cfun_io_fileno(int32_t argc, Janet *argv) { - janet_fixarity(argc, 1); - IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype); - if (iof->flags & JANET_FILE_CLOSED) - janet_panic("file is closed"); -#ifdef JANET_WINDOWS -#define fileno _fileno -#endif - return janet_wrap_integer(fileno(iof->file)); -} - /* Read up to n bytes into buffer. */ static void read_chunk(IOFile *iof, JanetBuffer *buffer, int32_t nBytesMax) { if (!(iof->flags & (JANET_FILE_READ | JANET_FILE_UPDATE))) @@ -338,7 +308,6 @@ static Janet cfun_io_fseek(int32_t argc, Janet *argv) { static JanetMethod io_file_methods[] = { {"close", cfun_io_fclose}, - {"fileno", cfun_io_fileno}, {"flush", cfun_io_fflush}, {"read", cfun_io_fread}, {"seek", cfun_io_fseek}, @@ -592,26 +561,6 @@ static const JanetReg io_cfuns[] = { "\tb - open the file in binary mode (rather than text mode)\n" "\t+ - append to the file instead of overwriting it") }, - { - "file/fdopen", cfun_io_fdopen, - JDOC("(file/fdopen fd &opt mode)\n\n" - "Create a file from an fd. fd is a platform specific file descriptor, and " - "mode is a set of flags indicating the mode to open the file in. " - "mode is a keyword where each character represents a flag. If the file " - "cannot be opened, returns nil, otherwise returns the new file handle. " - "Mode flags:\n\n" - "\tr - allow reading from the file\n" - "\tw - allow writing to the file\n" - "\ta - append to the file\n" - "\tb - open the file in binary mode (rather than text mode)\n" - "\t+ - append to the file instead of overwriting it") - }, - { - "file/fileno", cfun_io_fileno, - JDOC("(file/fileno f)\n\n" - "Return the underlying file descriptor for the file as a number." - "The meaning of this number is platform specific.") - }, { "file/close", cfun_io_fclose, JDOC("(file/close f)\n\n" diff --git a/src/core/vm.c b/src/core/vm.c index c13aba23..e82b8eeb 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -195,49 +195,64 @@ JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf = NULL; } /* Trace a function call */ -static void vm_do_trace(JanetFunction *func) { - Janet *stack = janet_vm_fiber->data + janet_vm_fiber->stackstart; - int32_t start = janet_vm_fiber->stackstart; - int32_t end = janet_vm_fiber->stacktop; - int32_t argc = end - start; - if (func->def->name) { +static void vm_do_trace(JanetFunction *func, int32_t argc, const Janet *argv) { + if (func->def->name){ janet_printf("trace (%S", func->def->name); } else { janet_printf("trace (%p", janet_wrap_function(func)); } for (int32_t i = 0; i < argc; i++) { - janet_printf(" %p", stack[i]); + janet_printf(" %p", argv[i]); } - printf(")\n"); + janet_printf(")\n"); } -/* Call a non function type */ -static Janet call_nonfn(JanetFiber *fiber, Janet callee) { - int32_t argn = fiber->stacktop - fiber->stackstart; - Janet ds, key; - JanetType t = janet_type(callee); - if (t == JANET_ABSTRACT) { - JanetAbstract abst = janet_unwrap_abstract(callee); - const JanetAbstractType *at = janet_abstract_type(abst); - if (NULL != at->call) { - fiber->stacktop = fiber->stackstart; - return at->call(abst, argn, fiber->data + fiber->stackstart); +/* Invoke a method once we have looked it up */ +static Janet janet_method_invoke(Janet method, int32_t argc, Janet *argv) { + switch (janet_type(method)) { + case JANET_CFUNCTION: + return (janet_unwrap_cfunction(method))(argc, argv); + case JANET_FUNCTION: { + JanetFunction *fun = janet_unwrap_function(method); + return janet_call(fun, argc, argv); + } + case JANET_ABSTRACT: { + JanetAbstract abst = janet_unwrap_abstract(method); + const JanetAbstractType *at = janet_abstract_type(abst); + if (NULL != at->call) { + return at->call(abst, argc, argv); + } + } + /* fallthrough */ + case JANET_STRING: + case JANET_BUFFER: + case JANET_TABLE: + case JANET_STRUCT: + case JANET_ARRAY: + case JANET_TUPLE: { + if (argc != 1) { + janet_panicf("%v called with %d arguments, possibly expected 1", method, argc); + } + return janet_in(method, argv[0]); + } + default: { + if (argc != 1) { + janet_panicf("%v called with %d arguments, possibly expected 1", method, argc); + } + return janet_in(argv[0], method); } } - if (argn != 1) janet_panicf("%v called with %d arguments, possibly expected 1", callee, argn); - if ((1 << t) & (JANET_TFLAG_INDEXED | JANET_TFLAG_DICTIONARY | - JANET_TFLAG_STRING | JANET_TFLAG_BUFFER | JANET_TFLAG_ABSTRACT)) { - ds = callee; - key = fiber->data[fiber->stackstart]; - } else { - ds = fiber->data[fiber->stackstart]; - key = callee; - } - fiber->stacktop = fiber->stackstart; - return janet_in(ds, key); } -/* Get a callable from a keyword method name and check ensure that it is valid. */ +/* Call a non function type from a JOP_CALL or JOP_TAILCALL instruction. + * Assumes that the arguments are on the fiber stack. */ +static Janet call_nonfn(JanetFiber *fiber, Janet callee) { + int32_t argc = fiber->stacktop - fiber->stackstart; + fiber->stacktop = fiber->stackstart; + return janet_method_invoke(callee, argc, fiber->data + fiber->stacktop); +} + +/* Get a callable from a keyword method name and ensure that it is valid. */ static Janet resolve_method(Janet name, JanetFiber *fiber) { int32_t argc = fiber->stacktop - fiber->stackstart; if (argc < 1) janet_panicf("method call (%v) takes at least 1 argument, got 0", name); @@ -250,36 +265,7 @@ static Janet resolve_method(Janet name, JanetFiber *fiber) { /* Lookup method on value x */ static Janet janet_method_lookup(Janet x, const char *name) { Janet kname = janet_ckeywordv(name); - switch (janet_type(x)) { - default: - return janet_wrap_nil(); - case JANET_ABSTRACT: { - Janet method; - void *abst = janet_unwrap_abstract(x); - JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(abst); - if (!type->get || !(type->get)(abst, kname, &method)) { - return janet_wrap_nil(); - } else { - return method; - } - } - case JANET_TABLE: - return janet_table_get(janet_unwrap_table(x), kname); - case JANET_STRUCT: - return janet_struct_get(janet_unwrap_struct(x), kname); - } -} - -/* Invoke a method once we have looked it up */ -static Janet janet_method_invoke(Janet method, int32_t argc, Janet *argv) { - if (janet_checktype(method, JANET_CFUNCTION)) { - return (janet_unwrap_cfunction(method))(argc, argv); - } else if (janet_checktype(method, JANET_FUNCTION)) { - JanetFunction *fun = janet_unwrap_function(method); - return janet_call(fun, argc, argv); - } else { - janet_panicf("method is not callable: %v", method); - } + return janet_get(x, kname); } /* Call a method first on the righthand side, and then on the left hand side with a prefix */ @@ -901,7 +887,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { } if (janet_checktype(callee, JANET_FUNCTION)) { func = janet_unwrap_function(callee); - if (func->gc.flags & JANET_FUNCFLAG_TRACE) vm_do_trace(func); + if (func->gc.flags & JANET_FUNCFLAG_TRACE) { + vm_do_trace(func, fiber->stacktop - fiber->stackstart, stack); + } janet_stack_frame(stack)->pc = pc; if (janet_fiber_funcframe(fiber, func)) { int32_t n = fiber->stacktop - fiber->stackstart; @@ -938,7 +926,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { } if (janet_checktype(callee, JANET_FUNCTION)) { func = janet_unwrap_function(callee); - if (func->gc.flags & JANET_FUNCFLAG_TRACE) vm_do_trace(func); + if (func->gc.flags & JANET_FUNCFLAG_TRACE) { + vm_do_trace(func, fiber->stacktop - fiber->stackstart, stack); + } if (janet_fiber_funcframe_tail(fiber, func)) { janet_stack_frame(fiber->data + fiber->frame)->pc = pc; int32_t n = fiber->stacktop - fiber->stackstart; @@ -1186,6 +1176,11 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) { if (janet_vm_stackn >= JANET_RECURSION_GUARD) janet_panic("C stack recursed too deeply"); + /* Tracing */ + if (fun->gc.flags & JANET_FUNCFLAG_TRACE) { + vm_do_trace(fun, argc, argv); + } + /* Push frame */ janet_fiber_pushn(janet_vm_fiber, argv, argc); if (janet_fiber_funcframe(janet_vm_fiber, fun)) {