1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-24 22:23:15 +00:00

Allow proper serialization of size_t in marsh.c

Typed arrays used size_t in serialization: C APIs will
also often use it, so it makes sense to add first class support
for it rather than assume it will will fint into an integer.

These changes should quiet some visual studio warnings.

Also make some spacing more consistent.
This commit is contained in:
Calvin Rose 2019-03-07 22:06:49 -05:00
parent 0ee2ff1b05
commit 021b71ad62
4 changed files with 71 additions and 38 deletions

View File

@ -128,6 +128,24 @@ static void pushbytes(MarshalState *st, const uint8_t *bytes, int32_t len) {
janet_buffer_push_bytes(st->buf, bytes, len);
}
/* Marshal a size_t onto the buffer */
static void pushsize(MarshalState *st, size_t x) {
if (x <= 0xF0) {
/* Single byte */
pushbyte(st, (uint8_t) x);
} else {
/* Multibyte */
uint8_t bytes[9];
int nbytes = 0;
while (x) {
bytes[++nbytes] = x & 0xFF;
x >>= 8;
}
bytes[0] = 0xF0 + nbytes;
pushbytes(st, bytes, nbytes + 1);
}
}
/* Forward declaration to enable mutual recursion. */
static void marshal_one(MarshalState *st, Janet x, int flags);
static void marshal_one_fiber(MarshalState *st, JanetFiber *fiber, int flags);
@ -266,6 +284,11 @@ static void marshal_one_fiber(MarshalState *st, JanetFiber *fiber, int flags) {
marshal_one(st, janet_wrap_fiber(fiber->child), flags + 1);
}
void janet_marshal_size(JanetMarshalContext *ctx, size_t value) {
MarshalState *st = (MarshalState *)(ctx->m_state);
pushsize(st, value);
};
void janet_marshal_int(JanetMarshalContext *ctx, int32_t value) {
MarshalState *st = (MarshalState *)(ctx->m_state);
pushint(st, value);
@ -297,7 +320,7 @@ static void marshal_one_abstract(MarshalState *st, Janet x, int flags) {
JanetMarshalContext context = {st, NULL, flags, NULL};
pushbyte(st, LB_ABSTRACT);
marshal_one(st, janet_ckeywordv(at->name), flags + 1);
pushint(st, janet_abstract_size(abstract));
pushsize(st, janet_abstract_size(abstract));
at->marshal(abstract, &context);
} else {
janet_panicf("try to marshal unregistered abstract type, cannot marshal %p", x);
@ -329,7 +352,6 @@ static void marshal_one(MarshalState *st, Janet x, int flags) {
}
}
/* Check reference and registry value */
{
Janet check = janet_table_get(&st->seen, x);
@ -552,6 +574,29 @@ static int32_t readint(UnmarshalState *st, const uint8_t **atdata) {
return ret;
}
/* Helper to read a size_t (up to 8 bytes unsigned). */
static size_t readsize(UnmarshalState *st, const uint8_t **atdata) {
const uint8_t *data = *atdata;
MARSH_EOS(st, data);
if (*data <= 0xF0) {
/* Single byte */
size_t ret = *data++;
*atdata = data;
return ret;
} else {
/* Multibyte */
int nbytes = *data++ - 0xF0;
size_t value = 0;
if (nbytes < 1 || nbytes > 8)
janet_panic("invalid size_t");
MARSH_EOS(st, data + nbytes - 1);
for (int i = 0; i < nbytes; i++)
value = (value << 8) + *data++;
*atdata = data;
return value;
}
}
/* Assert a janet type */
static void janet_asserttype(Janet x, JanetType t) {
if (!janet_checktype(x, t)) {
@ -904,14 +949,9 @@ void janet_unmarshal_int(JanetMarshalContext *ctx, int32_t *i) {
*i = readint(st, &(ctx->data));
};
void janet_unmarshal_uint(JanetMarshalContext *ctx, uint32_t *i) {
UnmarshalState *st = (UnmarshalState *)(ctx->u_state);
*i = (uint32_t)readint(st, &(ctx->data));
};
void janet_unmarshal_size(JanetMarshalContext *ctx, size_t *i) {
UnmarshalState *st = (UnmarshalState *)(ctx->u_state);
*i = (size_t)readint(st, &(ctx->data));
*i = readsize(st, &(ctx->data));
};
void janet_unmarshal_byte(JanetMarshalContext *ctx, uint8_t *b) {
@ -938,7 +978,7 @@ static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t *
const JanetAbstractType *at = janet_get_abstract_type(key);
if (at == NULL) return NULL;
if (at->unmarshal) {
void *p = janet_abstract(at, readint(st, &data));
void *p = janet_abstract(at, readsize(st, &data));
JanetMarshalContext context = {NULL, st, flags, data};
at->unmarshal(p, &context);
*out = janet_wrap_abstract(p);

View File

@ -40,7 +40,7 @@ typedef int64_t ta_int64_t;
typedef float ta_float32_t;
typedef double ta_float64_t;
static char *ta_type_names[] = {
static char *ta_type_names[] = {
"uint8",
"int8",
"uint16",
@ -54,7 +54,7 @@ static char *ta_type_names[] = {
"any"
};
static size_t ta_type_sizes[] = {
static size_t ta_type_sizes[] = {
sizeof(ta_uint8_t),
sizeof(ta_int8_t),
sizeof(ta_uint16_t),
@ -107,17 +107,17 @@ static int ta_buffer_gc(void *p, size_t s) {
static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) {
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
janet_marshal_int(ctx, buf->size);
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(void *p, JanetMarshalContext *ctx) {
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
uint32_t size;
janet_unmarshal_uint(ctx, &size);
ta_buffer_init(buf, size); // warning if indianess <> platform ??
janet_unmarshal_uint(ctx, &(buf->flags));
size_t size;
janet_unmarshal_size(ctx, &size);
ta_buffer_init(buf, size);
janet_unmarshal_int(ctx, &(buf->flags));
janet_unmarshal_bytes(ctx, buf->data, buf->size);
}
@ -151,10 +151,14 @@ static void ta_view_marshal(void *p, JanetMarshalContext *ctx) {
static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) {
JanetTArrayView *view = (JanetTArrayView *)p;
size_t offset;
int32_t atype;
Janet buffer;
janet_unmarshal_size(ctx, &(view->size));
janet_unmarshal_size(ctx, &(view->stride));
janet_unmarshal_uint(ctx, &(view->type));
janet_unmarshal_int(ctx, &atype);
if (atype < 0 || atype >= TA_COUNT_TYPES)
janet_panic("bad typed array type");
view->type = atype;
janet_unmarshal_size(ctx, &offset);
janet_unmarshal_janet(ctx, &buffer);
view->buffer = (JanetTArrayBuffer *)janet_unwrap_abstract(buffer);
@ -166,15 +170,14 @@ static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) {
#define DEFINE_VIEW_TYPE(thetype) \
typedef struct { \
JanetTArrayBuffer * buffer; \
ta_##thetype##_t * data; \
JanetTArrayBuffer *buffer; \
ta_##thetype##_t *data; \
size_t size; \
size_t stride; \
JanetTArrayType type; \
} TA_View_##thetype ;
#define DEFINE_VIEW_GETTER(type) \
#define DEFINE_VIEW_GETTER(type) \
static Janet ta_get_##type(void *p, Janet key) { \
Janet value; \
size_t index; \
@ -206,7 +209,9 @@ void ta_put_##type(void *p, Janet key,Janet value) { \
}
#define DEFINE_VIEW_INITIALIZER(thetype) \
static JanetTArrayView * ta_init_##thetype(JanetTArrayView * view,JanetTArrayBuffer * buf,size_t size,size_t offset,size_t stride) { \
static JanetTArrayView *ta_init_##thetype(JanetTArrayView *view, \
JanetTArrayBuffer *buf, size_t size, \
size_t offset, size_t stride) { \
if ((stride<1) || (size <1)) { \
janet_panic("stride and size should be > 0"); \
}; \
@ -227,8 +232,6 @@ void ta_put_##type(void *p, Janet key,Janet value) { \
return view; \
};
#define BUILD_TYPE(type) \
DEFINE_VIEW_TYPE(type) \
DEFINE_VIEW_GETTER(type) \
@ -251,7 +254,6 @@ BUILD_TYPE(float64)
#undef DEFINE_VIEW_SETTER
#undef DEFINE_VIEW_INITIALIZER
#define DEFINE_VIEW_ABSTRACT_TYPE(type) \
{ \
"ta/"#type, \
@ -278,8 +280,6 @@ static const JanetAbstractType ta_array_types[] = {
#undef DEFINE_VIEW_ABSTRACT_TYPE
static int is_ta_anytype(Janet x) {
if (janet_checktype(x, JANET_ABSTRACT)) {
const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x));
@ -295,7 +295,6 @@ static int is_ta_type(Janet x, JanetTArrayType type) {
(janet_abstract_type(janet_unwrap_abstract(x)) == &ta_array_types[type])) ? 1 : 0;
}
#define CASE_TYPE_INITIALIZE(type) case JANET_TARRAY_TYPE_##type : ta_init_##type(view,buffer,size,offset,stride); break
JanetTArrayBuffer *janet_tarray_buffer(size_t size) {
@ -319,7 +318,6 @@ JanetTArrayView *janet_tarray_view(JanetTArrayType type, size_t size, size_t str
CASE_TYPE_INITIALIZE(float64);
default :
janet_panic("bad typed array type");
}
return view;
}
@ -374,7 +372,6 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) {
return janet_wrap_abstract(view);
}
static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
if (is_ta_anytype(argv[0])) {
@ -415,10 +412,9 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) {
janet_struct_put(props, janet_ckeywordv("big-endian"), janet_wrap_boolean(buffer->flags & TA_FLAG_BIG_ENDIAN));
return janet_wrap_struct(janet_struct_end(props));
}
}
/* TODO move it , it's not the good place for this function */
/* TODO move it, it's not the good place for this function */
static Janet cfun_abstract_properties(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
const uint8_t *key = janet_getkeyword(argv, 0);

View File

@ -93,6 +93,4 @@ void janet_lib_peg(JanetTable *env);
void janet_lib_typed_array(JanetTable *env);
#endif
#endif

View File

@ -1257,12 +1257,12 @@ JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int *flags);
/* Marshal API */
JANET_API void janet_marshal_int(JanetMarshalContext *ctx, int32_t value);
JANET_API void janet_marshal_size(JanetMarshalContext *ctx, size_t value);
JANET_API void janet_marshal_byte(JanetMarshalContext *ctx, uint8_t value);
JANET_API void janet_marshal_bytes(JanetMarshalContext *ctx, const uint8_t *bytes, int32_t len);
JANET_API void janet_marshal_janet(JanetMarshalContext *ctx, Janet x);
JANET_API void janet_unmarshal_int(JanetMarshalContext *ctx, int32_t *i);
JANET_API void janet_unmarshal_uint(JanetMarshalContext *ctx, uint32_t *i);
JANET_API void janet_unmarshal_size(JanetMarshalContext *ctx, size_t *i);
JANET_API void janet_unmarshal_byte(JanetMarshalContext *ctx, uint8_t *b);
JANET_API void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, int32_t len);
@ -1290,12 +1290,12 @@ typedef enum {
typedef struct {
uint8_t *data;
size_t size;
uint32_t flags;
int32_t flags;
} JanetTArrayBuffer;
typedef struct {
JanetTArrayBuffer *buffer;
void *data; /* pointer inside buffer->data */
void *data; /* pointer inside buffer->data */
size_t size;
size_t stride;
JanetTArrayType type;
@ -1310,7 +1310,6 @@ JANET_API JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, Ja
#endif
/***** END SECTION MAIN *****/
#ifdef __cplusplus