From 4d07176f1c19907fbd311dc0b0619e97dbd4f7b1 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Thu, 21 Feb 2019 20:52:39 +0100 Subject: [PATCH] work in progress --- src/core/marsh.c | 71 ++++++++++++++++++++++++++++++++++-- src/core/typedarray.c | 84 +++++++++++++++++++++++++++++++++++++++++-- src/include/janet.h | 21 +++++++++++ 3 files changed, 170 insertions(+), 6 deletions(-) diff --git a/src/core/marsh.c b/src/core/marsh.c index b79d00ee..6eadc2b4 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -288,6 +288,67 @@ static void marshal_one_fiber(MarshalState *st, JanetFiber *fiber, int flags) { marshal_one(st, janet_wrap_fiber(fiber->child), flags + 1); } + + +typedef struct { + JanetMarshalState *st; + int flags; +} JanetMarshalContext; + + + + +#define MARK_SEEN() \ + janet_table_put(&st->seen, x, janet_wrap_integer(st->nextid++)) + + +void janet_marshal_int(JanetMarshalContext *ctx,int32_t value) { + pushint(ctx->st,value); +}; +void janet_marshal_byte(JanetMarshalContext *ctx,uint8_t value) { + pushbyte(ctx->st,value); +}; +void janet_marshal_bytes(JanetMarshalContext *ctx,const uint8_t *bytes, int32_t len) { + pushbytes(ctx->st,bytes,len); +} +void janet_marshal_janet(JanetMarshalContext *ctx,Janet x) { + marshal_one(ctx->st,x,ctx->st->flags + 1); +} + +static int marshal_one_abstract(MarshalState *st, Janet x, int flags) { + const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); + if (at->marshal) { + MARK_SEEN(); + JanetMarshalContext context={st,flags}; + at->marshal(janet_unwrap_abstract(x),&context); + + /* objects has to be allocate by marshal function and null/terminated*/ + JanetMarshalObject * walk = objects; + while (walk) { + switch (walk->type) { + case JANET_MO_TYPE_INTEGER : + pushint(st,walk->value.integer); + break; + case JANET_MO_TYPE_BYTE : + pushbyte(st,walk->value.byte); + break; + case JANET_MO_TYPE_BYTES : + pushbyte(st,walk->value.bytes,walk->length); + break; + case JANET_MO_TYPE_JANET : + marshal_one(st,walk->value.janet, flags + 1); + break; + } + walk++; + } + if (objects) free(objects); + return 1; + } else { + return 0; + } +} + + /* The main body of the marshaling function. Is the main * entry point for the mutually recursive functions. */ static void marshal_one(MarshalState *st, Janet x, int flags) { @@ -316,8 +377,6 @@ static void marshal_one(MarshalState *st, Janet x, int flags) { } } -#define MARK_SEEN() \ - janet_table_put(&st->seen, x, janet_wrap_integer(st->nextid++)) /* Check reference and registry value */ { @@ -448,7 +507,13 @@ static void marshal_one(MarshalState *st, Janet x, int flags) { MARK_SEEN(); } goto done; - case JANET_ABSTRACT: + case JANET_ABSTRACT: { + if (marshal_one_abstract(st,x,flags)) { + goto done; + } else { + goto noregval; + } + } case JANET_CFUNCTION: goto noregval; case JANET_FUNCTION: { diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 7ba04859..934ecfe7 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -53,7 +53,6 @@ typedef enum TA_Type { TA_TYPE_float64, } TA_Type; -#define TA_COUNT_TYPES (TA_TYPE_float64 + 1) static char *ta_type_names[] = { "uint8", @@ -80,7 +79,10 @@ static size_t ta_type_sizes[] = { sizeof(ta_float32_t), sizeof(ta_float64_t), }; +#define TA_COUNT_TYPES (TA_TYPE_float64 + 1) +#define TA_ATOM_MAXSIZE 8; +#define TA_FLAG_BIG_ENDIAN 1 static TA_Type get_ta_type_by_name(const uint8_t *name) { size_t nt = sizeof(ta_type_names) / sizeof(char *); @@ -92,14 +94,22 @@ static TA_Type get_ta_type_by_name(const uint8_t *name) { } + + typedef struct { - size_t size; uint8_t *data; + size_t size; + int32_t flags; } TA_Buffer; static TA_Buffer *ta_buffer_init(TA_Buffer *buf, size_t size) { buf->data = (uint8_t *)calloc(size, sizeof(uint8_t)); buf->size = size; +#ifdef JANET_BIG_ENDIAN + buf->flags = TA_FLAG_BIG_ENDIAN; +#else + buf->flags = 0; +#endif return buf; } @@ -110,6 +120,14 @@ static int ta_buffer_gc(void *p, size_t s) { return 0; } +static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) { + TA_Buffer *buf = (TA_Buffer *)p; + janet_marshal_int(ctx,buf->size); + janet_marshal_int(ctx,buf->flags); + janet_marshal_bytes(ctx,buf->data,buf->size); +} + + static const JanetAbstractType ta_buffer_type = {"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}; @@ -282,7 +300,6 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { #undef CASE_TYPE_INITIALIZE - static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); if (is_ta_type(argv[0])) { @@ -320,6 +337,67 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { return janet_wrap_struct(janet_struct_end(props)); } +static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { + janet_fixarity(argc, 4); + if (is_ta_type(argv[0]) && is_ta_type(argv[2])) { + TA_View *src = (TA_View *)janet_unwrap_abstract(argv[0]); + size_t index_src=(size_t)janet_getinteger(argv, 1); + TA_View *dst = (TA_View *)janet_unwrap_abstract(argv[2]); + size_t index_dst=(size_t)janet_getinteger(argv, 3); + size_t src_atom_size=ta_type_sizes[src->type]; + size_t dst_atom_size=ta_type_sizes[dst->type]; + size_t pos_src=((uint8_t *)(src->data) - src->buffer->data)+(index_src*src->stride*src_atom_size); + size_t pos_dst=((uint8_t *)(dst->data) - dst->buffer->data)+(index_dst*dst->stride*dst_atom_size); + if (pos_dst+src_atom_size <= dst->buffer->size) + memmove(dst->buffer->data+pos_dst,src->buffer->data+pos_src,src_atom_size); + else + janet_panic("typed array out of bound"); + } else { + janet_panic("expected typed array"); + } + return janet_wrap_nil(); +} + +static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) { + janet_fixarity(argc, 4); + if (is_ta_type(argv[0]) && is_ta_type(argv[2])) { + TA_View *src = (TA_View *)janet_unwrap_abstract(argv[0]); + size_t index_src=(size_t)janet_getinteger(argv, 1); + TA_View *dst = (TA_View *)janet_unwrap_abstract(argv[2]); + size_t index_dst=(size_t)janet_getinteger(argv, 3); + size_t src_atom_size=ta_type_sizes[src->type]; + size_t dst_atom_size=ta_type_sizes[dst->type]; + size_t pos_src=((uint8_t *)(src->data) - src->buffer->data)+(index_src*src->stride*src_atom_size); + size_t pos_dst=((uint8_t *)(dst->data) - dst->buffer->data)+(index_dst*dst->stride*dst_atom_size); + uint8_t temp[TA_ATOM_MAXSIZE]; + if (pos_dst+src_atom_size <= dst->buffer->size) { + uint8_t * src_ptr=src->buffer->data+pos_src; + uint8_t * dst_ptr=dst->buffer->data+pos_dst; + memcpy(temp,src_ptr,src_atom_size); + memcpy(src_ptr,dst_ptr,src_atom_size); + memcpy(dst_ptr,temp,src_atom_size); + } + else + janet_panic("typed array buffer out of bound"); + } else { + janet_panic("expected typed array"); + } + return janet_wrap_nil(); +} + + +/* static int marshal_push_ta_buffer(MarshalState *st, Janet x, int flags) { */ +/* TA_Buffer *buffer =(TA_Buffer *)janet_unwrap_abstract(x); */ +/* /\* Record reference *\/ */ +/* janet_table_put(&st->seen, x, janet_wrap_integer(st->nextid++)) */ +/* pushbyte(st, LB_TA_BUFFER); */ +/* pushint(st, buffer->size); */ +/* pushint(st, buffer->flags); */ +/* pushbytes(st, buffer->data, buffer->size); */ +/* } */ + + + static const JanetReg ta_cfuns[] = { diff --git a/src/include/janet.h b/src/include/janet.h index cf46b8f2..ebafbe90 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1191,6 +1191,27 @@ JANET_API JanetRange janet_getslice(int32_t argc, const Janet *argv); JANET_API int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const char *which); JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which); + +typedef enum { + JANET_MO_TYPE_INTEGER, + JANET_MO_TYPE_BYTE, + JANET_MO_TYPE_BYTES, + JANET_MO_TYPE_JANET, +} JanetMarshalObjectType; + +typedef struct { + union { + int32_t integer; + uint8_t byte; + uint8_t * bytes; + Janet janet; + } value; + int length; /* for bytes type */ + MarshalObjectType type; +} JanetMarshalObject; + +JanetMarshalObject * janet_marhal_objects_init(size_t count); + /***** END SECTION MAIN *****/ #ifdef __cplusplus