mirror of
https://github.com/janet-lang/janet
synced 2024-11-25 17:57:17 +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:
parent
0ee2ff1b05
commit
021b71ad62
@ -128,6 +128,24 @@ static void pushbytes(MarshalState *st, const uint8_t *bytes, int32_t len) {
|
|||||||
janet_buffer_push_bytes(st->buf, bytes, 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. */
|
/* Forward declaration to enable mutual recursion. */
|
||||||
static void marshal_one(MarshalState *st, Janet x, int flags);
|
static void marshal_one(MarshalState *st, Janet x, int flags);
|
||||||
static void marshal_one_fiber(MarshalState *st, JanetFiber *fiber, 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);
|
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) {
|
void janet_marshal_int(JanetMarshalContext *ctx, int32_t value) {
|
||||||
MarshalState *st = (MarshalState *)(ctx->m_state);
|
MarshalState *st = (MarshalState *)(ctx->m_state);
|
||||||
pushint(st, value);
|
pushint(st, value);
|
||||||
@ -297,7 +320,7 @@ static void marshal_one_abstract(MarshalState *st, Janet x, int flags) {
|
|||||||
JanetMarshalContext context = {st, NULL, flags, NULL};
|
JanetMarshalContext context = {st, NULL, flags, NULL};
|
||||||
pushbyte(st, LB_ABSTRACT);
|
pushbyte(st, LB_ABSTRACT);
|
||||||
marshal_one(st, janet_ckeywordv(at->name), flags + 1);
|
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);
|
at->marshal(abstract, &context);
|
||||||
} else {
|
} else {
|
||||||
janet_panicf("try to marshal unregistered abstract type, cannot marshal %p", x);
|
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 */
|
/* Check reference and registry value */
|
||||||
{
|
{
|
||||||
Janet check = janet_table_get(&st->seen, x);
|
Janet check = janet_table_get(&st->seen, x);
|
||||||
@ -552,6 +574,29 @@ static int32_t readint(UnmarshalState *st, const uint8_t **atdata) {
|
|||||||
return ret;
|
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 */
|
/* Assert a janet type */
|
||||||
static void janet_asserttype(Janet x, JanetType t) {
|
static void janet_asserttype(Janet x, JanetType t) {
|
||||||
if (!janet_checktype(x, t)) {
|
if (!janet_checktype(x, t)) {
|
||||||
@ -904,14 +949,9 @@ void janet_unmarshal_int(JanetMarshalContext *ctx, int32_t *i) {
|
|||||||
*i = readint(st, &(ctx->data));
|
*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) {
|
void janet_unmarshal_size(JanetMarshalContext *ctx, size_t *i) {
|
||||||
UnmarshalState *st = (UnmarshalState *)(ctx->u_state);
|
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) {
|
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);
|
const JanetAbstractType *at = janet_get_abstract_type(key);
|
||||||
if (at == NULL) return NULL;
|
if (at == NULL) return NULL;
|
||||||
if (at->unmarshal) {
|
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};
|
JanetMarshalContext context = {NULL, st, flags, data};
|
||||||
at->unmarshal(p, &context);
|
at->unmarshal(p, &context);
|
||||||
*out = janet_wrap_abstract(p);
|
*out = janet_wrap_abstract(p);
|
||||||
|
@ -107,17 +107,17 @@ static int ta_buffer_gc(void *p, size_t s) {
|
|||||||
|
|
||||||
static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) {
|
static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) {
|
||||||
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
|
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
|
||||||
janet_marshal_int(ctx, buf->size);
|
janet_marshal_size(ctx, buf->size);
|
||||||
janet_marshal_int(ctx, buf->flags);
|
janet_marshal_int(ctx, buf->flags);
|
||||||
janet_marshal_bytes(ctx, buf->data, buf->size);
|
janet_marshal_bytes(ctx, buf->data, buf->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ta_buffer_unmarshal(void *p, JanetMarshalContext *ctx) {
|
static void ta_buffer_unmarshal(void *p, JanetMarshalContext *ctx) {
|
||||||
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
|
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
|
||||||
uint32_t size;
|
size_t size;
|
||||||
janet_unmarshal_uint(ctx, &size);
|
janet_unmarshal_size(ctx, &size);
|
||||||
ta_buffer_init(buf, size); // warning if indianess <> platform ??
|
ta_buffer_init(buf, size);
|
||||||
janet_unmarshal_uint(ctx, &(buf->flags));
|
janet_unmarshal_int(ctx, &(buf->flags));
|
||||||
janet_unmarshal_bytes(ctx, buf->data, buf->size);
|
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) {
|
static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) {
|
||||||
JanetTArrayView *view = (JanetTArrayView *)p;
|
JanetTArrayView *view = (JanetTArrayView *)p;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
int32_t atype;
|
||||||
Janet buffer;
|
Janet buffer;
|
||||||
janet_unmarshal_size(ctx, &(view->size));
|
janet_unmarshal_size(ctx, &(view->size));
|
||||||
janet_unmarshal_size(ctx, &(view->stride));
|
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_size(ctx, &offset);
|
||||||
janet_unmarshal_janet(ctx, &buffer);
|
janet_unmarshal_janet(ctx, &buffer);
|
||||||
view->buffer = (JanetTArrayBuffer *)janet_unwrap_abstract(buffer);
|
view->buffer = (JanetTArrayBuffer *)janet_unwrap_abstract(buffer);
|
||||||
@ -173,7 +177,6 @@ static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) {
|
|||||||
JanetTArrayType type; \
|
JanetTArrayType type; \
|
||||||
} TA_View_##thetype ;
|
} TA_View_##thetype ;
|
||||||
|
|
||||||
|
|
||||||
#define DEFINE_VIEW_GETTER(type) \
|
#define DEFINE_VIEW_GETTER(type) \
|
||||||
static Janet ta_get_##type(void *p, Janet key) { \
|
static Janet ta_get_##type(void *p, Janet key) { \
|
||||||
Janet value; \
|
Janet value; \
|
||||||
@ -206,7 +209,9 @@ void ta_put_##type(void *p, Janet key,Janet value) { \
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_VIEW_INITIALIZER(thetype) \
|
#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)) { \
|
if ((stride<1) || (size <1)) { \
|
||||||
janet_panic("stride and size should be > 0"); \
|
janet_panic("stride and size should be > 0"); \
|
||||||
}; \
|
}; \
|
||||||
@ -227,8 +232,6 @@ void ta_put_##type(void *p, Janet key,Janet value) { \
|
|||||||
return view; \
|
return view; \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BUILD_TYPE(type) \
|
#define BUILD_TYPE(type) \
|
||||||
DEFINE_VIEW_TYPE(type) \
|
DEFINE_VIEW_TYPE(type) \
|
||||||
DEFINE_VIEW_GETTER(type) \
|
DEFINE_VIEW_GETTER(type) \
|
||||||
@ -251,7 +254,6 @@ BUILD_TYPE(float64)
|
|||||||
#undef DEFINE_VIEW_SETTER
|
#undef DEFINE_VIEW_SETTER
|
||||||
#undef DEFINE_VIEW_INITIALIZER
|
#undef DEFINE_VIEW_INITIALIZER
|
||||||
|
|
||||||
|
|
||||||
#define DEFINE_VIEW_ABSTRACT_TYPE(type) \
|
#define DEFINE_VIEW_ABSTRACT_TYPE(type) \
|
||||||
{ \
|
{ \
|
||||||
"ta/"#type, \
|
"ta/"#type, \
|
||||||
@ -278,8 +280,6 @@ static const JanetAbstractType ta_array_types[] = {
|
|||||||
|
|
||||||
#undef DEFINE_VIEW_ABSTRACT_TYPE
|
#undef DEFINE_VIEW_ABSTRACT_TYPE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int is_ta_anytype(Janet x) {
|
static int is_ta_anytype(Janet x) {
|
||||||
if (janet_checktype(x, JANET_ABSTRACT)) {
|
if (janet_checktype(x, JANET_ABSTRACT)) {
|
||||||
const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x));
|
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;
|
(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
|
#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) {
|
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);
|
CASE_TYPE_INITIALIZE(float64);
|
||||||
default :
|
default :
|
||||||
janet_panic("bad typed array type");
|
janet_panic("bad typed array type");
|
||||||
|
|
||||||
}
|
}
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@ -374,7 +372,6 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) {
|
|||||||
return janet_wrap_abstract(view);
|
return janet_wrap_abstract(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) {
|
static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
if (is_ta_anytype(argv[0])) {
|
if (is_ta_anytype(argv[0])) {
|
||||||
@ -415,7 +412,6 @@ 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));
|
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));
|
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 */
|
||||||
|
@ -93,6 +93,4 @@ void janet_lib_peg(JanetTable *env);
|
|||||||
void janet_lib_typed_array(JanetTable *env);
|
void janet_lib_typed_array(JanetTable *env);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1257,12 +1257,12 @@ JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int *flags);
|
|||||||
|
|
||||||
/* Marshal API */
|
/* Marshal API */
|
||||||
JANET_API void janet_marshal_int(JanetMarshalContext *ctx, int32_t value);
|
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_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_bytes(JanetMarshalContext *ctx, const uint8_t *bytes, int32_t len);
|
||||||
JANET_API void janet_marshal_janet(JanetMarshalContext *ctx, Janet x);
|
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_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_size(JanetMarshalContext *ctx, size_t *i);
|
||||||
JANET_API void janet_unmarshal_byte(JanetMarshalContext *ctx, uint8_t *b);
|
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);
|
JANET_API void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, int32_t len);
|
||||||
@ -1290,7 +1290,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
uint32_t flags;
|
int32_t flags;
|
||||||
} JanetTArrayBuffer;
|
} JanetTArrayBuffer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -1310,7 +1310,6 @@ JANET_API JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, Ja
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***** END SECTION MAIN *****/
|
/***** END SECTION MAIN *****/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user