diff --git a/src/vm.c b/src/vm.c index 1f25e520..973030a1 100644 --- a/src/vm.c +++ b/src/vm.c @@ -27,11 +27,14 @@ #include "tjs.h" #include +#include #include #include #define TJS__DEFAULT_STACK_SIZE 10 * 1024 * 1024 // 10 MB +/* JS malloc functions */ + static void *tjs__mf_malloc(JSMallocState *s, size_t size) { void *ptr; @@ -92,6 +95,48 @@ static const JSMallocFunctions tjs_mf = { .js_malloc_usable_size = tjs__malloc_usable_size, }; +/* SharedArrayBuffer functions */ + +typedef struct { + int ref_count; + uint64_t buf[0]; +} TJSSABHeader; + +static int atomic_add_int(int *ptr, int v) { + return atomic_fetch_add((_Atomic(uint32_t) *) ptr, v) + v; +} + +static void *tjs__sab_alloc(void *opaque, size_t size) { + TJSSABHeader *sab = tjs__malloc(sizeof(*sab) + size); + if (!sab) + return NULL; + sab->ref_count = 1; + return sab->buf; +} + +static void tjs__sab_free(void *opaque, void *ptr) { + TJSSABHeader *sab; + int ref_count; + sab = (TJSSABHeader *) ((uint8_t *) ptr - sizeof(TJSSABHeader)); + ref_count = atomic_add_int(&sab->ref_count, -1); + assert(ref_count >= 0); + if (ref_count == 0) + tjs__free(sab); +} + +static void tjs__sab_dup(void *opaque, void *ptr) { + TJSSABHeader *sab; + sab = (TJSSABHeader *) ((uint8_t *) ptr - sizeof(TJSSABHeader)); + atomic_add_int(&sab->ref_count, 1); +} + +static const JSSharedArrayBufferFunctions tjs_sf = { + .sab_alloc = tjs__sab_alloc, + .sab_dup = tjs__sab_dup, + .sab_free = tjs__sab_free, + .sab_opaque = NULL, +}; + /* core */ extern const uint8_t tjs__core[]; extern const uint32_t tjs__core_size; @@ -247,6 +292,9 @@ TJSRuntime *TJS_NewRuntimeInternal(bool is_worker, TJSRunOptions *options) { /* Set stack size */ JS_SetMaxStackSize(rt, options->stack_size); + /* SharedArrayBuffer functions */ + JS_SetSharedArrayBufferFunctions(rt, &tjs_sf); + qrt->is_worker = is_worker; CHECK_EQ(uv_loop_init(&qrt->loop), 0);