1
0
mirror of https://github.com/janet-lang/janet synced 2025-11-07 02:53:02 +00:00

Compare commits

..

16 Commits

Author SHA1 Message Date
Calvin Rose
cc5beda0d2 Update patch release. 2023-10-15 14:33:43 -05:00
Calvin Rose
a363fd926d Update CHANGELOG.md 2023-10-15 14:32:56 -05:00
Calvin Rose
21ebede529 Move posix-fork inside correct if-def
Don't compile if processes are disabled.
2023-10-15 11:03:26 -05:00
Calvin Rose
15d67e9191 Merge pull request #1310 from Andriamanitra/patch-forward-word
Change Alt-f in the REPL move to next end of word instead of beginning
2023-10-14 18:36:05 -07:00
Calvin Rose
b5996f5f02 Update for 1.32.0 2023-10-14 19:48:20 -05:00
Andriamanitra
83204dc293 Change Alt-f in the REPL move to next end of word instead of beginning 2023-10-14 14:21:16 +03:00
Calvin Rose
e3f4142d2a Update result value from janet_do* functions. 2023-10-12 05:26:23 -05:00
Calvin Rose
f18ad36b1b Rework #1306 - better default for pretty printing numbers.
Not perfect for serialization, but a representation that
plays well with both safe integers (z where abs(z) < 2^54) and
non-integer floats.
2023-10-11 00:59:57 -05:00
Calvin Rose
cb25a2ecd6 Avoid using execvpe function. 2023-10-08 21:33:15 -05:00
Calvin Rose
741a5036e8 Add %D and %I for 64 bit formatting.
Instead of breaking old code with changing %i and %d.
2023-10-08 21:23:03 -05:00
Calvin Rose
549ee95f3d Add os/posix-exec (along os/posix-fork)
Useful for old-style unix daemons, start up scripts, and so on.
Easy to add on top of os/execute.

May want to consider allowing the same IO redirection as os/execute
and os/spawn.

May also want to put both fork and exec behind a config switch since I
suppose some systems may not support them, although I don't know of any
concrete examples.
2023-10-08 21:03:08 -05:00
Calvin Rose
6ae81058aa Be more consistent with va_arg types. 2023-10-08 19:09:35 -05:00
Calvin Rose
267c603824 Don't use full parallelism to avoid oom 2023-10-08 18:37:31 -05:00
Calvin Rose
a8f583a372 CMD isn't bash 2023-10-08 18:34:04 -05:00
Calvin Rose
2b5d90f73a Disable amalgamation w/ mingw in CI due to memory limitations 2023-10-08 18:28:07 -05:00
Calvin Rose
4139e426fe Refine interface for janet's new event loop.
Infer the current root fiber and force user to
allocate state for async events.
2023-10-08 18:25:46 -05:00
17 changed files with 218 additions and 139 deletions

View File

@@ -56,7 +56,7 @@ jobs:
gcc gcc
- name: Build the project - name: Build the project
shell: cmd shell: cmd
run: make -j CC=gcc run: make -j4 CC=gcc JANET_NO_AMALG=1
test-mingw-linux: test-mingw-linux:
name: Build and test with Mingw on Linux + Wine name: Build and test with Mingw on Linux + Wine

5
.gitignore vendored
View File

@@ -34,8 +34,11 @@ local
# Common test files I use. # Common test files I use.
temp.janet temp.janet
temp*.janet temp.c
temp*janet
temp*.c
scratch.janet scratch.janet
scratch.c
# Emscripten # Emscripten
*.bc *.bc

View File

@@ -1,7 +1,10 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## Unreleased - ??? ## 1.32.1 - 2023-10-15
- Fix return value from C function `janet_dobytes` when called on Janet functions that yield to event loop.
- Change C API for event loop interaction - get rid of JanetListener and instead use `janet_async_start` and `janet_async_end`.
- Rework event loop to make fewer system calls on kqueue and epoll.
- Expose atomic refcount abstraction in janet.h - Expose atomic refcount abstraction in janet.h
- Add `array/weak` for weak references in arrays - Add `array/weak` for weak references in arrays
- Add support for weak tables via `table/weak`, `table/weak-keys`, and `table/weak-values`. - Add support for weak tables via `table/weak`, `table/weak-keys`, and `table/weak-values`.

View File

@@ -196,9 +196,9 @@ build/%.bin.o: src/%.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS) Makefile
######################## ########################
ifeq ($(UNAME), Darwin) ifeq ($(UNAME), Darwin)
SONAME=libjanet.1.31.dylib SONAME=libjanet.1.32.dylib
else else
SONAME=libjanet.so.1.31 SONAME=libjanet.so.1.32
endif endif
build/c/shell.c: src/mainclient/shell.c build/c/shell.c: src/mainclient/shell.c

View File

@@ -0,0 +1,5 @@
# Switch to python
(print "running in Janet")
(os/posix-exec ["python"] :p)
(print "will not print")

View File

@@ -20,7 +20,7 @@
project('janet', 'c', project('janet', 'c',
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'], default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
version : '1.31.0') version : '1.32.1')
# Global settings # Global settings
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet') janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')

View File

@@ -4,10 +4,10 @@
#define JANETCONF_H #define JANETCONF_H
#define JANET_VERSION_MAJOR 1 #define JANET_VERSION_MAJOR 1
#define JANET_VERSION_MINOR 31 #define JANET_VERSION_MINOR 32
#define JANET_VERSION_PATCH 0 #define JANET_VERSION_PATCH 1
#define JANET_VERSION_EXTRA "" #define JANET_VERSION_EXTRA ""
#define JANET_VERSION "1.31.0" #define JANET_VERSION "1.32.1"
/* #define JANET_BUILD "local" */ /* #define JANET_BUILD "local" */

View File

@@ -338,7 +338,7 @@ int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const c
int32_t not_raw = raw; int32_t not_raw = raw;
if (not_raw < 0) not_raw += length + 1; if (not_raw < 0) not_raw += length + 1;
if (not_raw < 0 || not_raw > length) if (not_raw < 0 || not_raw > length)
janet_panicf("%s index %d out of range [%d,%d]", which, raw, -length - 1, length); janet_panicf("%s index %d out of range [%d,%d]", which, (int64_t) raw, -(int64_t)length - 1, (int64_t) length);
return not_raw; return not_raw;
} }
@@ -361,7 +361,7 @@ int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const ch
int32_t not_raw = raw; int32_t not_raw = raw;
if (not_raw < 0) not_raw += length; if (not_raw < 0) not_raw += length;
if (not_raw < 0 || not_raw > length) if (not_raw < 0 || not_raw > length)
janet_panicf("%s index %d out of range [%d,%d)", which, raw, -length, length); janet_panicf("%s index %d out of range [%d,%d)", which, (int64_t)raw, -(int64_t)length, (int64_t)length);
return not_raw; return not_raw;
} }

View File

@@ -255,6 +255,7 @@ static void add_timeout(JanetTimeout to) {
void janet_async_end(JanetFiber *fiber) { void janet_async_end(JanetFiber *fiber) {
if (fiber->ev_callback) { if (fiber->ev_callback) {
fiber->ev_callback(fiber, JANET_ASYNC_EVENT_DEINIT);
janet_gcunroot(janet_wrap_abstract(fiber->ev_stream)); janet_gcunroot(janet_wrap_abstract(fiber->ev_stream));
fiber->ev_callback = NULL; fiber->ev_callback = NULL;
if (fiber->ev_state) { if (fiber->ev_state) {
@@ -267,7 +268,16 @@ void janet_async_end(JanetFiber *fiber) {
} }
} }
void *janet_async_start(JanetFiber *fiber, JanetStream *stream, JanetAsyncMode mode, JanetEVCallback callback, size_t data_size) { void janet_async_in_flight(JanetFiber *fiber) {
#ifdef JANET_WINDOWS
fiber->flags |= JANET_FIBER_EV_FLAG_IN_FLIGHT;
#else
(void) fiber;
#endif
}
void janet_async_start(JanetStream *stream, JanetAsyncMode mode, JanetEVCallback callback, void *state) {
JanetFiber *fiber = janet_vm.root_fiber;
janet_assert(!fiber->ev_callback, "double async on fiber"); janet_assert(!fiber->ev_callback, "double async on fiber");
if (mode & JANET_ASYNC_LISTEN_READ) stream->read_fiber = fiber; if (mode & JANET_ASYNC_LISTEN_READ) stream->read_fiber = fiber;
if (mode & JANET_ASYNC_LISTEN_WRITE) stream->write_fiber = fiber; if (mode & JANET_ASYNC_LISTEN_WRITE) stream->write_fiber = fiber;
@@ -275,14 +285,9 @@ void *janet_async_start(JanetFiber *fiber, JanetStream *stream, JanetAsyncMode m
fiber->ev_stream = stream; fiber->ev_stream = stream;
janet_ev_inc_refcount(); janet_ev_inc_refcount();
janet_gcroot(janet_wrap_abstract(stream)); janet_gcroot(janet_wrap_abstract(stream));
if (data_size) { fiber->ev_state = state;
void *data = janet_malloc(data_size); callback(fiber, JANET_ASYNC_EVENT_INIT);
fiber->ev_state = data; janet_await();
return data;
} else {
fiber->ev_state = NULL;
return NULL;
}
} }
void janet_fiber_did_resume(JanetFiber *fiber) { void janet_fiber_did_resume(JanetFiber *fiber) {
@@ -2199,7 +2204,7 @@ void ev_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
} }
/* fallthrough */ /* fallthrough */
case JANET_ASYNC_EVENT_USER: { case JANET_ASYNC_EVENT_INIT: {
int32_t chunk_size = state->bytes_left > JANET_EV_CHUNKSIZE ? JANET_EV_CHUNKSIZE : state->bytes_left; int32_t chunk_size = state->bytes_left > JANET_EV_CHUNKSIZE ? JANET_EV_CHUNKSIZE : state->bytes_left;
memset(&(state->overlapped), 0, sizeof(OVERLAPPED)); memset(&(state->overlapped), 0, sizeof(OVERLAPPED));
int status; int status;
@@ -2237,7 +2242,7 @@ void ev_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
return; return;
} }
} }
fiber->flags |= JANET_FIBER_EV_FLAG_IN_FLIGHT; janet_async_in_flight(fiber);
} }
break; break;
#else #else
@@ -2253,7 +2258,7 @@ void ev_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
read_more: read_more:
case JANET_ASYNC_EVENT_HUP: case JANET_ASYNC_EVENT_HUP:
case JANET_ASYNC_EVENT_USER: case JANET_ASYNC_EVENT_INIT:
case JANET_ASYNC_EVENT_READ: { case JANET_ASYNC_EVENT_READ: {
JanetBuffer *buffer = state->buf; JanetBuffer *buffer = state->buf;
int32_t bytes_left = state->bytes_left; int32_t bytes_left = state->bytes_left;
@@ -2332,9 +2337,8 @@ void ev_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
} }
} }
static void janet_ev_read_generic(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int is_chunked, JanetReadMode mode, int flags) { static JANET_NO_RETURN void janet_ev_read_generic(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int is_chunked, JanetReadMode mode, int flags) {
JanetFiber *f = janet_vm.root_fiber; StateRead *state = janet_malloc(sizeof(StateRead));
StateRead *state = (StateRead *) janet_async_start(f, stream, JANET_ASYNC_LISTEN_READ, ev_callback_read, sizeof(StateRead));
state->is_chunk = is_chunked; state->is_chunk = is_chunked;
state->buf = buf; state->buf = buf;
state->bytes_left = nbytes; state->bytes_left = nbytes;
@@ -2345,23 +2349,23 @@ static void janet_ev_read_generic(JanetStream *stream, JanetBuffer *buf, int32_t
#else #else
state->flags = flags; state->flags = flags;
#endif #endif
ev_callback_read(f, JANET_ASYNC_EVENT_USER); janet_async_start(stream, JANET_ASYNC_LISTEN_READ, ev_callback_read, state);
} }
void janet_ev_read(JanetStream *stream, JanetBuffer *buf, int32_t nbytes) { JANET_NO_RETURN void janet_ev_read(JanetStream *stream, JanetBuffer *buf, int32_t nbytes) {
janet_ev_read_generic(stream, buf, nbytes, 0, JANET_ASYNC_READMODE_READ, 0); janet_ev_read_generic(stream, buf, nbytes, 0, JANET_ASYNC_READMODE_READ, 0);
} }
void janet_ev_readchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes) { JANET_NO_RETURN void janet_ev_readchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes) {
janet_ev_read_generic(stream, buf, nbytes, 1, JANET_ASYNC_READMODE_READ, 0); janet_ev_read_generic(stream, buf, nbytes, 1, JANET_ASYNC_READMODE_READ, 0);
} }
#ifdef JANET_NET #ifdef JANET_NET
void janet_ev_recv(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags) { JANET_NO_RETURN void janet_ev_recv(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags) {
janet_ev_read_generic(stream, buf, nbytes, 0, JANET_ASYNC_READMODE_RECV, flags); janet_ev_read_generic(stream, buf, nbytes, 0, JANET_ASYNC_READMODE_RECV, flags);
} }
void janet_ev_recvchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags) { JANET_NO_RETURN void janet_ev_recvchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags) {
janet_ev_read_generic(stream, buf, nbytes, 1, JANET_ASYNC_READMODE_RECV, flags); janet_ev_read_generic(stream, buf, nbytes, 1, JANET_ASYNC_READMODE_RECV, flags);
} }
void janet_ev_recvfrom(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags) { JANET_NO_RETURN void janet_ev_recvfrom(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags) {
janet_ev_read_generic(stream, buf, nbytes, 0, JANET_ASYNC_READMODE_RECVFROM, flags); janet_ev_read_generic(stream, buf, nbytes, 0, JANET_ASYNC_READMODE_RECVFROM, flags);
} }
#endif #endif
@@ -2431,7 +2435,7 @@ void ev_callback_write(JanetFiber *fiber, JanetAsyncEvent event) {
return; return;
} }
break; break;
case JANET_ASYNC_EVENT_USER: { case JANET_ASYNC_EVENT_INIT: {
/* Begin write */ /* Begin write */
int32_t len; int32_t len;
const uint8_t *bytes; const uint8_t *bytes;
@@ -2461,7 +2465,7 @@ void ev_callback_write(JanetFiber *fiber, JanetAsyncEvent event) {
status = WSASendTo(sock, &state->wbuf, 1, NULL, state->flags, to, tolen, &state->overlapped, NULL); status = WSASendTo(sock, &state->wbuf, 1, NULL, state->flags, to, tolen, &state->overlapped, NULL);
if (status) { if (status) {
if (WSA_IO_PENDING == WSAGetLastError()) { if (WSA_IO_PENDING == WSAGetLastError()) {
fiber->flags |= JANET_FIBER_EV_FLAG_IN_FLIGHT; janet_async_in_flight(fiber);
} else { } else {
janet_cancel(fiber, janet_ev_lasterr()); janet_cancel(fiber, janet_ev_lasterr());
janet_async_end(fiber); janet_async_end(fiber);
@@ -2486,7 +2490,7 @@ void ev_callback_write(JanetFiber *fiber, JanetAsyncEvent event) {
status = WriteFile(stream->handle, bytes, len, NULL, &state->overlapped); status = WriteFile(stream->handle, bytes, len, NULL, &state->overlapped);
if (!status) { if (!status) {
if (ERROR_IO_PENDING == GetLastError()) { if (ERROR_IO_PENDING == GetLastError()) {
fiber->flags |= JANET_FIBER_EV_FLAG_IN_FLIGHT; janet_async_in_flight(fiber);
} else { } else {
janet_cancel(fiber, janet_ev_lasterr()); janet_cancel(fiber, janet_ev_lasterr());
janet_async_end(fiber); janet_async_end(fiber);
@@ -2505,7 +2509,7 @@ void ev_callback_write(JanetFiber *fiber, JanetAsyncEvent event) {
janet_cancel(fiber, janet_cstringv("stream hup")); janet_cancel(fiber, janet_cstringv("stream hup"));
janet_async_end(fiber); janet_async_end(fiber);
break; break;
case JANET_ASYNC_EVENT_USER: case JANET_ASYNC_EVENT_INIT:
case JANET_ASYNC_EVENT_WRITE: { case JANET_ASYNC_EVENT_WRITE: {
int32_t start, len; int32_t start, len;
const uint8_t *bytes; const uint8_t *bytes;
@@ -2570,10 +2574,8 @@ void ev_callback_write(JanetFiber *fiber, JanetAsyncEvent event) {
} }
} }
static void janet_ev_write_generic(JanetStream *stream, void *buf, void *dest_abst, JanetWriteMode mode, int is_buffer, int flags) { static JANET_NO_RETURN void janet_ev_write_generic(JanetStream *stream, void *buf, void *dest_abst, JanetWriteMode mode, int is_buffer, int flags) {
JanetFiber *f = janet_vm.root_fiber; StateWrite *state = janet_malloc(sizeof(StateWrite));
StateWrite *state = (StateWrite *) janet_async_start(f, stream, JANET_ASYNC_LISTEN_WRITE,
ev_callback_write, sizeof(StateWrite));
state->is_buffer = is_buffer; state->is_buffer = is_buffer;
state->src.buf = buf; state->src.buf = buf;
state->dest_abst = dest_abst; state->dest_abst = dest_abst;
@@ -2584,31 +2586,31 @@ static void janet_ev_write_generic(JanetStream *stream, void *buf, void *dest_ab
state->flags = flags; state->flags = flags;
state->start = 0; state->start = 0;
#endif #endif
ev_callback_write(f, JANET_ASYNC_EVENT_USER); janet_async_start(stream, JANET_ASYNC_LISTEN_WRITE, ev_callback_write, state);
} }
void janet_ev_write_buffer(JanetStream *stream, JanetBuffer *buf) { JANET_NO_RETURN void janet_ev_write_buffer(JanetStream *stream, JanetBuffer *buf) {
janet_ev_write_generic(stream, buf, NULL, JANET_ASYNC_WRITEMODE_WRITE, 1, 0); janet_ev_write_generic(stream, buf, NULL, JANET_ASYNC_WRITEMODE_WRITE, 1, 0);
} }
void janet_ev_write_string(JanetStream *stream, JanetString str) { JANET_NO_RETURN void janet_ev_write_string(JanetStream *stream, JanetString str) {
janet_ev_write_generic(stream, (void *) str, NULL, JANET_ASYNC_WRITEMODE_WRITE, 0, 0); janet_ev_write_generic(stream, (void *) str, NULL, JANET_ASYNC_WRITEMODE_WRITE, 0, 0);
} }
#ifdef JANET_NET #ifdef JANET_NET
void janet_ev_send_buffer(JanetStream *stream, JanetBuffer *buf, int flags) { JANET_NO_RETURN void janet_ev_send_buffer(JanetStream *stream, JanetBuffer *buf, int flags) {
janet_ev_write_generic(stream, buf, NULL, JANET_ASYNC_WRITEMODE_SEND, 1, flags); janet_ev_write_generic(stream, buf, NULL, JANET_ASYNC_WRITEMODE_SEND, 1, flags);
} }
void janet_ev_send_string(JanetStream *stream, JanetString str, int flags) { JANET_NO_RETURN void janet_ev_send_string(JanetStream *stream, JanetString str, int flags) {
janet_ev_write_generic(stream, (void *) str, NULL, JANET_ASYNC_WRITEMODE_SEND, 0, flags); janet_ev_write_generic(stream, (void *) str, NULL, JANET_ASYNC_WRITEMODE_SEND, 0, flags);
} }
void janet_ev_sendto_buffer(JanetStream *stream, JanetBuffer *buf, void *dest, int flags) { JANET_NO_RETURN void janet_ev_sendto_buffer(JanetStream *stream, JanetBuffer *buf, void *dest, int flags) {
janet_ev_write_generic(stream, buf, dest, JANET_ASYNC_WRITEMODE_SENDTO, 1, flags); janet_ev_write_generic(stream, buf, dest, JANET_ASYNC_WRITEMODE_SENDTO, 1, flags);
} }
void janet_ev_sendto_string(JanetStream *stream, JanetString str, void *dest, int flags) { JANET_NO_RETURN void janet_ev_sendto_string(JanetStream *stream, JanetString str, void *dest, int flags) {
janet_ev_write_generic(stream, (void *) str, dest, JANET_ASYNC_WRITEMODE_SENDTO, 0, flags); janet_ev_write_generic(stream, (void *) str, dest, JANET_ASYNC_WRITEMODE_SENDTO, 0, flags);
} }
#endif #endif
@@ -2999,7 +3001,6 @@ JANET_CORE_FN(janet_cfun_stream_read,
if (to != INFINITY) janet_addtimeout(to); if (to != INFINITY) janet_addtimeout(to);
janet_ev_read(stream, buffer, n); janet_ev_read(stream, buffer, n);
} }
janet_await();
} }
JANET_CORE_FN(janet_cfun_stream_chunk, JANET_CORE_FN(janet_cfun_stream_chunk,
@@ -3014,7 +3015,6 @@ JANET_CORE_FN(janet_cfun_stream_chunk,
double to = janet_optnumber(argv, argc, 3, INFINITY); double to = janet_optnumber(argv, argc, 3, INFINITY);
if (to != INFINITY) janet_addtimeout(to); if (to != INFINITY) janet_addtimeout(to);
janet_ev_readchunk(stream, buffer, n); janet_ev_readchunk(stream, buffer, n);
janet_await();
} }
JANET_CORE_FN(janet_cfun_stream_write, JANET_CORE_FN(janet_cfun_stream_write,
@@ -3034,7 +3034,6 @@ JANET_CORE_FN(janet_cfun_stream_write,
if (to != INFINITY) janet_addtimeout(to); if (to != INFINITY) janet_addtimeout(to);
janet_ev_write_string(stream, bytes.bytes); janet_ev_write_string(stream, bytes.bytes);
} }
janet_await();
} }
static int mutexgc(void *p, size_t size) { static int mutexgc(void *p, size_t size) {

View File

@@ -999,13 +999,13 @@ typedef struct {
uint64_t x; uint64_t x;
} sysv64_sseint_return; } sysv64_sseint_return;
typedef sysv64_int_return janet_sysv64_variant_1(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f, typedef sysv64_int_return janet_sysv64_variant_1(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f,
double r1, double r2, double r3, double r4, double r5, double r6, double r7, double r8); double r1, double r2, double r3, double r4, double r5, double r6, double r7, double r8);
typedef sysv64_sse_return janet_sysv64_variant_2(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f, typedef sysv64_sse_return janet_sysv64_variant_2(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f,
double r1, double r2, double r3, double r4, double r5, double r6, double r7, double r8); double r1, double r2, double r3, double r4, double r5, double r6, double r7, double r8);
typedef sysv64_intsse_return janet_sysv64_variant_3(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f, typedef sysv64_intsse_return janet_sysv64_variant_3(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f,
double r1, double r2, double r3, double r4, double r5, double r6, double r7, double r8); double r1, double r2, double r3, double r4, double r5, double r6, double r7, double r8);
typedef sysv64_sseint_return janet_sysv64_variant_4(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f, typedef sysv64_sseint_return janet_sysv64_variant_4(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f,
double r1, double r2, double r3, double r4, double r5, double r6, double r7, double r8); double r1, double r2, double r3, double r4, double r5, double r6, double r7, double r8);
static Janet janet_ffi_sysv64(JanetFFISignature *signature, void *function_pointer, const Janet *argv) { static Janet janet_ffi_sysv64(JanetFFISignature *signature, void *function_pointer, const Janet *argv) {
union { union {

View File

@@ -239,8 +239,8 @@ int janet_fiber_funcframe(JanetFiber *fiber, JanetFunction *func) {
fiber->data + tuplehead, fiber->data + tuplehead,
oldtop - tuplehead) oldtop - tuplehead)
: janet_wrap_tuple(janet_tuple_n( : janet_wrap_tuple(janet_tuple_n(
fiber->data + tuplehead, fiber->data + tuplehead,
oldtop - tuplehead)); oldtop - tuplehead));
} }
} }
@@ -370,8 +370,8 @@ int janet_fiber_funcframe_tail(JanetFiber *fiber, JanetFunction *func) {
fiber->data + tuplehead, fiber->data + tuplehead,
fiber->stacktop - tuplehead) fiber->stacktop - tuplehead)
: janet_wrap_tuple(janet_tuple_n( : janet_wrap_tuple(janet_tuple_n(
fiber->data + tuplehead, fiber->data + tuplehead,
fiber->stacktop - tuplehead)); fiber->stacktop - tuplehead));
} }
stacksize = tuplehead - fiber->stackstart + 1; stacksize = tuplehead - fiber->stackstart + 1;
} else { } else {

View File

@@ -124,6 +124,13 @@ void net_callback_connect(JanetFiber *fiber, JanetAsyncEvent event) {
switch (event) { switch (event) {
default: default:
break; break;
#ifndef JANET_WINDOWS
/* Wait until we have an actually event before checking.
* Windows doesn't support async connect with this, just try immediately.*/
case JANET_ASYNC_EVENT_INIT:
#endif
case JANET_ASYNC_EVENT_DEINIT:
return;
case JANET_ASYNC_EVENT_CLOSE: case JANET_ASYNC_EVENT_CLOSE:
janet_cancel(fiber, janet_cstringv("stream closed")); janet_cancel(fiber, janet_cstringv("stream closed"));
janet_async_end(fiber); janet_async_end(fiber);
@@ -154,12 +161,9 @@ void net_callback_connect(JanetFiber *fiber, JanetAsyncEvent event) {
} }
static void net_sched_connect(JanetStream *stream) { static void net_sched_connect(JanetStream *stream) {
JanetFiber *f = janet_vm.root_fiber; NetStateConnect *state = janet_malloc(sizeof(NetStateConnect));
NetStateConnect *state = (NetStateConnect *) janet_async_start(f, stream, JANET_ASYNC_LISTEN_WRITE, net_callback_connect, sizeof(NetStateConnect));
state->did_connect = 0; state->did_connect = 0;
#ifdef JANET_WINDOWS janet_async_start(stream, JANET_ASYNC_LISTEN_WRITE, net_callback_connect, state);
net_callback_connect(f, JANET_ASYNC_EVENT_USER);
#endif
} }
/* State machine for accepting connections. */ /* State machine for accepting connections. */
@@ -229,14 +233,16 @@ void net_callback_accept(JanetFiber *fiber, JanetAsyncEvent event) {
JANET_NO_RETURN static void janet_sched_accept(JanetStream *stream, JanetFunction *fun) { JANET_NO_RETURN static void janet_sched_accept(JanetStream *stream, JanetFunction *fun) {
Janet err; Janet err;
JanetFiber *f = janet_vm.root_fiber; NetStateAccept *state = janet_malloc(sizeof(NetStateAccept));
NetStateAccept *state = (NetStateAccept *) janet_async_start(f, stream, JANET_ASYNC_LISTEN_READ, net_callback_accept, sizeof(NetStateAccept));
memset(&state->overlapped, 0, sizeof(WSAOVERLAPPED)); memset(&state->overlapped, 0, sizeof(WSAOVERLAPPED));
memset(&state->buf, 0, 1024); memset(&state->buf, 0, 1024);
state->function = fun; state->function = fun;
state->lstream = stream; state->lstream = stream;
if (net_sched_accept_impl(state, f, &err)) janet_panicv(err); if (net_sched_accept_impl(state, janet_root_fiber(), &err)) {
janet_await(); janet_free(state);
janet_panicv(err);
}
janet_async_start(stream, JANET_ASYNC_LISTEN_READ, net_callback_accept, state);
} }
static int net_sched_accept_impl(NetStateAccept *state, JanetFiber *fiber, Janet *err) { static int net_sched_accept_impl(NetStateAccept *state, JanetFiber *fiber, Janet *err) {
@@ -253,7 +259,7 @@ static int net_sched_accept_impl(NetStateAccept *state, JanetFiber *fiber, Janet
int code = WSAGetLastError(); int code = WSAGetLastError();
if (code == WSA_IO_PENDING) { if (code == WSA_IO_PENDING) {
/* indicates io is happening async */ /* indicates io is happening async */
fiber->flags |= JANET_FIBER_EV_FLAG_IN_FLIGHT; janet_async_in_flight(fiber);
return 0; return 0;
} }
*err = janet_ev_lasterr(); *err = janet_ev_lasterr();
@@ -282,7 +288,7 @@ void net_callback_accept(JanetFiber *fiber, JanetAsyncEvent event) {
janet_schedule(fiber, janet_wrap_nil()); janet_schedule(fiber, janet_wrap_nil());
janet_async_end(fiber); janet_async_end(fiber);
return; return;
case JANET_ASYNC_EVENT_USER: case JANET_ASYNC_EVENT_INIT:
case JANET_ASYNC_EVENT_READ: { case JANET_ASYNC_EVENT_READ: {
#if defined(JANET_LINUX) #if defined(JANET_LINUX)
JSock connfd = accept4(stream->handle, NULL, NULL, SOCK_CLOEXEC); JSock connfd = accept4(stream->handle, NULL, NULL, SOCK_CLOEXEC);
@@ -310,11 +316,10 @@ void net_callback_accept(JanetFiber *fiber, JanetAsyncEvent event) {
} }
JANET_NO_RETURN static void janet_sched_accept(JanetStream *stream, JanetFunction *fun) { JANET_NO_RETURN static void janet_sched_accept(JanetStream *stream, JanetFunction *fun) {
JanetFiber *f = janet_vm.root_fiber; NetStateAccept *state = janet_malloc(sizeof(NetStateAccept));
NetStateAccept *state = (NetStateAccept *) janet_async_start(f, stream, JANET_ASYNC_LISTEN_READ, net_callback_accept, sizeof(NetStateAccept)); memset(state, 0, sizeof(NetStateAccept));
state->function = fun; state->function = fun;
net_callback_accept(f, JANET_ASYNC_EVENT_USER); janet_async_start(stream, JANET_ASYNC_LISTEN_READ, net_callback_accept, state);
janet_await();
} }
#endif #endif
@@ -851,7 +856,6 @@ JANET_CORE_FN(cfun_stream_read,
if (to != INFINITY) janet_addtimeout(to); if (to != INFINITY) janet_addtimeout(to);
janet_ev_recv(stream, buffer, n, MSG_NOSIGNAL); janet_ev_recv(stream, buffer, n, MSG_NOSIGNAL);
} }
janet_await();
} }
JANET_CORE_FN(cfun_stream_chunk, JANET_CORE_FN(cfun_stream_chunk,
@@ -866,7 +870,6 @@ JANET_CORE_FN(cfun_stream_chunk,
double to = janet_optnumber(argv, argc, 3, INFINITY); double to = janet_optnumber(argv, argc, 3, INFINITY);
if (to != INFINITY) janet_addtimeout(to); if (to != INFINITY) janet_addtimeout(to);
janet_ev_recvchunk(stream, buffer, n, MSG_NOSIGNAL); janet_ev_recvchunk(stream, buffer, n, MSG_NOSIGNAL);
janet_await();
} }
JANET_CORE_FN(cfun_stream_recv_from, JANET_CORE_FN(cfun_stream_recv_from,
@@ -881,7 +884,6 @@ JANET_CORE_FN(cfun_stream_recv_from,
double to = janet_optnumber(argv, argc, 3, INFINITY); double to = janet_optnumber(argv, argc, 3, INFINITY);
if (to != INFINITY) janet_addtimeout(to); if (to != INFINITY) janet_addtimeout(to);
janet_ev_recvfrom(stream, buffer, n, MSG_NOSIGNAL); janet_ev_recvfrom(stream, buffer, n, MSG_NOSIGNAL);
janet_await();
} }
JANET_CORE_FN(cfun_stream_write, JANET_CORE_FN(cfun_stream_write,
@@ -901,7 +903,6 @@ JANET_CORE_FN(cfun_stream_write,
if (to != INFINITY) janet_addtimeout(to); if (to != INFINITY) janet_addtimeout(to);
janet_ev_send_string(stream, bytes.bytes, MSG_NOSIGNAL); janet_ev_send_string(stream, bytes.bytes, MSG_NOSIGNAL);
} }
janet_await();
} }
JANET_CORE_FN(cfun_stream_send_to, JANET_CORE_FN(cfun_stream_send_to,
@@ -922,7 +923,6 @@ JANET_CORE_FN(cfun_stream_send_to,
if (to != INFINITY) janet_addtimeout(to); if (to != INFINITY) janet_addtimeout(to);
janet_ev_sendto_string(stream, bytes.bytes, dest, MSG_NOSIGNAL); janet_ev_sendto_string(stream, bytes.bytes, dest, MSG_NOSIGNAL);
} }
janet_await();
} }
JANET_CORE_FN(cfun_stream_flush, JANET_CORE_FN(cfun_stream_flush,

View File

@@ -1081,11 +1081,18 @@ static JanetFile *get_stdio_for_handle(JanetHandle handle, void *orig, int iswri
} }
#endif #endif
static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) { typedef enum {
JANET_EXECUTE_EXECUTE,
JANET_EXECUTE_SPAWN,
JANET_EXECUTE_EXEC
} JanetExecuteMode;
static Janet os_execute_impl(int32_t argc, Janet *argv, JanetExecuteMode mode) {
janet_sandbox_assert(JANET_SANDBOX_SUBPROCESS); janet_sandbox_assert(JANET_SANDBOX_SUBPROCESS);
janet_arity(argc, 1, 3); janet_arity(argc, 1, 3);
/* Get flags */ /* Get flags */
int is_spawn = mode == JANET_EXECUTE_SPAWN;
uint64_t flags = 0; uint64_t flags = 0;
if (argc > 1) { if (argc > 1) {
flags = janet_getflags(argv, 1, "epxd"); flags = janet_getflags(argv, 1, "epxd");
@@ -1109,7 +1116,7 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
int pipe_owner_flags = (is_spawn && (flags & 0x8)) ? JANET_PROC_ALLOW_ZOMBIE : 0; int pipe_owner_flags = (is_spawn && (flags & 0x8)) ? JANET_PROC_ALLOW_ZOMBIE : 0;
/* Get optional redirections */ /* Get optional redirections */
if (argc > 2) { if (argc > 2 && (mode != JANET_EXECUTE_EXEC)) {
JanetDictView tab = janet_getdictionary(argv, 2); JanetDictView tab = janet_getdictionary(argv, 2);
Janet maybe_stdin = janet_dictionary_get(tab.kvs, tab.cap, janet_ckeywordv("in")); Janet maybe_stdin = janet_dictionary_get(tab.kvs, tab.cap, janet_ckeywordv("in"));
Janet maybe_stdout = janet_dictionary_get(tab.kvs, tab.cap, janet_ckeywordv("out")); Janet maybe_stdout = janet_dictionary_get(tab.kvs, tab.cap, janet_ckeywordv("out"));
@@ -1230,12 +1237,32 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
* of posix_spawn would modify the argv array passed in. */ * of posix_spawn would modify the argv array passed in. */
char *const *cargv = (char *const *)child_argv; char *const *cargv = (char *const *)child_argv;
/* Use posix_spawn to spawn new process */
if (use_environ) { if (use_environ) {
janet_lock_environ(); janet_lock_environ();
} }
/* exec mode */
if (mode == JANET_EXECUTE_EXEC) {
#ifdef JANET_WINDOWS
janet_panic("not supported on windows");
#else
int status;
if (!use_environ) {
environ = envp;
}
do {
if (janet_flag_at(flags, 1)) {
status = execvp(cargv[0], cargv);
} else {
status = execv(cargv[0], cargv);
}
} while (status == -1 && errno == EINTR);
janet_panicf("%p: %s", cargv[0], strerror(errno ? errno : ENOENT));
#endif
}
/* Use posix_spawn to spawn new process */
/* Posix spawn setup */ /* Posix spawn setup */
posix_spawn_file_actions_t actions; posix_spawn_file_actions_t actions;
posix_spawn_file_actions_init(&actions); posix_spawn_file_actions_init(&actions);
@@ -1344,7 +1371,7 @@ JANET_CORE_FN(os_execute,
"contain the keys :in, :out, and :err, which allow redirecting stdio in the subprocess. " "contain the keys :in, :out, and :err, which allow redirecting stdio in the subprocess. "
"These arguments should be core/file values. " "These arguments should be core/file values. "
"Returns the exit status of the program.") { "Returns the exit status of the program.") {
return os_execute_impl(argc, argv, 0); return os_execute_impl(argc, argv, JANET_EXECUTE_EXECUTE);
} }
JANET_CORE_FN(os_spawn, JANET_CORE_FN(os_spawn,
@@ -1357,7 +1384,43 @@ JANET_CORE_FN(os_spawn,
"The returned value `proc` has the fields :in, :out, :err, :return-code, and " "The returned value `proc` has the fields :in, :out, :err, :return-code, and "
"the additional field :pid on unix-like platforms. Use `(os/proc-wait proc)` to rejoin the " "the additional field :pid on unix-like platforms. Use `(os/proc-wait proc)` to rejoin the "
"subprocess or `(os/proc-kill proc)`.") { "subprocess or `(os/proc-kill proc)`.") {
return os_execute_impl(argc, argv, 1); return os_execute_impl(argc, argv, JANET_EXECUTE_SPAWN);
}
JANET_CORE_FN(os_posix_exec,
"(os/posix-exec args &opt flags env)",
"Use the execvpe or execve system calls to replace the current process with an interface similar to os/execute. "
"Hoever, instead of creating a subprocess, the current process is replaced. Is not supported on windows, and "
"does not allow redirection of stdio.") {
return os_execute_impl(argc, argv, JANET_EXECUTE_EXEC);
}
JANET_CORE_FN(os_posix_fork,
"(os/posix-fork)",
"Make a `fork` system call and create a new process. Return nil if in the new process, otherwise a core/process object (as returned by os/spawn). "
"Not supported on all systems (POSIX only).") {
janet_sandbox_assert(JANET_SANDBOX_SUBPROCESS);
janet_fixarity(argc, 0);
(void) argv;
#ifdef JANET_WINDOWS
janet_panic("not supported");
#else
pid_t result;
do {
result = fork();
} while (result == -1 && errno == EINTR);
if (result == -1) {
janet_panic(strerror(errno));
}
if (result) {
JanetProc *proc = janet_abstract(&ProcAT, sizeof(JanetProc));
memset(proc, 0, sizeof(JanetProc));
proc->pid = result;
proc->flags = JANET_PROC_ALLOW_ZOMBIE;
return janet_wrap_abstract(proc);
}
return janet_wrap_nil();
#endif
} }
#ifdef JANET_EV #ifdef JANET_EV
@@ -2336,34 +2399,6 @@ JANET_CORE_FN(os_permission_int,
return janet_wrap_integer(os_get_unix_mode(argv, 0)); return janet_wrap_integer(os_get_unix_mode(argv, 0));
} }
JANET_CORE_FN(os_posix_fork,
"(os/posix-fork)",
"Make a `fork` system call and create a new process. Return nil if in the new process, otherwise a core/process object (as returned by os/spawn). "
"Not supported on all systems (POSIX only).") {
janet_sandbox_assert(JANET_SANDBOX_SUBPROCESS);
janet_fixarity(argc, 0);
(void) argv;
#ifdef JANET_WINDOWS
janet_panic("not supported");
#else
pid_t result;
do {
result = fork();
} while (result == -1 && errno == EINTR);
if (result == -1) {
janet_panic(strerror(errno));
}
if (result) {
JanetProc *proc = janet_abstract(&ProcAT, sizeof(JanetProc));
memset(proc, 0, sizeof(JanetProc));
proc->pid = result;
proc->flags = JANET_PROC_ALLOW_ZOMBIE;
return janet_wrap_abstract(proc);
}
return janet_wrap_nil();
#endif
}
#ifdef JANET_EV #ifdef JANET_EV
/* /*
@@ -2651,6 +2686,7 @@ void janet_lib_os(JanetTable *env) {
JANET_CORE_REG("os/spawn", os_spawn), JANET_CORE_REG("os/spawn", os_spawn),
JANET_CORE_REG("os/shell", os_shell), JANET_CORE_REG("os/shell", os_shell),
JANET_CORE_REG("os/posix-fork", os_posix_fork), JANET_CORE_REG("os/posix-fork", os_posix_fork),
JANET_CORE_REG("os/posix-exec", os_posix_exec),
/* no need to sandbox process management if you can't create processes /* no need to sandbox process management if you can't create processes
* (allows for limited functionality if use exposes C-functions to create specific processes) */ * (allows for limited functionality if use exposes C-functions to create specific processes) */
JANET_CORE_REG("os/proc-wait", os_proc_wait), JANET_CORE_REG("os/proc-wait", os_proc_wait),

View File

@@ -31,6 +31,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <inttypes.h> #include <inttypes.h>
#include <float.h>
/* Implements a pretty printer for Janet. The pretty printer /* Implements a pretty printer for Janet. The pretty printer
* is simple and not that flexible, but fast. */ * is simple and not that flexible, but fast. */
@@ -38,11 +39,15 @@
/* Temporary buffer size */ /* Temporary buffer size */
#define BUFSIZE 64 #define BUFSIZE 64
/* Preprocessor hacks */
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
static void number_to_string_b(JanetBuffer *buffer, double x) { static void number_to_string_b(JanetBuffer *buffer, double x) {
janet_buffer_ensure(buffer, buffer->count + BUFSIZE, 2); janet_buffer_ensure(buffer, buffer->count + BUFSIZE, 2);
const char *fmt = (x == floor(x) && const char *fmt = (x == floor(x) &&
x <= JANET_INTMAX_DOUBLE && x <= JANET_INTMAX_DOUBLE &&
x >= JANET_INTMIN_DOUBLE) ? "%.0f" : "%g"; x >= JANET_INTMIN_DOUBLE) ? "%.0f" : ("%." STR(DBL_DIG) "g");
int count; int count;
if (x == 0.0) { if (x == 0.0) {
/* Prevent printing of '-0' */ /* Prevent printing of '-0' */
@@ -772,6 +777,8 @@ struct FmtMapping {
/* Janet uses fixed width integer types for most things, so map /* Janet uses fixed width integer types for most things, so map
* format specifiers to these fixed sizes */ * format specifiers to these fixed sizes */
static const struct FmtMapping format_mappings[] = { static const struct FmtMapping format_mappings[] = {
{'D', PRId64},
{'I', PRIi64},
{'d', PRId64}, {'d', PRId64},
{'i', PRIi64}, {'i', PRIi64},
{'o', PRIo64}, {'o', PRIo64},
@@ -850,13 +857,19 @@ void janet_formatbv(JanetBuffer *b, const char *format, va_list args) {
c = scanformat(c, form, width, precision); c = scanformat(c, form, width, precision);
switch (*c++) { switch (*c++) {
case 'c': { case 'c': {
int n = va_arg(args, long); int n = va_arg(args, int);
nb = snprintf(item, MAX_ITEM, form, n); nb = snprintf(item, MAX_ITEM, form, n);
break; break;
} }
case 'd': case 'd':
case 'i': { case 'i': {
int64_t n = va_arg(args, int); int64_t n = (int64_t) va_arg(args, int32_t);
nb = snprintf(item, MAX_ITEM, form, n);
break;
}
case 'D':
case 'I': {
int64_t n = va_arg(args, int64_t);
nb = snprintf(item, MAX_ITEM, form, n); nb = snprintf(item, MAX_ITEM, form, n);
break; break;
} }
@@ -864,7 +877,7 @@ void janet_formatbv(JanetBuffer *b, const char *format, va_list args) {
case 'X': case 'X':
case 'o': case 'o':
case 'u': { case 'u': {
uint64_t n = va_arg(args, unsigned int); uint64_t n = va_arg(args, uint64_t);
nb = snprintf(item, MAX_ITEM, form, n); nb = snprintf(item, MAX_ITEM, form, n);
break; break;
} }
@@ -908,7 +921,7 @@ void janet_formatbv(JanetBuffer *b, const char *format, va_list args) {
janet_buffer_push_cstring(b, typestr(va_arg(args, Janet))); janet_buffer_push_cstring(b, typestr(va_arg(args, Janet)));
break; break;
case 'T': { case 'T': {
int types = va_arg(args, long); int types = va_arg(args, int);
pushtypes(b, types); pushtypes(b, types);
break; break;
} }
@@ -1017,6 +1030,8 @@ void janet_buffer_format(
janet_getinteger(argv, arg)); janet_getinteger(argv, arg));
break; break;
} }
case 'D':
case 'I':
case 'd': case 'd':
case 'i': { case 'i': {
int64_t n = janet_getinteger64(argv, arg); int64_t n = janet_getinteger64(argv, arg);

View File

@@ -32,6 +32,7 @@ int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char
int errflags = 0, done = 0; int errflags = 0, done = 0;
int32_t index = 0; int32_t index = 0;
Janet ret = janet_wrap_nil(); Janet ret = janet_wrap_nil();
JanetFiber *fiber = NULL;
const uint8_t *where = sourcePath ? janet_cstring(sourcePath) : NULL; const uint8_t *where = sourcePath ? janet_cstring(sourcePath) : NULL;
if (where) janet_gcroot(janet_wrap_string(where)); if (where) janet_gcroot(janet_wrap_string(where));
@@ -47,7 +48,7 @@ int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char
JanetCompileResult cres = janet_compile(form, env, where); JanetCompileResult cres = janet_compile(form, env, where);
if (cres.status == JANET_COMPILE_OK) { if (cres.status == JANET_COMPILE_OK) {
JanetFunction *f = janet_thunk(cres.funcdef); JanetFunction *f = janet_thunk(cres.funcdef);
JanetFiber *fiber = janet_fiber(f, 64, 0, NULL); fiber = janet_fiber(f, 64, 0, NULL);
fiber->env = env; fiber->env = env;
JanetSignal status = janet_continue(fiber, janet_wrap_nil(), &ret); JanetSignal status = janet_continue(fiber, janet_wrap_nil(), &ret);
if (status != JANET_SIGNAL_OK && status != JANET_SIGNAL_EVENT) { if (status != JANET_SIGNAL_OK && status != JANET_SIGNAL_EVENT) {
@@ -112,9 +113,14 @@ int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char
#ifdef JANET_EV #ifdef JANET_EV
/* Enter the event loop if we are not already in it */ /* Enter the event loop if we are not already in it */
if (janet_vm.stackn == 0) { if (janet_vm.stackn == 0) {
janet_gcroot(ret); if (fiber) {
janet_gcroot(janet_wrap_fiber(fiber));
}
janet_loop(); janet_loop();
janet_gcunroot(ret); if (fiber) {
janet_gcunroot(janet_wrap_fiber(fiber));
ret = fiber->last_value;
}
} }
#endif #endif
if (out) *out = ret; if (out) *out = ret;

View File

@@ -596,8 +596,7 @@ typedef enum {
JANET_ASYNC_EVENT_READ = 6, JANET_ASYNC_EVENT_READ = 6,
JANET_ASYNC_EVENT_WRITE = 7, JANET_ASYNC_EVENT_WRITE = 7,
JANET_ASYNC_EVENT_COMPLETE = 8, /* Used on windows for IOCP */ JANET_ASYNC_EVENT_COMPLETE = 8, /* Used on windows for IOCP */
JANET_ASYNC_EVENT_FAILED = 9, /* Used on windows for IOCP */ JANET_ASYNC_EVENT_FAILED = 9 /* Used on windows for IOCP */
JANET_ASYNC_EVENT_USER = 10
} JanetAsyncEvent; } JanetAsyncEvent;
typedef enum { typedef enum {
@@ -606,9 +605,7 @@ typedef enum {
JANET_ASYNC_LISTEN_BOTH JANET_ASYNC_LISTEN_BOTH
} JanetAsyncMode; } JanetAsyncMode;
/* Typedefs */
typedef struct JanetStream JanetStream; typedef struct JanetStream JanetStream;
typedef void (*JanetEVCallback)(JanetFiber *fiber, JanetAsyncEvent event);
/* Wrapper around file descriptors and HANDLEs that can be polled. */ /* Wrapper around file descriptors and HANDLEs that can be polled. */
struct JanetStream { struct JanetStream {
@@ -620,9 +617,24 @@ struct JanetStream {
const void *methods; /* Methods for this stream */ const void *methods; /* Methods for this stream */
}; };
typedef void (*JanetEVCallback)(JanetFiber *fiber, JanetAsyncEvent event);
/* Start listening for events from a stream on the current root fiber. After
* calling this, users should call janet_await() before returning from the
* current C Function. This also will call janet_await.
* mode is which events to listen for, and callback is the function pointer to
* call when ever an event is sent from the event loop. state is an optional (can be NULL)
* pointer to data allocated with janet_malloc. This pointer will be passed to callback as
* fiber->ev_state. It will also be freed for you by the runtime when the event loop determines
* it can no longer be referenced. On windows, the contents of state MUST contained an OVERLAPPED struct. */
JANET_API JANET_NO_RETURN void janet_async_start(JanetStream *stream, JanetAsyncMode mode, JanetEVCallback callback, void *state);
/* Do not send any more events to the given callback. Call this after scheduling fiber to be resume
* or canceled. */
JANET_API void janet_async_end(JanetFiber *fiber); JANET_API void janet_async_end(JanetFiber *fiber);
JANET_API void *janet_async_start(JanetFiber *fiber, JanetStream *stream,
JanetAsyncMode mode, JanetEVCallback callback, size_t data_size); /* Needed for windows to mark a fiber as waiting for an IOCP completion event. Noop on other platforms. */
JANET_API void janet_async_in_flight(JanetFiber *fiber);
#endif #endif
@@ -1488,22 +1500,22 @@ JANET_API void janet_ev_post_event(JanetVM *vm, JanetCallback cb, JanetEVGeneric
JANET_API void janet_ev_default_threaded_callback(JanetEVGenericMessage return_value); JANET_API void janet_ev_default_threaded_callback(JanetEVGenericMessage return_value);
/* Read async from a stream */ /* Read async from a stream */
JANET_API void janet_ev_read(JanetStream *stream, JanetBuffer *buf, int32_t nbytes); JANET_NO_RETURN JANET_API void janet_ev_read(JanetStream *stream, JanetBuffer *buf, int32_t nbytes);
JANET_API void janet_ev_readchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes); JANET_NO_RETURN JANET_API void janet_ev_readchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes);
#ifdef JANET_NET #ifdef JANET_NET
JANET_API void janet_ev_recv(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags); JANET_NO_RETURN JANET_API void janet_ev_recv(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
JANET_API void janet_ev_recvchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags); JANET_NO_RETURN JANET_API void janet_ev_recvchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
JANET_API void janet_ev_recvfrom(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags); JANET_NO_RETURN JANET_API void janet_ev_recvfrom(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
#endif #endif
/* Write async to a stream */ /* Write async to a stream */
JANET_API void janet_ev_write_buffer(JanetStream *stream, JanetBuffer *buf); JANET_NO_RETURN JANET_API void janet_ev_write_buffer(JanetStream *stream, JanetBuffer *buf);
JANET_API void janet_ev_write_string(JanetStream *stream, JanetString str); JANET_NO_RETURN JANET_API void janet_ev_write_string(JanetStream *stream, JanetString str);
#ifdef JANET_NET #ifdef JANET_NET
JANET_API void janet_ev_send_buffer(JanetStream *stream, JanetBuffer *buf, int flags); JANET_NO_RETURN JANET_API void janet_ev_send_buffer(JanetStream *stream, JanetBuffer *buf, int flags);
JANET_API void janet_ev_send_string(JanetStream *stream, JanetString str, int flags); JANET_NO_RETURN JANET_API void janet_ev_send_string(JanetStream *stream, JanetString str, int flags);
JANET_API void janet_ev_sendto_buffer(JanetStream *stream, JanetBuffer *buf, void *dest, int flags); JANET_NO_RETURN JANET_API void janet_ev_sendto_buffer(JanetStream *stream, JanetBuffer *buf, void *dest, int flags);
JANET_API void janet_ev_sendto_string(JanetStream *stream, JanetString str, void *dest, int flags); JANET_NO_RETURN JANET_API void janet_ev_sendto_string(JanetStream *stream, JanetString str, void *dest, int flags);
#endif #endif
#endif #endif

View File

@@ -502,10 +502,10 @@ static void kright(void) {
} }
static void krightw(void) { static void krightw(void) {
while (gbl_pos != gbl_len && !isspace(gbl_buf[gbl_pos])) { while (gbl_pos != gbl_len && isspace(gbl_buf[gbl_pos])) {
gbl_pos++; gbl_pos++;
} }
while (gbl_pos != gbl_len && isspace(gbl_buf[gbl_pos])) { while (gbl_pos != gbl_len && !isspace(gbl_buf[gbl_pos])) {
gbl_pos++; gbl_pos++;
} }
refresh(); refresh();