Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

changed JanetTArrayView to use JanetBuffer #146

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 64 additions & 99 deletions src/tarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,73 +64,44 @@ static JanetTArrayType get_ta_type_by_name(const uint8_t *name) {
return 0;
}

static JanetTArrayBuffer *ta_buffer_init(JanetTArrayBuffer *buf, size_t size) {
buf->data = NULL;
if (size > 0) {
buf->data = (uint8_t *)calloc(size, sizeof(uint8_t));
if (buf->data == NULL) {
janet_panic("out of memory");
}
}
buf->size = size;
#ifdef JANET_BIG_ENDIAN
buf->flags = TA_FLAG_BIG_ENDIAN;
#else
buf->flags = 0;
#endif
return buf;
}

static int ta_buffer_gc(void *p, size_t s) {
(void) s;
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
free(buf->data);
return 0;
}

static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) {
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
janet_marshal_abstract(ctx, p);
janet_marshal_size(ctx, buf->size);
janet_marshal_int(ctx, buf->flags);
janet_marshal_bytes(ctx, buf->data, buf->size);
}

static void *ta_buffer_unmarshal(JanetMarshalContext *ctx) {
JanetTArrayBuffer *buf = janet_unmarshal_abstract(ctx, sizeof(JanetTArrayBuffer));
size_t size = janet_unmarshal_size(ctx);
int32_t flags = janet_unmarshal_int(ctx);
ta_buffer_init(buf, size);
buf->flags = flags;
janet_unmarshal_bytes(ctx, buf->data, size);
return buf;
}

#ifdef JANET_ATEND_LENGTH
static size_t ta_view_length(void *p, size_t size) {
JanetTArrayView *view = (JanetTArrayView *)p;
return view->size;
}
static size_t ta_buffer_length(void *p, size_t size) {
JanetTArrayBuffer *buffer = (JanetTArrayBuffer *)p;
return buffer->size;
JanetBuffer *buffer = (JanetBuffer *)p;
return buffer->capacity;
}
#endif

const JanetAbstractType janet_ta_buffer_type = {
.name = "ta/buffer",
.gc = ta_buffer_gc,
.marshal = ta_buffer_marshal,
.unmarshal = ta_buffer_unmarshal,
#ifdef JANET_ATEND_LENGTH
.length = ta_buffer_length,
#endif
};

// get an unmanaged JanetBuffer
JanetBuffer *ta_buffer_init(size_t buf_size) {
void* mem = janet_smalloc(buf_size);
if (NULL == mem) {
JANET_OUT_OF_MEMORY;
}
return janet_pointer_buffer_unsafe(mem, buf_size, 0);
}

/* Ensure that the buffer has enough internal capacity */
void ta_buffer_sensure(JanetBuffer *buffer, int32_t new_size, int32_t growth) {
void *new_data;
uint8_t *old = buffer->data;
if (new_size <= buffer->capacity) return;
printf("new size %d old capa %d\n", new_size, buffer->capacity);
int64_t big_capacity = ((int64_t) new_size) * growth;
new_size = big_capacity > INT32_MAX ? INT32_MAX : (int32_t) big_capacity;
new_data = janet_srealloc(old, (size_t) new_size);
buffer->data = (uint8_t *) new_data;
buffer->capacity = new_size;
}

static int ta_mark(void *p, size_t s) {
(void) s;
JanetTArrayView *view = (JanetTArrayView *)p;
janet_mark(janet_wrap_abstract(view->buffer));
janet_mark(janet_wrap_buffer(view->buffer));
return 0;
}

Expand All @@ -142,11 +113,14 @@ static void ta_view_marshal(void *p, JanetMarshalContext *ctx) {
janet_marshal_size(ctx, view->stride);
janet_marshal_int(ctx, view->type);
janet_marshal_size(ctx, offset);
janet_marshal_janet(ctx, janet_wrap_abstract(view->buffer));
janet_marshal_janet(ctx, janet_wrap_buffer(view->buffer));
janet_marshal_size(ctx, view->buffer->capacity);
janet_marshal_bytes(ctx, view->buffer->data, view->buffer->capacity);
}

static void *ta_view_unmarshal(JanetMarshalContext *ctx) {
size_t offset;
size_t capacity;
int32_t atype;
Janet buffer;
JanetTArrayView *view = janet_unmarshal_abstract(ctx, sizeof(JanetTArrayView));
Expand All @@ -158,14 +132,14 @@ static void *ta_view_unmarshal(JanetMarshalContext *ctx) {
view->type = atype;
offset = janet_unmarshal_size(ctx);
buffer = janet_unmarshal_janet(ctx);
if (!janet_checktype(buffer, JANET_ABSTRACT) ||
(janet_abstract_type(janet_unwrap_abstract(buffer)) != &janet_ta_buffer_type)) {
janet_panicf("expected typed array buffer");
capacity = janet_unmarshal_size(ctx);
if (!janet_checktype(buffer, JANET_BUFFER)) {
janet_panicf("expected buffer");
}
view->buffer = (JanetTArrayBuffer *)janet_unwrap_abstract(buffer);
view->buffer = janet_unwrap_buffer(buffer);
size_t buf_need_size = offset + (ta_type_sizes[view->type]) * ((view->size - 1) * view->stride + 1);
if (view->buffer->size < buf_need_size)
janet_panic("bad typed array offset in marshalled data");
ta_buffer_sensure(view->buffer, buf_need_size, 2);
janet_unmarshal_bytes(ctx, view->buffer->data, capacity);
view->as.u8 = view->buffer->data + offset;
return view;
}
Expand Down Expand Up @@ -311,32 +285,27 @@ const JanetAbstractType janet_ta_view_type = {
#endif
};

JanetTArrayBuffer *janet_tarray_buffer(size_t size) {
JanetTArrayBuffer *buf = janet_abstract(&janet_ta_buffer_type, sizeof(JanetTArrayBuffer));
ta_buffer_init(buf, size);
return buf;
}

JanetTArrayView *janet_tarray_view(
JanetTArrayType type,
size_t size,
size_t stride,
size_t offset,
JanetTArrayBuffer *buffer) {
JanetBuffer *buffer) {

JanetTArrayView *view = janet_abstract(&janet_ta_view_type, sizeof(JanetTArrayView));

if ((stride < 1) || (size < 1)) janet_panic("stride and size should be > 0");
size_t buf_size = offset + ta_type_sizes[type] * ((size - 1) * stride + 1);

if (NULL == buffer) {
buffer = janet_abstract(&janet_ta_buffer_type, sizeof(JanetTArrayBuffer));
ta_buffer_init(buffer, buf_size);
buffer = ta_buffer_init(buf_size);
}

if (buffer->size < buf_size) {
ta_buffer_sensure(buffer, buf_size, 2);

if (buffer->capacity < buf_size) {
janet_panicf("bad buffer size, %i bytes allocated < %i required",
buffer->size,
buffer->capacity,
buf_size);
}

Expand All @@ -349,8 +318,8 @@ JanetTArrayView *janet_tarray_view(
return view;
}

JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n) {
return janet_getabstract(argv, n, &janet_ta_buffer_type);
JanetBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n) {
return janet_unwrap_buffer(argv[n]);
}

JanetTArrayView *janet_gettarray_any(const Janet *argv, int32_t n) {
Expand All @@ -370,7 +339,7 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 5);
size_t offset = 0;
size_t stride = 1;
JanetTArrayBuffer *buffer = NULL;
JanetBuffer *buffer = NULL;
const uint8_t *keyw = janet_getkeyword(argv, 0);
JanetTArrayType type = get_ta_type_by_name(keyw);
size_t size = janet_getsize(argv, 1);
Expand All @@ -382,12 +351,11 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) {
int32_t blen;
const uint8_t *bytes;
if (janet_bytes_view(argv[4], &bytes, &blen)) {
buffer = janet_abstract(&janet_ta_buffer_type, sizeof(JanetTArrayBuffer));
ta_buffer_init(buffer, (size_t) blen);
buffer = ta_buffer_init(blen);
memcpy(buffer->data, bytes, blen);
} else {
if (!janet_checktype(argv[4], JANET_ABSTRACT)) {
janet_panicf("bad slot #%d, expected ta/view|ta/buffer, got %v",
janet_panicf("bad slot #%d, expected ta/view|buffer, got %v",
4, argv[4]);
}
void *p = janet_unwrap_abstract(argv[4]);
Expand All @@ -396,10 +364,8 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) {
offset = (view->buffer->data - view->as.u8) + offset * ta_type_sizes[view->type];
stride *= view->stride;
buffer = view->buffer;
} else if (janet_abstract_type(p) == &janet_ta_buffer_type) {
buffer = p;
} else {
janet_panicf("bad slot #%d, expected ta/view|ta/buffer, got %v",
janet_panicf("bad slot #%d, expected ta/view|buffer, got %v",
4, argv[4]);
}
}
Expand All @@ -419,11 +385,11 @@ static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
JanetTArrayView *view;
if ((view = ta_is_view(argv[0]))) {
return janet_wrap_abstract(view->buffer);
return janet_wrap_buffer(view->buffer);
} else {
janet_panicf("bad slot #%d, expected ta/view, got %v",
0, argv[0]);
}
size_t size = janet_getsize(argv, 0);
JanetTArrayBuffer *buf = janet_tarray_buffer(size);
return janet_wrap_abstract(buf);
}

static Janet cfun_typed_array_size(int32_t argc, Janet *argv) {
Expand All @@ -432,8 +398,8 @@ static Janet cfun_typed_array_size(int32_t argc, Janet *argv) {
if ((view = ta_is_view(argv[0]))) {
return janet_wrap_number((double) view->size);
}
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)janet_getabstract(argv, 0, &janet_ta_buffer_type);
return janet_wrap_number((double) buf->size);
JanetBuffer *buf = janet_unwrap_buffer(argv[0]);
return janet_wrap_number((double) buf->capacity);
}

static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) {
Expand All @@ -454,15 +420,15 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) {
janet_struct_put(props, janet_ckeywordv("type-size"),
janet_wrap_number((double) ta_type_sizes[view->type]));
janet_struct_put(props, janet_ckeywordv("buffer"),
janet_wrap_abstract(view->buffer));
janet_wrap_buffer(view->buffer));
janet_struct_put(props, janet_ckeywordv("big-endian"),
janet_wrap_boolean(view->flags & TA_FLAG_BIG_ENDIAN));
return janet_wrap_struct(janet_struct_end(props));
} else {
JanetTArrayBuffer *buffer = janet_gettarray_buffer(argv, 0);
JanetBuffer *buffer = janet_gettarray_buffer(argv, 0);
JanetKV *props = janet_struct_begin(2);
janet_struct_put(props, janet_ckeywordv("size"),
janet_wrap_number((double) buffer->size));
janet_struct_put(props, janet_ckeywordv("big-endian"),
janet_wrap_boolean(buffer->flags & TA_FLAG_BIG_ENDIAN));
janet_wrap_number((double) buffer->capacity));
return janet_wrap_struct(janet_struct_end(props));
}
}
Expand Down Expand Up @@ -516,8 +482,8 @@ static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) {
size_t pos_dst = (dst->as.u8 - dst->buffer->data) + (index_dst * step_dst);
uint8_t *ps = src->buffer->data + pos_src;
uint8_t *pd = dst->buffer->data + pos_dst;
if ((pos_dst + (count - 1) * step_dst + src_atom_size <= dst->buffer->size) &&
(pos_src + (count - 1) * step_src + src_atom_size <= src->buffer->size)) {
if ((pos_dst + (count - 1) * step_dst + src_atom_size <= dst->buffer->capacity) &&
(pos_src + (count - 1) * step_src + src_atom_size <= src->buffer->capacity)) {
for (size_t i = 0; i < count; i++) {
memmove(pd, ps, src_atom_size);
pd += step_dst;
Expand All @@ -544,8 +510,8 @@ static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) {
size_t pos_dst = (dst->as.u8 - dst->buffer->data) + (index_dst * step_dst);
uint8_t *ps = src->buffer->data + pos_src, * pd = dst->buffer->data + pos_dst;
uint8_t temp[TA_ATOM_MAXSIZE];
if ((pos_dst + (count - 1)*step_dst + src_atom_size <= dst->buffer->size) &&
(pos_src + (count - 1)*step_src + src_atom_size <= src->buffer->size)) {
if ((pos_dst + (count - 1)*step_dst + src_atom_size <= dst->buffer->capacity) &&
(pos_src + (count - 1)*step_src + src_atom_size <= src->buffer->capacity)) {
for (size_t i = 0; i < count; i++) {
memcpy(temp, ps, src_atom_size);
memcpy(ps, pd, src_atom_size);
Expand All @@ -567,8 +533,8 @@ static const JanetReg ta_cfuns[] = {
},
{
"buffer", cfun_typed_array_buffer,
"(tarray/buffer array|size)\n\n"
"Return typed array buffer or create a new buffer."
"(tarray/buffer array)\n\n"
"Return typed array buffer."
},
{
"length", cfun_typed_array_size,
Expand Down Expand Up @@ -617,6 +583,5 @@ static JanetMethod tarray_view_methods[] = {
/* Module entry point */
JANET_MODULE_ENTRY(JanetTable *env) {
janet_cfuns(env, "tarray", ta_cfuns);
janet_register_abstract_type(&janet_ta_buffer_type);
janet_register_abstract_type(&janet_ta_view_type);
}
15 changes: 4 additions & 11 deletions src/tarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ extern "C" {
#endif

extern JANET_API const JanetAbstractType janet_ta_view_type;
extern JANET_API const JanetAbstractType janet_ta_buffer_type;

typedef enum {
JANET_TARRAY_TYPE_U8,
Expand All @@ -45,12 +44,6 @@ typedef enum {
JANET_TARRAY_TYPE_F64
} JanetTArrayType;

typedef struct {
uint8_t *data;
size_t size;
int32_t flags;
} JanetTArrayBuffer;

typedef struct {
union {
void *pointer;
Expand All @@ -65,16 +58,16 @@ typedef struct {
float *f32;
double *f64;
} as;
JanetTArrayBuffer *buffer;
JanetBuffer *buffer;
size_t size;
int32_t flags;
size_t stride;
JanetTArrayType type;
} JanetTArrayView;

JANET_API JanetTArrayBuffer *janet_tarray_buffer(size_t size);
JANET_API JanetTArrayView *janet_tarray_view(JanetTArrayType type, size_t size, size_t stride, size_t offset, JanetTArrayBuffer *buffer);
JANET_API JanetTArrayView *janet_tarray_view(JanetTArrayType type, size_t size, size_t stride, size_t offset, JanetBuffer *buffer);
JANET_API int janet_is_tarray_view(Janet x, JanetTArrayType type);
JANET_API JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n);
JANET_API JanetBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n);
JANET_API JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, JanetTArrayType type);
JanetTArrayView *janet_gettarray_any(const Janet *argv, int32_t n);

Expand Down
Loading
Loading