mirror of
https://github.com/janet-lang/janet
synced 2024-12-26 00:10:27 +00:00
Allow passing pointer-buffers to other threads.
This commit is contained in:
parent
1cadff8e58
commit
2e38f9ba61
@ -2,6 +2,8 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## ??? - Unreleased
|
||||
- Add `ffi/pointer-buffer` to convert pointers to buffers the cannot be reallocated. This
|
||||
allows easier manipulation of FFI memory, memory mapped files, and buffer memory shared between threads.
|
||||
- Calling `ev/cancel` on a fiber waiting on `ev/gather` will correctly
|
||||
cancel the child fibers.
|
||||
- Add `(sandbox ...)` function to core for permission based security. Also add `janet_sandbox` to C API.
|
||||
|
@ -58,6 +58,18 @@ JanetBuffer *janet_buffer_init(JanetBuffer *buffer, int32_t capacity) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Initialize an unmanaged buffer */
|
||||
JanetBuffer *janet_pointer_buffer_unsafe(void *memory, int32_t capacity, int32_t count) {
|
||||
if (count < 0) janet_panic("count < 0");
|
||||
if (capacity < count) janet_panic("capacity < count");
|
||||
JanetBuffer *buffer = janet_gcalloc(JANET_MEMORY_BUFFER, sizeof(JanetBuffer));
|
||||
buffer->gc.flags |= JANET_BUFFER_FLAG_NO_REALLOC;
|
||||
buffer->capacity = capacity;
|
||||
buffer->count = count;
|
||||
buffer->data = (uint8_t *) memory;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Deinitialize a buffer (free data memory) */
|
||||
void janet_buffer_deinit(JanetBuffer *buffer) {
|
||||
if (!(buffer->gc.flags & JANET_BUFFER_FLAG_NO_REALLOC)) {
|
||||
|
@ -1515,12 +1515,8 @@ JANET_CORE_FN(cfun_ffi_pointer_buffer,
|
||||
int32_t capacity = janet_getnat(argv, 1);
|
||||
int32_t count = janet_optnat(argv, argc, 2, 0);
|
||||
int64_t offset = janet_optinteger64(argv, argc, 3, 0);
|
||||
JanetBuffer *buffer = janet_gcalloc(JANET_MEMORY_BUFFER, sizeof(JanetBuffer));
|
||||
buffer->gc.flags |= JANET_BUFFER_FLAG_NO_REALLOC;
|
||||
buffer->capacity = capacity;
|
||||
buffer->count = count;
|
||||
buffer->data = ((uint8_t *) pointer) + offset;
|
||||
return janet_wrap_buffer(buffer);
|
||||
uint8_t *offset_pointer = ((uint8_t *) pointer) + offset;
|
||||
return janet_wrap_buffer(janet_pointer_buffer_unsafe(offset_pointer, capacity, count));
|
||||
}
|
||||
|
||||
void janet_lib_ffi(JanetTable *env) {
|
||||
|
@ -67,7 +67,8 @@ enum {
|
||||
LB_UNSAFE_POINTER, /* 222 */
|
||||
LB_STRUCT_PROTO, /* 223 */
|
||||
#ifdef JANET_EV
|
||||
LB_THREADED_ABSTRACT/* 224 */
|
||||
LB_THREADED_ABSTRACT, /* 224 */
|
||||
LB_POINTER_BUFFER, /* 224 */
|
||||
#endif
|
||||
} LeadBytes;
|
||||
|
||||
@ -153,6 +154,10 @@ static void pushbytes(MarshalState *st, const uint8_t *bytes, int32_t len) {
|
||||
janet_buffer_push_bytes(st->buf, bytes, len);
|
||||
}
|
||||
|
||||
static void pushpointer(MarshalState *st, void *ptr) {
|
||||
janet_buffer_push_bytes(st->buf, (const uint8_t *) &ptr, sizeof(ptr));
|
||||
}
|
||||
|
||||
/* Marshal a size_t onto the buffer */
|
||||
static void push64(MarshalState *st, uint64_t x) {
|
||||
if (x <= 0xF0) {
|
||||
@ -511,6 +516,16 @@ static void marshal_one(MarshalState *st, Janet x, int flags) {
|
||||
JanetBuffer *buffer = janet_unwrap_buffer(x);
|
||||
/* Record reference */
|
||||
MARK_SEEN();
|
||||
#ifdef JANET_EV
|
||||
if ((flags & JANET_MARSHAL_UNSAFE) &&
|
||||
(buffer->gc.flags & JANET_BUFFER_FLAG_NO_REALLOC)) {
|
||||
pushbyte(st, LB_POINTER_BUFFER);
|
||||
pushint(st, buffer->count);
|
||||
pushint(st, buffer->capacity);
|
||||
pushpointer(st, buffer->data);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
pushbyte(st, LB_BUFFER);
|
||||
pushint(st, buffer->count);
|
||||
pushbytes(st, buffer->data, buffer->count);
|
||||
@ -606,8 +621,7 @@ static void marshal_one(MarshalState *st, Janet x, int flags) {
|
||||
if (!(flags & JANET_MARSHAL_UNSAFE)) goto no_registry;
|
||||
MARK_SEEN();
|
||||
pushbyte(st, LB_UNSAFE_POINTER);
|
||||
void *ptr = janet_unwrap_pointer(x);
|
||||
pushbytes(st, (uint8_t *) &ptr, sizeof(void *));
|
||||
pushpointer(st, janet_unwrap_pointer(x));
|
||||
return;
|
||||
}
|
||||
no_registry:
|
||||
@ -1415,6 +1429,27 @@ static const uint8_t *unmarshal_one(
|
||||
janet_v_push(st->lookup, *out);
|
||||
return data;
|
||||
}
|
||||
case LB_POINTER_BUFFER: {
|
||||
data++;
|
||||
int32_t count = readnat(st, &data);
|
||||
int32_t capacity = readnat(st, &data);
|
||||
MARSH_EOS(st, data + sizeof(void *));
|
||||
union {
|
||||
void *ptr;
|
||||
uint8_t bytes[sizeof(void *)];
|
||||
} u;
|
||||
if (!(flags & JANET_MARSHAL_UNSAFE)) {
|
||||
janet_panicf("unsafe flag not given, "
|
||||
"will not unmarshal raw pointer at index %d",
|
||||
(int)(data - st->start));
|
||||
}
|
||||
memcpy(u.bytes, data, sizeof(void *));
|
||||
data += sizeof(void *);
|
||||
JanetBuffer *buffer = janet_pointer_buffer_unsafe(u.ptr, capacity, count);
|
||||
*out = janet_wrap_buffer(buffer);
|
||||
janet_v_push(st->lookup, *out);
|
||||
return data;
|
||||
}
|
||||
case LB_UNSAFE_CFUNCTION: {
|
||||
MARSH_EOS(st, data + sizeof(JanetCFunction));
|
||||
data++;
|
||||
|
@ -334,6 +334,7 @@ JANET_CORE_FN(cfun_net_sockaddr,
|
||||
"given in the port argument. On Linux, abstract "
|
||||
"unix domain sockets are specified with a leading '@' character in port. If `multi` is truthy, will "
|
||||
"return all address that match in an array instead of just the first.") {
|
||||
janet_sandbox_assert(JANET_SANDBOX_NET_CONNECT); /* connect OR listen */
|
||||
janet_arity(argc, 2, 4);
|
||||
int socktype = janet_get_sockettype(argv, argc, 2);
|
||||
int is_unix = 0;
|
||||
|
@ -1588,6 +1588,7 @@ JANET_API Janet janet_array_peek(JanetArray *array);
|
||||
#define JANET_BUFFER_FLAG_NO_REALLOC 0x10000
|
||||
JANET_API JanetBuffer *janet_buffer(int32_t capacity);
|
||||
JANET_API JanetBuffer *janet_buffer_init(JanetBuffer *buffer, int32_t capacity);
|
||||
JANET_API JanetBuffer *janet_pointer_buffer_unsafe(void *memory, int32_t capacity, int32_t count);
|
||||
JANET_API void janet_buffer_deinit(JanetBuffer *buffer);
|
||||
JANET_API void janet_buffer_ensure(JanetBuffer *buffer, int32_t capacity, int32_t growth);
|
||||
JANET_API void janet_buffer_setcount(JanetBuffer *buffer, int32_t count);
|
||||
|
Loading…
Reference in New Issue
Block a user