From 1d50fd948543cd6d6a180e12363e33a9abaaa8c4 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Thu, 21 Feb 2019 00:15:48 +0100 Subject: [PATCH 01/18] First exeperiments with JS style Binary Typed Arrays --- examples/tarray.janet | 74 +++++++++ src/core/corelib.c | 4 + src/core/typedarray.c | 350 ++++++++++++++++++++++++++++++++++++++++++ src/core/util.h | 5 + src/include/janet.h | 6 + 5 files changed, 439 insertions(+) create mode 100644 examples/tarray.janet create mode 100644 src/core/typedarray.c diff --git a/examples/tarray.janet b/examples/tarray.janet new file mode 100644 index 00000000..1210a6f6 --- /dev/null +++ b/examples/tarray.janet @@ -0,0 +1,74 @@ +(defmacro printf [& xs] ['print ['string/format (splice xs)]]) + +(defn matrix [nrow ncol] {:nrow nrow :ncol ncol :array (tarray/new :float64 (* nrow ncol))}) + +(defn matrix/row [mat i] + (def {:nrow nrow :ncol ncol :array array} mat) + (tarray/new :float64 ncol 1 (* i ncol) array)) + +(defn matrix/column [mat j] + (def {:nrow nrow :ncol ncol :array array} mat) + (tarray/new :float64 nrow ncol j array)) + +(defn matrix/set [mat i j value] + (def {:nrow nrow :ncol ncol :array array} mat) + (set (array (+ (* i ncol) j)) value)) + +(defn matrix/get [mat i j value] + (def {:nrow nrow :ncol ncol :array array} mat) + (array (+ (* i ncol) j))) + + +# other variants to test rows and cols views + +(defn matrix/set* [mat i j value] + (set ((matrix/row mat i) j) value)) + +(defn matrix/set** [mat i j value] + (set ((matrix/column mat j) i) value)) + + +(defn matrix/get* [mat i j value] + ((matrix/row mat i) j)) + +(defn matrix/get** [mat i j value] + ((matrix/column j) i)) + + +(defn tarray/print [array] + (def size (tarray/length array)) + (def buf @"") + (buffer/format buf "[%2i]" size) + (for i 0 size + (buffer/format buf " %+6.3f " (array i))) + (print buf)) + +(defn matrix/print [mat] + (def {:nrow nrow :ncol ncol :array tarray} mat) + (printf "matrix %iX%i %p" nrow ncol tarray) + (for i 0 nrow + (tarray/print (matrix/row mat i)))) + + +(def nr 5) +(def nc 4) +(def A (matrix nr nc)) + +(loop (i :range (0 nr) j :range (0 nc)) + (matrix/set A i j i)) +(matrix/print A) + +(loop (i :range (0 nr) j :range (0 nc)) + (matrix/set* A i j i))) +(matrix/print A) + +(loop (i :range (0 nr) j :range (0 nc)) + (matrix/set** A i j i))) +(matrix/print A) + +(print "tarray") +(tarray/print (A :array)) + +(printf "properties:\n%p" (tarray/properties (A :array))) + +(printf "row properties:\n%p" (tarray/properties (matrix/row A 1))) diff --git a/src/core/corelib.c b/src/core/corelib.c index effed5df..c946ef7d 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -787,6 +787,10 @@ JanetTable *janet_core_env(void) { #ifdef JANET_ASSEMBLER janet_lib_asm(env); #endif +#ifdef JANET_TYPED_ARRAY + janet_lib_typed_array(env); +#endif + #ifdef JANET_BOOTSTRAP /* Run bootstrap source */ diff --git a/src/core/typedarray.c b/src/core/typedarray.c new file mode 100644 index 00000000..c7e557bd --- /dev/null +++ b/src/core/typedarray.c @@ -0,0 +1,350 @@ +/* +* Copyright (c) 2019 Calvin Rose +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +/* Compiler feature test macros for things */ +#define _DEFAULT_SOURCE +#define _BSD_SOURCE + +#ifndef JANET_AMALG +#include +#include "util.h" +#endif + +typedef uint8_t ta_uint8_t; +typedef int8_t ta_int8_t; +typedef uint16_t ta_uint16_t; +typedef int16_t ta_int16_t; +typedef uint32_t ta_uint32_t; +typedef int32_t ta_int32_t; +typedef uint64_t ta_uint64_t; +typedef int64_t ta_int64_t; +typedef float ta_float32_t; +typedef double ta_float64_t; + +typedef enum TA_Type { + TA_TYPE_uint8, + TA_TYPE_int8, + TA_TYPE_uint16, + TA_TYPE_int16, + TA_TYPE_uint32, + TA_TYPE_int32, + TA_TYPE_uint64, + TA_TYPE_int64, + TA_TYPE_float32, + TA_TYPE_float64, +} TA_Type; + +#define TA_COUNT_TYPES (TA_TYPE_float64 + 1) + +static char * ta_type_names[]= { + "uint8", + "int8", + "uint16", + "int16", + "uint32", + "int32", + "uint64", + "int64", + "float32", + "float64", +}; + +static size_t ta_type_sizes[]= { + sizeof(ta_uint8_t), + sizeof(ta_int8_t), + sizeof(ta_uint16_t), + sizeof(ta_int16_t), + sizeof(ta_uint32_t), + sizeof(ta_int32_t), + sizeof(ta_uint64_t), + sizeof(ta_int64_t), + sizeof(ta_float32_t), + sizeof(ta_float64_t), +}; + + +static TA_Type get_ta_type_by_name(const uint8_t * name) { + size_t nt=sizeof(ta_type_names)/sizeof(char *); + for (size_t i=0; idata=(uint8_t *)calloc(size,sizeof(uint8_t)); + buf->size=size; + return buf; +} + +static int ta_buffer_gc(void *p, size_t s) { + (void) s; + TA_Buffer * buf=(TA_Buffer *)p; + free(buf->data); + return 0; +} + +static const JanetAbstractType ta_buffer_type= {"ta/buffer",ta_buffer_gc,NULL,NULL,NULL}; + + +typedef struct { + TA_Buffer *buffer; + void * data; /* pointer inside buffer->data */ + size_t size; + size_t stride; + TA_Type type; +} TA_View; + + +static int ta_mark(void *p, size_t s) { + (void) s; + TA_View * view=(TA_View *)p; + janet_mark(janet_wrap_abstract(view->buffer)); + return 0; +} + +#define DEFINE_VIEW_TYPE(type) \ + typedef struct { \ + TA_Buffer * buffer; \ + ta_##type##_t * data; \ + size_t size; \ + size_t stride; \ + TA_Type type; \ + } TA_View_##type ; + + +#define DEFINE_VIEW_GETTER(type) \ +static Janet ta_get_##type(void *p, Janet key) { \ + Janet value; \ + size_t index; \ + if (!janet_checkint(key)) \ + janet_panic("expected integer key"); \ + index = (size_t)janet_unwrap_integer(key);\ + TA_View_##type * array=(TA_View_##type *)p; \ + if (index >= array->size) { \ + value = janet_wrap_nil(); \ + } else { \ + value = janet_wrap_number(array->data[index*array->stride]); \ + } \ + return value; \ +} + +#define DEFINE_VIEW_SETTER(type) \ +void ta_put_##type(void *p, Janet key,Janet value) { \ + size_t index;\ + if (!janet_checkint(key))\ + janet_panic("expected integer key"); \ + if (!janet_checktype(value,JANET_NUMBER)) \ + janet_panic("expected number value"); \ + index = (size_t)janet_unwrap_integer(key); \ + TA_View_##type * array=(TA_View_##type *)p; \ + if (index >= array->size) { \ + janet_panic("typed array out of bound"); \ + } \ + array->data[index*array->stride]=(ta_##type##_t)janet_unwrap_number(value); \ +} + +#define DEFINE_VIEW_INITIALIZER(type) \ + static TA_View * ta_init_##type(TA_View * view,TA_Buffer * buf,size_t size,size_t offset,size_t stride) { \ + TA_View_##type * tview=(TA_View_##type *) view; \ + size_t buf_size=offset+(size-1)*(sizeof(ta_##type##_t))*stride+1; \ + if (buf==NULL) { \ + buf=(TA_Buffer *)janet_abstract(&ta_buffer_type,sizeof(TA_Buffer)); \ + ta_buffer_init(buf,buf_size); \ + } \ + if (buf->sizebuffer=buf; \ + tview->stride=stride; \ + tview->size=size; \ + tview->data=(ta_##type##_t *)(buf->data+offset); \ + tview->type=TA_TYPE_##type; \ + return view; \ +} + +#define BUILD_TYPE(type) \ +DEFINE_VIEW_TYPE(type) \ +DEFINE_VIEW_GETTER(type) \ +DEFINE_VIEW_SETTER(type) \ +DEFINE_VIEW_INITIALIZER(type) + +BUILD_TYPE(uint8) +BUILD_TYPE(int8) +BUILD_TYPE(uint16) +BUILD_TYPE(int16) +BUILD_TYPE(uint32) +BUILD_TYPE(int32) +BUILD_TYPE(uint64) +BUILD_TYPE(int64) +BUILD_TYPE(float32) +BUILD_TYPE(float64) + +#undef DEFINE_VIEW_TYPE +#undef DEFINE_VIEW_GETTER +#undef DEFINE_VIEW_SETTER +#undef DEFINE_VIEW_INITIALIZER + + +#define VIEW_ABSTRACT_DEFINE(type) {"ta/"#type,NULL,ta_mark,ta_get_##type,ta_put_##type} + +static const JanetAbstractType ta_array_types[]= { + VIEW_ABSTRACT_DEFINE(uint8), + VIEW_ABSTRACT_DEFINE(int8), + VIEW_ABSTRACT_DEFINE(uint16), + VIEW_ABSTRACT_DEFINE(int16), + VIEW_ABSTRACT_DEFINE(uint32), + VIEW_ABSTRACT_DEFINE(int32), + VIEW_ABSTRACT_DEFINE(uint64), + VIEW_ABSTRACT_DEFINE(int64), + VIEW_ABSTRACT_DEFINE(float32), + VIEW_ABSTRACT_DEFINE(float64), +}; + +static int is_ta_type(Janet x) { + if (janet_checktype(x, JANET_ABSTRACT)) { + const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); + for (size_t i=0; i2) + stride=(size_t)janet_getinteger(argv,2); + if (argc>3) + offset=(size_t)janet_getinteger(argv,3); + if (argc>4) { + if (is_ta_type(argv[4])) { + TA_View *view = (TA_View *)janet_unwrap_abstract(argv[4]); + offset=(view->buffer->data - (uint8_t *)(view->data))+offset*ta_type_sizes[view->type]; + stride*=view->stride; + buffer=view->buffer; + } else { + buffer=(TA_Buffer *)janet_getabstract(argv,4,&ta_buffer_type); + } + } + TA_View * view=janet_abstract(&ta_array_types[type],sizeof(TA_View)); + switch (type) { + CASE_TYPE_INITIALIZE(uint8); + CASE_TYPE_INITIALIZE(int8); + CASE_TYPE_INITIALIZE(uint16); + CASE_TYPE_INITIALIZE(int16); + CASE_TYPE_INITIALIZE(uint32); + CASE_TYPE_INITIALIZE(int32); + CASE_TYPE_INITIALIZE(uint64); + CASE_TYPE_INITIALIZE(int64); + CASE_TYPE_INITIALIZE(float32); + CASE_TYPE_INITIALIZE(float64); + } + return janet_wrap_abstract(view); +} + +#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])) { + TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); + return janet_wrap_abstract(view->buffer); + } + size_t size=(size_t)janet_getinteger(argv,0); + TA_Buffer * buf=(TA_Buffer *)janet_abstract(&ta_buffer_type,sizeof(TA_Buffer)); + ta_buffer_init(buf,size); + return janet_wrap_abstract(buf); +} + +static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { + janet_fixarity(argc, 1); + if (is_ta_type(argv[0])) { + TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); + return janet_wrap_number(view->size); + } + TA_Buffer * buf=(TA_Buffer *)janet_getabstract(argv,0,&ta_buffer_type); + return janet_wrap_number(buf->size); +} + +static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { + janet_fixarity(argc, 1); + if (!is_ta_type(argv[0])) + janet_panic("expected typed array"); + TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); + JanetKV * props=janet_struct_begin(6); + janet_struct_put(props,janet_ckeywordv("size"),janet_wrap_number(view->size)); + janet_struct_put(props,janet_ckeywordv("byte-offset"),janet_wrap_number((uint8_t *)(view->data)-view->buffer->data)); + janet_struct_put(props,janet_ckeywordv("stride"),janet_wrap_number(view->stride)); + janet_struct_put(props,janet_ckeywordv("type"),janet_ckeywordv(ta_type_names[view->type])); + janet_struct_put(props,janet_ckeywordv("type-size"),janet_wrap_number(ta_type_sizes[view->type])); + janet_struct_put(props,janet_ckeywordv("buffer"),janet_wrap_abstract(view->buffer)); + return janet_wrap_struct(janet_struct_end(props)); +} + + + +static const JanetReg ta_cfuns[] = { + { "tarray/new", cfun_typed_array_new, + JDOC("(tarray/new type size [stride = 1 [offset = 0 [tarray | buffer]]] )\n\n" + "Create new typed array") + }, + { "tarray/buffer", cfun_typed_array_buffer, + JDOC("(tarray/buffer (array | size) )\n\n" + "return typed array buffer or create a new buffer ") + }, + { "tarray/length", cfun_typed_array_size, + JDOC("(tarray/length (array | buffer) )\n\n" + "return typed array or buffer size ") + }, + { "tarray/properties", cfun_typed_array_properties, + JDOC("(tarray/properties array )\n\n" + "return typed array properties as a struct") + }, + + {NULL,NULL,NULL} +}; + + +/* Module entry point */ +void janet_lib_typed_array(JanetTable *env) { + janet_core_cfuns(env, NULL, ta_cfuns); +} diff --git a/src/core/util.h b/src/core/util.h index ab8d887f..42058dc2 100644 --- a/src/core/util.h +++ b/src/core/util.h @@ -89,5 +89,10 @@ void janet_lib_debug(JanetTable *env); #ifdef JANET_PEG void janet_lib_peg(JanetTable *env); #endif +#ifdef JANET_TYPED_ARRAY +void janet_lib_typed_array(JanetTable *env); +#endif + + #endif diff --git a/src/include/janet.h b/src/include/janet.h index 47387d16..cf46b8f2 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -128,6 +128,12 @@ extern "C" { #define JANET_PEG #endif +/* Enable or disable the typedarray module */ +#ifndef JANET_NO_TYPED_ARRAY +#define JANET_TYPED_ARRAY +#endif + + /* How to export symbols */ #ifndef JANET_API #ifdef JANET_WINDOWS From 60548583593606b533fd3d3289426039b76a7b24 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Thu, 21 Feb 2019 00:20:54 +0100 Subject: [PATCH 02/18] fix C format --- src/core/typedarray.c | 162 ++++++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 79 deletions(-) diff --git a/src/core/typedarray.c b/src/core/typedarray.c index c7e557bd..7ba04859 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2019 Calvin Rose +* Copyright (c) 2019 Calvin Rose & contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -55,7 +55,7 @@ typedef enum TA_Type { #define TA_COUNT_TYPES (TA_TYPE_float64 + 1) -static char * ta_type_names[]= { +static char *ta_type_names[] = { "uint8", "int8", "uint16", @@ -68,7 +68,7 @@ static char * ta_type_names[]= { "float64", }; -static size_t ta_type_sizes[]= { +static size_t ta_type_sizes[] = { sizeof(ta_uint8_t), sizeof(ta_int8_t), sizeof(ta_uint16_t), @@ -82,9 +82,9 @@ static size_t ta_type_sizes[]= { }; -static TA_Type get_ta_type_by_name(const uint8_t * name) { - size_t nt=sizeof(ta_type_names)/sizeof(char *); - for (size_t i=0; idata=(uint8_t *)calloc(size,sizeof(uint8_t)); - buf->size=size; +static TA_Buffer *ta_buffer_init(TA_Buffer *buf, size_t size) { + buf->data = (uint8_t *)calloc(size, sizeof(uint8_t)); + buf->size = size; return buf; } static int ta_buffer_gc(void *p, size_t s) { (void) s; - TA_Buffer * buf=(TA_Buffer *)p; + TA_Buffer *buf = (TA_Buffer *)p; free(buf->data); return 0; } -static const JanetAbstractType ta_buffer_type= {"ta/buffer",ta_buffer_gc,NULL,NULL,NULL}; +static const JanetAbstractType ta_buffer_type = {"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}; typedef struct { TA_Buffer *buffer; - void * data; /* pointer inside buffer->data */ + void *data; /* pointer inside buffer->data */ size_t size; size_t stride; TA_Type type; @@ -124,26 +124,26 @@ typedef struct { static int ta_mark(void *p, size_t s) { (void) s; - TA_View * view=(TA_View *)p; + TA_View *view = (TA_View *)p; janet_mark(janet_wrap_abstract(view->buffer)); return 0; } #define DEFINE_VIEW_TYPE(type) \ - typedef struct { \ - TA_Buffer * buffer; \ - ta_##type##_t * data; \ - size_t size; \ - size_t stride; \ - TA_Type type; \ + typedef struct { \ + TA_Buffer * buffer; \ + ta_##type##_t * data; \ + size_t size; \ + size_t stride; \ + TA_Type type; \ } TA_View_##type ; #define DEFINE_VIEW_GETTER(type) \ static Janet ta_get_##type(void *p, Janet key) { \ - Janet value; \ + Janet value; \ size_t index; \ - if (!janet_checkint(key)) \ + if (!janet_checkint(key)) \ janet_panic("expected integer key"); \ index = (size_t)janet_unwrap_integer(key);\ TA_View_##type * array=(TA_View_##type *)p; \ @@ -173,7 +173,7 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ #define DEFINE_VIEW_INITIALIZER(type) \ static TA_View * ta_init_##type(TA_View * view,TA_Buffer * buf,size_t size,size_t offset,size_t stride) { \ TA_View_##type * tview=(TA_View_##type *) view; \ - size_t buf_size=offset+(size-1)*(sizeof(ta_##type##_t))*stride+1; \ + size_t buf_size=offset+(size-1)*(sizeof(ta_##type##_t))*stride+1; \ if (buf==NULL) { \ buf=(TA_Buffer *)janet_abstract(&ta_buffer_type,sizeof(TA_Buffer)); \ ta_buffer_init(buf,buf_size); \ @@ -184,7 +184,7 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ tview->buffer=buf; \ tview->stride=stride; \ tview->size=size; \ - tview->data=(ta_##type##_t *)(buf->data+offset); \ + tview->data=(ta_##type##_t *)(buf->data+offset); \ tview->type=TA_TYPE_##type; \ return view; \ } @@ -214,7 +214,7 @@ BUILD_TYPE(float64) #define VIEW_ABSTRACT_DEFINE(type) {"ta/"#type,NULL,ta_mark,ta_get_##type,ta_put_##type} -static const JanetAbstractType ta_array_types[]= { +static const JanetAbstractType ta_array_types[] = { VIEW_ABSTRACT_DEFINE(uint8), VIEW_ABSTRACT_DEFINE(int8), VIEW_ABSTRACT_DEFINE(uint16), @@ -230,8 +230,8 @@ static const JanetAbstractType ta_array_types[]= { static int is_ta_type(Janet x) { if (janet_checktype(x, JANET_ABSTRACT)) { const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); - for (size_t i=0; i2) - stride=(size_t)janet_getinteger(argv,2); - if (argc>3) - offset=(size_t)janet_getinteger(argv,3); - if (argc>4) { - if (is_ta_type(argv[4])) { - TA_View *view = (TA_View *)janet_unwrap_abstract(argv[4]); - offset=(view->buffer->data - (uint8_t *)(view->data))+offset*ta_type_sizes[view->type]; - stride*=view->stride; - buffer=view->buffer; - } else { - buffer=(TA_Buffer *)janet_getabstract(argv,4,&ta_buffer_type); - } + janet_arity(argc, 2, 5); + size_t offset = 0; + size_t stride = 1; + TA_Buffer *buffer = NULL; + const uint8_t *keyw = janet_getkeyword(argv, 0); + TA_Type type = get_ta_type_by_name(keyw); + size_t size = (size_t)janet_getinteger(argv, 1); + if (argc > 2) + stride = (size_t)janet_getinteger(argv, 2); + if (argc > 3) + offset = (size_t)janet_getinteger(argv, 3); + if (argc > 4) { + if (is_ta_type(argv[4])) { + TA_View *view = (TA_View *)janet_unwrap_abstract(argv[4]); + offset = (view->buffer->data - (uint8_t *)(view->data)) + offset * ta_type_sizes[view->type]; + stride *= view->stride; + buffer = view->buffer; + } else { + buffer = (TA_Buffer *)janet_getabstract(argv, 4, &ta_buffer_type); + } } - TA_View * view=janet_abstract(&ta_array_types[type],sizeof(TA_View)); + TA_View *view = janet_abstract(&ta_array_types[type], sizeof(TA_View)); switch (type) { - CASE_TYPE_INITIALIZE(uint8); - CASE_TYPE_INITIALIZE(int8); - CASE_TYPE_INITIALIZE(uint16); - CASE_TYPE_INITIALIZE(int16); - CASE_TYPE_INITIALIZE(uint32); - CASE_TYPE_INITIALIZE(int32); - CASE_TYPE_INITIALIZE(uint64); - CASE_TYPE_INITIALIZE(int64); - CASE_TYPE_INITIALIZE(float32); - CASE_TYPE_INITIALIZE(float64); + CASE_TYPE_INITIALIZE(uint8); + CASE_TYPE_INITIALIZE(int8); + CASE_TYPE_INITIALIZE(uint16); + CASE_TYPE_INITIALIZE(int16); + CASE_TYPE_INITIALIZE(uint32); + CASE_TYPE_INITIALIZE(int32); + CASE_TYPE_INITIALIZE(uint64); + CASE_TYPE_INITIALIZE(int64); + CASE_TYPE_INITIALIZE(float32); + CASE_TYPE_INITIALIZE(float64); } return janet_wrap_abstract(view); } @@ -289,9 +289,9 @@ static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) { TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); return janet_wrap_abstract(view->buffer); } - size_t size=(size_t)janet_getinteger(argv,0); - TA_Buffer * buf=(TA_Buffer *)janet_abstract(&ta_buffer_type,sizeof(TA_Buffer)); - ta_buffer_init(buf,size); + size_t size = (size_t)janet_getinteger(argv, 0); + TA_Buffer *buf = (TA_Buffer *)janet_abstract(&ta_buffer_type, sizeof(TA_Buffer)); + ta_buffer_init(buf, size); return janet_wrap_abstract(buf); } @@ -301,46 +301,50 @@ static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); return janet_wrap_number(view->size); } - TA_Buffer * buf=(TA_Buffer *)janet_getabstract(argv,0,&ta_buffer_type); + TA_Buffer *buf = (TA_Buffer *)janet_getabstract(argv, 0, &ta_buffer_type); return janet_wrap_number(buf->size); } static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); if (!is_ta_type(argv[0])) - janet_panic("expected typed array"); + janet_panic("expected typed array"); TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); - JanetKV * props=janet_struct_begin(6); - janet_struct_put(props,janet_ckeywordv("size"),janet_wrap_number(view->size)); - janet_struct_put(props,janet_ckeywordv("byte-offset"),janet_wrap_number((uint8_t *)(view->data)-view->buffer->data)); - janet_struct_put(props,janet_ckeywordv("stride"),janet_wrap_number(view->stride)); - janet_struct_put(props,janet_ckeywordv("type"),janet_ckeywordv(ta_type_names[view->type])); - janet_struct_put(props,janet_ckeywordv("type-size"),janet_wrap_number(ta_type_sizes[view->type])); - janet_struct_put(props,janet_ckeywordv("buffer"),janet_wrap_abstract(view->buffer)); + JanetKV *props = janet_struct_begin(6); + janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number(view->size)); + janet_struct_put(props, janet_ckeywordv("byte-offset"), janet_wrap_number((uint8_t *)(view->data) - view->buffer->data)); + janet_struct_put(props, janet_ckeywordv("stride"), janet_wrap_number(view->stride)); + janet_struct_put(props, janet_ckeywordv("type"), janet_ckeywordv(ta_type_names[view->type])); + janet_struct_put(props, janet_ckeywordv("type-size"), janet_wrap_number(ta_type_sizes[view->type])); + janet_struct_put(props, janet_ckeywordv("buffer"), janet_wrap_abstract(view->buffer)); return janet_wrap_struct(janet_struct_end(props)); } static const JanetReg ta_cfuns[] = { - { "tarray/new", cfun_typed_array_new, + { + "tarray/new", cfun_typed_array_new, JDOC("(tarray/new type size [stride = 1 [offset = 0 [tarray | buffer]]] )\n\n" - "Create new typed array") + "Create new typed array") }, - { "tarray/buffer", cfun_typed_array_buffer, + { + "tarray/buffer", cfun_typed_array_buffer, JDOC("(tarray/buffer (array | size) )\n\n" - "return typed array buffer or create a new buffer ") + "return typed array buffer or create a new buffer ") }, - { "tarray/length", cfun_typed_array_size, + { + "tarray/length", cfun_typed_array_size, JDOC("(tarray/length (array | buffer) )\n\n" - "return typed array or buffer size ") + "return typed array or buffer size ") }, - { "tarray/properties", cfun_typed_array_properties, + { + "tarray/properties", cfun_typed_array_properties, JDOC("(tarray/properties array )\n\n" - "return typed array properties as a struct") + "return typed array properties as a struct") }, - {NULL,NULL,NULL} + {NULL, NULL, NULL} }; From 4d07176f1c19907fbd311dc0b0619e97dbd4f7b1 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Thu, 21 Feb 2019 20:52:39 +0100 Subject: [PATCH 03/18] 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 From 59e4b15fad4eb107037c5acaeac767d622e86ffb Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Fri, 22 Feb 2019 10:54:22 +0100 Subject: [PATCH 04/18] added some abstract type instrospection capabilities registering abstract type in vm_register table --- src/core/typedarray.c | 25 +++++++++++++++++++++++++ src/core/util.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/include/janet.h | 11 +++++++++++ 3 files changed, 77 insertions(+) diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 7ba04859..f1b48e4c 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -320,6 +320,25 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { return janet_wrap_struct(janet_struct_end(props)); } +static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { + janet_fixarity(argc, 1); + JanetAbstractTypeInfo * info; + if (janet_checktype(argv[0],JANET_KEYWORD)) { + const uint8_t *keyw = janet_unwrap_keyword(argv[0]); + info=janet_get_abstract_type_info_byname((const char*)keyw); + } else { + uint32_t tag = (uint32_t)janet_getinteger(argv, 0); + info=janet_get_abstract_type_info(tag); + } + if (info==NULL) { + return janet_wrap_nil(); + } + JanetKV *props = janet_struct_begin(2); + janet_struct_put(props, janet_ckeywordv("tag"), janet_wrap_number(info->tag)); + janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->type.name)); + return janet_wrap_struct(janet_struct_end(props)); +} + static const JanetReg ta_cfuns[] = { @@ -343,6 +362,11 @@ static const JanetReg ta_cfuns[] = { JDOC("(tarray/properties array )\n\n" "return typed array properties as a struct") }, + { + "abstract/properties", cfun_abstract_properties, + JDOC("(abstract/properties tag)\n\n" + "return abstract type properties as a struct") + }, {NULL, NULL, NULL} }; @@ -351,4 +375,5 @@ static const JanetReg ta_cfuns[] = { /* Module entry point */ void janet_lib_typed_array(JanetTable *env) { janet_core_cfuns(env, NULL, ta_cfuns); + janet_register_abstract_type(&ta_buffer_type,1111); } diff --git a/src/core/util.c b/src/core/util.c index c51a7cd5..831b8251 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -284,6 +284,47 @@ void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns) } } +static const JanetAbstractType type_info = {"core/type_info", NULL, NULL, NULL, NULL}; + +void janet_register_abstract_type(const JanetAbstractType *atype,uint32_t tag) { + JanetAbstractTypeInfo * abstract =(JanetAbstractTypeInfo *)janet_abstract(&type_info,sizeof(JanetAbstractTypeInfo)); + abstract->type=*atype; + abstract->tag=tag; + if (!(janet_checktype(janet_table_get(janet_vm_registry,janet_wrap_number(tag)),JANET_NIL)) || + !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(atype->name)),JANET_NIL))) { + janet_panic("Register abstract type fail, a type with same name or tag exist"); + } + janet_table_put(janet_vm_registry,janet_wrap_number(tag), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry,janet_ckeywordv(atype->name), janet_wrap_abstract(abstract)); +} + +JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag) { + Janet info=janet_table_get(janet_vm_registry,janet_wrap_number(tag)); + if (janet_checktype(info, JANET_NIL)) { + return NULL; + } + if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { + janet_panic("expected type_info"); + } + JanetAbstractTypeInfo * type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); + return type_info; +} + +JanetAbstractTypeInfo * janet_get_abstract_type_info_byname(const char * name) { + Janet info=janet_table_get(janet_vm_registry,janet_ckeywordv(name)); + if (janet_checktype(info, JANET_NIL)) { + return NULL; + } + if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { + janet_panic("expected type_info"); + } + JanetAbstractTypeInfo * type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); + return type_info; +} + + + + #ifndef JANET_BOOTSTRAP void janet_core_def(JanetTable *env, const char *name, Janet x, const void *p) { (void) p; diff --git a/src/include/janet.h b/src/include/janet.h index cf46b8f2..81e71ba4 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1191,6 +1191,17 @@ 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 struct { + JanetAbstractType type; + uint32_t tag; +} JanetAbstractTypeInfo; + +JANET_API void janet_register_abstract_type(const JanetAbstractType *atype,uint32_t tag); +JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag); + /*JANET_API uint32_t janet_get_abstract_type_tag(const JanetAbstractType *atype);*/ +JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info_byname(const char * name); + /***** END SECTION MAIN *****/ #ifdef __cplusplus From db9ac6dba5e2188644464f546c147f08f2d11e98 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Fri, 22 Feb 2019 15:57:48 +0100 Subject: [PATCH 05/18] marshal buffer ok --- src/core/marsh.c | 68 +++++++++++++++---------------------------- src/core/typedarray.c | 19 +++++++----- src/core/util.c | 14 +++++++++ src/include/janet.h | 24 +++++++++++++-- 4 files changed, 71 insertions(+), 54 deletions(-) diff --git a/src/core/marsh.c b/src/core/marsh.c index 6eadc2b4..2295ea2c 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -289,63 +289,43 @@ static void marshal_one_fiber(MarshalState *st, JanetFiber *fiber, int flags) { } +void janet_marshal_int(JanetMarshalContext *ctx,int32_t value) { + MarshalState *st =(MarshalState *)(ctx->m_state); + pushint(st,value); +}; -typedef struct { - JanetMarshalState *st; - int flags; -} JanetMarshalContext; - +void janet_marshal_byte(JanetMarshalContext *ctx,uint8_t value) { + MarshalState *st =(MarshalState *)(ctx->m_state); + pushbyte(st,value); +}; +void janet_marshal_bytes(JanetMarshalContext *ctx,const uint8_t *bytes, int32_t len) { + MarshalState *st =(MarshalState *)(ctx->m_state); + pushbytes(st,bytes,len); +} +void janet_marshal_janet(JanetMarshalContext *ctx,Janet x) { + MarshalState *st =(MarshalState *)(ctx->m_state); + marshal_one(st,x,ctx->flags + 1); +} #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) { + const JanetAbstractTypeInfo *info = janet_get_abstract_type_info_byname(at->name); + if (! info) return 1 ; /* unregistered type skip marshalling*/ + if (info->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); + JanetMarshalContext context={st,NULL,flags}; + pushbyte(st, LB_ABSTRACT); + pushint(st,info->tag); + info->marshal(janet_unwrap_abstract(x),&context); return 1; - } else { - return 0; } + return 0; } diff --git a/src/core/typedarray.c b/src/core/typedarray.c index e1c5c977..9c7ddf25 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -128,7 +128,11 @@ static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) { } -static const JanetAbstractType ta_buffer_type = {"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}; +static const JanetAbstractTypeInfo ta_buffer_type={ + {"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}, + 1111, + ta_buffer_marshal, +}; typedef struct { @@ -193,7 +197,7 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ TA_View_##type * tview=(TA_View_##type *) view; \ size_t buf_size=offset+(size-1)*(sizeof(ta_##type##_t))*stride+1; \ if (buf==NULL) { \ - buf=(TA_Buffer *)janet_abstract(&ta_buffer_type,sizeof(TA_Buffer)); \ + buf=(TA_Buffer *)janet_abstract(&ta_buffer_type.at,sizeof(TA_Buffer)); \ ta_buffer_init(buf,buf_size); \ } \ if (buf->sizestride; buffer = view->buffer; } else { - buffer = (TA_Buffer *)janet_getabstract(argv, 4, &ta_buffer_type); + buffer = (TA_Buffer *)janet_getabstract(argv, 4, &ta_buffer_type.at); } } TA_View *view = janet_abstract(&ta_array_types[type], sizeof(TA_View)); @@ -307,7 +311,7 @@ static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) { return janet_wrap_abstract(view->buffer); } size_t size = (size_t)janet_getinteger(argv, 0); - TA_Buffer *buf = (TA_Buffer *)janet_abstract(&ta_buffer_type, sizeof(TA_Buffer)); + TA_Buffer *buf = (TA_Buffer *)janet_abstract(&ta_buffer_type.at, sizeof(TA_Buffer)); ta_buffer_init(buf, size); return janet_wrap_abstract(buf); } @@ -318,7 +322,7 @@ static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); return janet_wrap_number(view->size); } - TA_Buffer *buf = (TA_Buffer *)janet_getabstract(argv, 0, &ta_buffer_type); + TA_Buffer *buf = (TA_Buffer *)janet_getabstract(argv, 0, &ta_buffer_type.at); return janet_wrap_number(buf->size); } @@ -337,6 +341,7 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { return janet_wrap_struct(janet_struct_end(props)); } +/* TODO for test it's not the good place for this function */ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); JanetAbstractTypeInfo * info; @@ -352,7 +357,7 @@ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { } JanetKV *props = janet_struct_begin(2); janet_struct_put(props, janet_ckeywordv("tag"), janet_wrap_number(info->tag)); - janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->type.name)); + janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->at.name)); return janet_wrap_struct(janet_struct_end(props)); } @@ -441,5 +446,5 @@ static const JanetReg ta_cfuns[] = { /* Module entry point */ void janet_lib_typed_array(JanetTable *env) { janet_core_cfuns(env, NULL, ta_cfuns); - janet_register_abstract_type(&ta_buffer_type,1111); + janet_register_abstract_type(&ta_buffer_type); } diff --git a/src/core/util.c b/src/core/util.c index 831b8251..e54bee08 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -286,6 +286,7 @@ void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns) static const JanetAbstractType type_info = {"core/type_info", NULL, NULL, NULL, NULL}; +/* void janet_register_abstract_type(const JanetAbstractType *atype,uint32_t tag) { JanetAbstractTypeInfo * abstract =(JanetAbstractTypeInfo *)janet_abstract(&type_info,sizeof(JanetAbstractTypeInfo)); abstract->type=*atype; @@ -297,6 +298,19 @@ void janet_register_abstract_type(const JanetAbstractType *atype,uint32_t tag) { janet_table_put(janet_vm_registry,janet_wrap_number(tag), janet_wrap_abstract(abstract)); janet_table_put(janet_vm_registry,janet_ckeywordv(atype->name), janet_wrap_abstract(abstract)); } +*/ + +void janet_register_abstract_type(const JanetAbstractTypeInfo * info) { + JanetAbstractTypeInfo * abstract =(JanetAbstractTypeInfo *)janet_abstract(&type_info,sizeof(JanetAbstractTypeInfo)); + memcpy(abstract,info,sizeof(JanetAbstractTypeInfo)); + if (!(janet_checktype(janet_table_get(janet_vm_registry,janet_wrap_number(info->tag)),JANET_NIL)) || + !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(info->at.name)),JANET_NIL))) { + janet_panic("Register abstract type fail, a type with same name or tag exist"); + } + janet_table_put(janet_vm_registry,janet_wrap_number(info->tag), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry,janet_ckeywordv(info->at.name), janet_wrap_abstract(abstract)); +} + JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag) { Janet info=janet_table_get(janet_vm_registry,janet_wrap_number(tag)); diff --git a/src/include/janet.h b/src/include/janet.h index 5372b3e7..d94f9cfa 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1191,17 +1191,35 @@ 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 struct { - JanetAbstractType type; - uint32_t tag; + void * m_state; /* void* to not expose MarshalState ?*/ + void * u_state; + int flags; +} JanetMarshalContext; + +void janet_marshal_int(JanetMarshalContext *ctx,int32_t value); +void janet_marshal_byte(JanetMarshalContext *ctx,uint8_t value); +void janet_marshal_bytes(JanetMarshalContext *ctx,const uint8_t *bytes, int32_t len); +void janet_marshal_janet(JanetMarshalContext *ctx,Janet x); + + +typedef struct { + const JanetAbstractType at; + const uint32_t tag; + void (* marshal)(void *p,JanetMarshalContext *ctx); } JanetAbstractTypeInfo; -JANET_API void janet_register_abstract_type(const JanetAbstractType *atype,uint32_t tag); +JANET_API void janet_register_abstract_type(const JanetAbstractTypeInfo * info); + JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag); /*JANET_API uint32_t janet_get_abstract_type_tag(const JanetAbstractType *atype);*/ JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info_byname(const char * name); + + /***** END SECTION MAIN *****/ #ifdef __cplusplus From 7cb1c7cef22c82311494c8b2dfa6f8f3172028f8 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Fri, 22 Feb 2019 17:41:27 +0100 Subject: [PATCH 06/18] added ta marshalling --- src/core/typedarray.c | 93 ++++++++++++++++++++++++++----------------- src/core/util.c | 4 +- src/include/janet.h | 2 +- 3 files changed, 60 insertions(+), 39 deletions(-) diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 9c7ddf25..a9df7162 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -127,10 +127,11 @@ static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) { janet_marshal_bytes(ctx,buf->data,buf->size); } +static const JanetAbstractType ta_buffer_type={"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}; -static const JanetAbstractTypeInfo ta_buffer_type={ - {"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}, - 1111, +static const JanetAbstractTypeInfo ta_buffer_typeinfo={ + &ta_buffer_type, + 1000, ta_buffer_marshal, }; @@ -151,14 +152,25 @@ static int ta_mark(void *p, size_t s) { return 0; } -#define DEFINE_VIEW_TYPE(type) \ +static void ta_view_marshal(void *p, JanetMarshalContext *ctx) { + TA_View *view = (TA_View *)p; + janet_marshal_int(ctx,view->size); + janet_marshal_int(ctx,view->stride); + janet_marshal_int(ctx,view->type); + janet_marshal_janet(ctx,janet_wrap_abstract(view->buffer)); +} + + + + +#define DEFINE_VIEW_TYPE(thetype) \ typedef struct { \ TA_Buffer * buffer; \ - ta_##type##_t * data; \ + ta_##thetype##_t * data; \ size_t size; \ size_t stride; \ TA_Type type; \ - } TA_View_##type ; + } TA_View_##thetype ; #define DEFINE_VIEW_GETTER(type) \ @@ -192,12 +204,12 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ array->data[index*array->stride]=(ta_##type##_t)janet_unwrap_number(value); \ } -#define DEFINE_VIEW_INITIALIZER(type) \ - static TA_View * ta_init_##type(TA_View * view,TA_Buffer * buf,size_t size,size_t offset,size_t stride) { \ - TA_View_##type * tview=(TA_View_##type *) view; \ - size_t buf_size=offset+(size-1)*(sizeof(ta_##type##_t))*stride+1; \ +#define DEFINE_VIEW_INITIALIZER(thetype) \ + static TA_View * ta_init_##thetype(TA_View * view,TA_Buffer * buf,size_t size,size_t offset,size_t stride) { \ + TA_View_##thetype * tview=(TA_View_##thetype *) view; \ + size_t buf_size=offset+(size-1)*(sizeof(ta_##thetype##_t))*stride+1; \ if (buf==NULL) { \ - buf=(TA_Buffer *)janet_abstract(&ta_buffer_type.at,sizeof(TA_Buffer)); \ + buf=(TA_Buffer *)janet_abstract(&ta_buffer_type,sizeof(TA_Buffer)); \ ta_buffer_init(buf,buf_size); \ } \ if (buf->sizebuffer=buf; \ tview->stride=stride; \ tview->size=size; \ - tview->data=(ta_##type##_t *)(buf->data+offset); \ - tview->type=TA_TYPE_##type; \ + tview->data=(ta_##thetype##_t *)(buf->data+offset); \ + tview->type=TA_TYPE_##thetype; \ return view; \ -} +}; +#define DEFINE_VIEW_ABSTRACT_TYPE(type) static const JanetAbstractType ta_view_##type##_t = {"ta/"#type,NULL,ta_mark,ta_get_##type,ta_put_##type}; + + #define BUILD_TYPE(type) \ DEFINE_VIEW_TYPE(type) \ DEFINE_VIEW_GETTER(type) \ DEFINE_VIEW_SETTER(type) \ -DEFINE_VIEW_INITIALIZER(type) +DEFINE_VIEW_INITIALIZER(type) \ +DEFINE_VIEW_ABSTRACT_TYPE(type) BUILD_TYPE(uint8) BUILD_TYPE(int8) @@ -232,34 +248,34 @@ BUILD_TYPE(float64) #undef DEFINE_VIEW_GETTER #undef DEFINE_VIEW_SETTER #undef DEFINE_VIEW_INITIALIZER +#undef DEFINE_VIEW_ABSTRACT_TYPE +#define VIEW_ABSTRACT_INFO_INIT(type,tag) {&ta_view_##type##_t,tag,ta_view_marshal} -#define VIEW_ABSTRACT_DEFINE(type) {"ta/"#type,NULL,ta_mark,ta_get_##type,ta_put_##type} - -static const JanetAbstractType ta_array_types[] = { - VIEW_ABSTRACT_DEFINE(uint8), - VIEW_ABSTRACT_DEFINE(int8), - VIEW_ABSTRACT_DEFINE(uint16), - VIEW_ABSTRACT_DEFINE(int16), - VIEW_ABSTRACT_DEFINE(uint32), - VIEW_ABSTRACT_DEFINE(int32), - VIEW_ABSTRACT_DEFINE(uint64), - VIEW_ABSTRACT_DEFINE(int64), - VIEW_ABSTRACT_DEFINE(float32), - VIEW_ABSTRACT_DEFINE(float64), +static const JanetAbstractTypeInfo ta_array_types[] = { + VIEW_ABSTRACT_INFO_INIT(uint8,1001), + VIEW_ABSTRACT_INFO_INT(int8,1002), + VIEW_ABSTRACT_INFO_INIT(uint16,1003), + VIEW_ABSTRACT_INFO_INIT(int16,1004), + VIEW_ABSTRACT_INFO_INIT(uint32,1005), + VIEW_ABSTRACT_INFO_INIT(int32,1006), + VIEW_ABSTRACT_INFO_INIT(uint64,1007), + VIEW_ABSTRACT_INFO_INIT(int64,1008), + VIEW_ABSTRACT_INFO_INIT(float32,1009), + VIEW_ABSTRACT_INFO_INIT(float64,1010), }; static int is_ta_type(Janet x) { if (janet_checktype(x, JANET_ABSTRACT)) { const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); for (size_t i = 0; i < TA_COUNT_TYPES; i++) { - if (at == ta_array_types + i) return 1; + if (at == ta_array_types[i].at) return 1; } } return 0; } -#undef VIEW_ABSTRACT_DEFINE +#undef VIEW_ABSTRACT_INFO_INIT #define CASE_TYPE_INITIALIZE(type) case TA_TYPE_##type : ta_init_##type(view,buffer,size,offset,stride); break @@ -283,10 +299,10 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { stride *= view->stride; buffer = view->buffer; } else { - buffer = (TA_Buffer *)janet_getabstract(argv, 4, &ta_buffer_type.at); + buffer = (TA_Buffer *)janet_getabstract(argv, 4,&ta_buffer_type); } } - TA_View *view = janet_abstract(&ta_array_types[type], sizeof(TA_View)); + TA_View *view = janet_abstract(ta_array_types[type].at, sizeof(TA_View)); switch (type) { CASE_TYPE_INITIALIZE(uint8); CASE_TYPE_INITIALIZE(int8); @@ -311,7 +327,7 @@ static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) { return janet_wrap_abstract(view->buffer); } size_t size = (size_t)janet_getinteger(argv, 0); - TA_Buffer *buf = (TA_Buffer *)janet_abstract(&ta_buffer_type.at, sizeof(TA_Buffer)); + TA_Buffer *buf = (TA_Buffer *)janet_abstract(&ta_buffer_type, sizeof(TA_Buffer)); ta_buffer_init(buf, size); return janet_wrap_abstract(buf); } @@ -322,7 +338,7 @@ static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); return janet_wrap_number(view->size); } - TA_Buffer *buf = (TA_Buffer *)janet_getabstract(argv, 0, &ta_buffer_type.at); + TA_Buffer *buf = (TA_Buffer *)janet_getabstract(argv, 0,&ta_buffer_type); return janet_wrap_number(buf->size); } @@ -357,7 +373,7 @@ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { } JanetKV *props = janet_struct_begin(2); janet_struct_put(props, janet_ckeywordv("tag"), janet_wrap_number(info->tag)); - janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->at.name)); + janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->at->name)); return janet_wrap_struct(janet_struct_end(props)); } @@ -443,8 +459,13 @@ static const JanetReg ta_cfuns[] = { }; + + /* Module entry point */ void janet_lib_typed_array(JanetTable *env) { janet_core_cfuns(env, NULL, ta_cfuns); - janet_register_abstract_type(&ta_buffer_type); + janet_register_abstract_type(&ta_buffer_typeinfo); + for (size_t i=0;itag)),JANET_NIL)) || - !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(info->at.name)),JANET_NIL))) { + !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(info->at->name)),JANET_NIL))) { janet_panic("Register abstract type fail, a type with same name or tag exist"); } janet_table_put(janet_vm_registry,janet_wrap_number(info->tag), janet_wrap_abstract(abstract)); - janet_table_put(janet_vm_registry,janet_ckeywordv(info->at.name), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry,janet_ckeywordv(info->at->name), janet_wrap_abstract(abstract)); } diff --git a/src/include/janet.h b/src/include/janet.h index a38faf09..985cc276 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1258,7 +1258,7 @@ void janet_marshal_janet(JanetMarshalContext *ctx,Janet x); typedef struct { - const JanetAbstractType at; + const JanetAbstractType *at; const uint32_t tag; void (* marshal)(void *p,JanetMarshalContext *ctx); } JanetAbstractTypeInfo; From 0cc6c6ff33ddce81e95b82bc56eddb176730972f Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Sat, 23 Feb 2019 16:58:47 +0100 Subject: [PATCH 07/18] implement typed array marshal/unmarshal and generic marshaling capabilities to abstract types. --- src/core/marsh.c | 65 ++++++++++++++++++++++-- src/core/typedarray.c | 113 +++++++++++++++++++++++++++++++++--------- src/core/util.c | 33 ++++++------ src/include/janet.h | 23 ++++++--- 4 files changed, 182 insertions(+), 52 deletions(-) diff --git a/src/core/marsh.c b/src/core/marsh.c index 3aa3abdc..70e8f89e 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -319,7 +319,7 @@ static int marshal_one_abstract(MarshalState *st, Janet x, int flags) { if (! info) return 1 ; /* unregistered type skip marshalling*/ if (info->marshal) { MARK_SEEN(); - JanetMarshalContext context={st,NULL,flags}; + JanetMarshalContext context={st,NULL,flags,NULL}; pushbyte(st, LB_ABSTRACT); pushint(st,info->tag); info->marshal(janet_unwrap_abstract(x),&context); @@ -576,7 +576,8 @@ enum { UMR_EXPECTED_STRING, UMR_INVALID_REFERENCE, UMR_INVALID_BYTECODE, - UMR_INVALID_FIBER + UMR_INVALID_FIBER, + UMR_INVALID_ABSTRACT } UnmarshalResult; const char *umr_strings[] = { @@ -590,7 +591,8 @@ const char *umr_strings[] = { "expected string", "invalid reference", "invalid bytecode", - "invalid fiber" + "invalid fiber", + "invalid abstract", }; /* Helper to read a 32 bit integer from an unmarshal state */ @@ -954,6 +956,59 @@ error: return NULL; } + +void janet_unmarshal_int(JanetMarshalContext *ctx,int32_t* i) { + UnmarshalState *st =(UnmarshalState *)(ctx->u_state); + *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)); +}; + + + +void janet_unmarshal_byte(JanetMarshalContext *ctx,uint8_t* b) { + *b=*(ctx->data++); +}; + +void janet_unmarshal_bytes(JanetMarshalContext *ctx,uint8_t *dest, int32_t len) { + memcpy(dest,ctx->data,len); + ctx->data+=len; +} + +void janet_unmarshal_janet(JanetMarshalContext *ctx,Janet *out) { + UnmarshalState *st =(UnmarshalState *)(ctx->u_state); + ctx->data=unmarshal_one(st,ctx->data,out,ctx->flags); +} + +static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t *data, Janet *out, int flags) { + uint32_t tag=readint(st,&data); + const JanetAbstractTypeInfo *info = janet_get_abstract_type_info(tag); + if (info==NULL) goto error; + if (info->unmarshal) { + void *p = janet_abstract(info->at,info->size); + JanetMarshalContext context={NULL,st,flags,data}; + info->unmarshal(p,&context); + *out=janet_wrap_abstract(p); + return data; + } + return 0; + error: + longjmp(st->err, UMR_INVALID_ABSTRACT); + return NULL; +} + + + + + static const uint8_t *unmarshal_one( UnmarshalState *st, const uint8_t *data, @@ -1067,6 +1122,10 @@ static const uint8_t *unmarshal_one( } return data; } + case LB_ABSTRACT: { + data++; + return unmarshal_one_abstract(st,data,out,flags); + } case LB_REFERENCE: case LB_ARRAY: case LB_TUPLE: diff --git a/src/core/typedarray.c b/src/core/typedarray.c index a9df7162..02f66153 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -80,8 +80,7 @@ static size_t ta_type_sizes[] = { sizeof(ta_float64_t), }; #define TA_COUNT_TYPES (TA_TYPE_float64 + 1) -#define TA_ATOM_MAXSIZE 8; - +#define TA_ATOM_MAXSIZE 8 #define TA_FLAG_BIG_ENDIAN 1 static TA_Type get_ta_type_by_name(const uint8_t *name) { @@ -99,7 +98,7 @@ static TA_Type get_ta_type_by_name(const uint8_t *name) { typedef struct { uint8_t *data; size_t size; - int32_t flags; + uint32_t flags; } TA_Buffer; static TA_Buffer *ta_buffer_init(TA_Buffer *buf, size_t size) { @@ -127,12 +126,25 @@ static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) { janet_marshal_bytes(ctx,buf->data,buf->size); } +static void ta_buffer_unmarshal(void *p, JanetMarshalContext *ctx) { + TA_Buffer *buf = (TA_Buffer *)p; + uint32_t size; + janet_unmarshal_uint(ctx,&size); + ta_buffer_init(buf,size); // warning if indianess <> platform ?? + janet_unmarshal_uint(ctx,&(buf->flags)); + janet_unmarshal_bytes(ctx,buf->data,buf->size); +} + + static const JanetAbstractType ta_buffer_type={"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}; static const JanetAbstractTypeInfo ta_buffer_typeinfo={ &ta_buffer_type, + sizeof(TA_Buffer), 1000, + 0, ta_buffer_marshal, + ta_buffer_unmarshal, }; @@ -154,13 +166,30 @@ static int ta_mark(void *p, size_t s) { static void ta_view_marshal(void *p, JanetMarshalContext *ctx) { TA_View *view = (TA_View *)p; + size_t offset = (view->buffer->data - (uint8_t *)(view->data)); janet_marshal_int(ctx,view->size); janet_marshal_int(ctx,view->stride); janet_marshal_int(ctx,view->type); + janet_marshal_int(ctx,offset); janet_marshal_janet(ctx,janet_wrap_abstract(view->buffer)); } +static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) { + TA_View *view = (TA_View *)p; + size_t offset; + Janet buffer; + janet_unmarshal_size(ctx,&(view->size)); + janet_unmarshal_size(ctx,&(view->stride)); + janet_unmarshal_uint(ctx,&(view->type)); + janet_unmarshal_size(ctx,&offset); + janet_unmarshal_janet(ctx,&buffer); + view->buffer=(TA_Buffer *)janet_unwrap_abstract(buffer); + view->data=view->buffer->data+offset; +} + + + #define DEFINE_VIEW_TYPE(thetype) \ @@ -250,11 +279,11 @@ BUILD_TYPE(float64) #undef DEFINE_VIEW_INITIALIZER #undef DEFINE_VIEW_ABSTRACT_TYPE -#define VIEW_ABSTRACT_INFO_INIT(type,tag) {&ta_view_##type##_t,tag,ta_view_marshal} +#define VIEW_ABSTRACT_INFO_INIT(type,salt) {&ta_view_##type##_t,sizeof(TA_View),salt,0,ta_view_marshal,ta_view_unmarshal} static const JanetAbstractTypeInfo ta_array_types[] = { VIEW_ABSTRACT_INFO_INIT(uint8,1001), - VIEW_ABSTRACT_INFO_INT(int8,1002), + VIEW_ABSTRACT_INFO_INIT(int8,1002), VIEW_ABSTRACT_INFO_INIT(uint16,1003), VIEW_ABSTRACT_INFO_INIT(int16,1004), VIEW_ABSTRACT_INFO_INIT(uint32,1005), @@ -371,28 +400,41 @@ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { if (info==NULL) { return janet_wrap_nil(); } - JanetKV *props = janet_struct_begin(2); + JanetKV *props = janet_struct_begin(5); janet_struct_put(props, janet_ckeywordv("tag"), janet_wrap_number(info->tag)); + janet_struct_put(props, janet_ckeywordv("salt"), janet_wrap_number(info->salt)); janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->at->name)); + janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number(info->size)); + janet_struct_put(props, janet_ckeywordv("marshal"), janet_wrap_boolean((info->marshal !=NULL) && (info->unmarshal!=NULL))); return janet_wrap_struct(janet_struct_end(props)); } -/* + static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { - janet_fixarity(argc, 4); + janet_arity(argc, 4, 5); 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 count=(argc == 5)? (size_t)janet_getinteger(argv, 4) : 1; 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); + size_t step_src=src->stride*src_atom_size; + size_t step_dst=dst->stride*dst_atom_size; + size_t pos_src=((uint8_t *)(src->data) - src->buffer->data)+(index_src*step_src); + size_t pos_dst=((uint8_t *)(dst->data) - dst->buffer->data)+(index_dst*step_dst); + uint8_t * ps=src->buffer->data+pos_src,* 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)) { + for (size_t i=0;itype]; 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); + size_t step_src=src->stride*src_atom_size; + size_t step_dst=dst->stride*dst_atom_size; + size_t pos_src=((uint8_t *)(src->data) - src->buffer->data)+(index_src*step_src); + size_t pos_dst=((uint8_t *)(dst->data) - 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+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); + 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)) { + for (size_t i=0;itype=*atype; - abstract->tag=tag; - if (!(janet_checktype(janet_table_get(janet_vm_registry,janet_wrap_number(tag)),JANET_NIL)) || - !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(atype->name)),JANET_NIL))) { - janet_panic("Register abstract type fail, a type with same name or tag exist"); - } - janet_table_put(janet_vm_registry,janet_wrap_number(tag), janet_wrap_abstract(abstract)); - janet_table_put(janet_vm_registry,janet_ckeywordv(atype->name), janet_wrap_abstract(abstract)); +static uint32_t janet_abstract_type_gentag(const char * name,uint32_t salt) { + /* something smarter should propably done here ? */ + int32_t len = strlen(name); + const char *end = name + len; + uint32_t hash = 5381+salt; + while (name < end) + hash = (hash << 5) + hash + *name++; + return (int32_t) hash; } -*/ void janet_register_abstract_type(const JanetAbstractTypeInfo * info) { JanetAbstractTypeInfo * abstract =(JanetAbstractTypeInfo *)janet_abstract(&type_info,sizeof(JanetAbstractTypeInfo)); - memcpy(abstract,info,sizeof(JanetAbstractTypeInfo)); - if (!(janet_checktype(janet_table_get(janet_vm_registry,janet_wrap_number(info->tag)),JANET_NIL)) || - !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(info->at->name)),JANET_NIL))) { + memcpy(abstract,info,sizeof(JanetAbstractTypeInfo)); + abstract->tag=janet_abstract_type_gentag(info->at->name,info->salt); + if (!(janet_checktype(janet_table_get(janet_vm_registry,janet_wrap_number(abstract->tag)),JANET_NIL)) || + !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(abstract->at->name)),JANET_NIL))) { janet_panic("Register abstract type fail, a type with same name or tag exist"); } - janet_table_put(janet_vm_registry,janet_wrap_number(info->tag), janet_wrap_abstract(abstract)); - janet_table_put(janet_vm_registry,janet_ckeywordv(info->at->name), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry,janet_wrap_number(abstract->tag), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry,janet_ckeywordv(abstract->at->name), janet_wrap_abstract(abstract)); } diff --git a/src/include/janet.h b/src/include/janet.h index 985cc276..c2ecd015 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1243,30 +1243,37 @@ 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 struct { void * m_state; /* void* to not expose MarshalState ?*/ void * u_state; int flags; + const uint8_t * data; } JanetMarshalContext; -void janet_marshal_int(JanetMarshalContext *ctx,int32_t value); -void janet_marshal_byte(JanetMarshalContext *ctx,uint8_t value); -void janet_marshal_bytes(JanetMarshalContext *ctx,const uint8_t *bytes, int32_t len); -void janet_marshal_janet(JanetMarshalContext *ctx,Janet x); +JANET_API void janet_marshal_int(JanetMarshalContext *ctx,int32_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); +JANET_API void janet_unmarshal_janet(JanetMarshalContext *ctx,Janet *out); typedef struct { const JanetAbstractType *at; - const uint32_t tag; + size_t size; /* abstract type size */ + const uint32_t salt; /* salt */ + uint32_t tag; /* unique tag computed by janet (hash of name and salt) */ void (* marshal)(void *p,JanetMarshalContext *ctx); + void (* unmarshal)(void *p,JanetMarshalContext *ctx); } JanetAbstractTypeInfo; JANET_API void janet_register_abstract_type(const JanetAbstractTypeInfo * info); JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag); - /*JANET_API uint32_t janet_get_abstract_type_tag(const JanetAbstractType *atype);*/ JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info_byname(const char * name); From 2becebce92fe49806022a9cfc1e3f9e9b4bb8393 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Sat, 23 Feb 2019 17:13:43 +0100 Subject: [PATCH 08/18] fix C source format --- src/core/abstract.c | 2 +- src/core/marsh.c | 124 +++++++++++------------ src/core/typedarray.c | 224 +++++++++++++++++++++--------------------- src/core/util.c | 78 +++++++-------- src/include/janet.h | 50 +++++----- 5 files changed, 238 insertions(+), 240 deletions(-) diff --git a/src/core/abstract.c b/src/core/abstract.c index 66bff463..1132c470 100644 --- a/src/core/abstract.c +++ b/src/core/abstract.c @@ -28,7 +28,7 @@ /* Create new userdata */ void *janet_abstract(const JanetAbstractType *atype, size_t size) { JanetAbstractHead *header = janet_gcalloc(JANET_MEMORY_ABSTRACT, - sizeof(JanetAbstractHead) + size); + sizeof(JanetAbstractHead) + size); header->size = size; header->type = atype; return (void *) & (header->data); diff --git a/src/core/marsh.c b/src/core/marsh.c index 70e8f89e..bcdf4965 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -289,24 +289,24 @@ static void marshal_one_fiber(MarshalState *st, JanetFiber *fiber, int flags) { } -void janet_marshal_int(JanetMarshalContext *ctx,int32_t value) { - MarshalState *st =(MarshalState *)(ctx->m_state); - pushint(st,value); +void janet_marshal_int(JanetMarshalContext *ctx, int32_t value) { + MarshalState *st = (MarshalState *)(ctx->m_state); + pushint(st, value); }; -void janet_marshal_byte(JanetMarshalContext *ctx,uint8_t value) { - MarshalState *st =(MarshalState *)(ctx->m_state); - pushbyte(st,value); +void janet_marshal_byte(JanetMarshalContext *ctx, uint8_t value) { + MarshalState *st = (MarshalState *)(ctx->m_state); + pushbyte(st, value); }; -void janet_marshal_bytes(JanetMarshalContext *ctx,const uint8_t *bytes, int32_t len) { - MarshalState *st =(MarshalState *)(ctx->m_state); - pushbytes(st,bytes,len); +void janet_marshal_bytes(JanetMarshalContext *ctx, const uint8_t *bytes, int32_t len) { + MarshalState *st = (MarshalState *)(ctx->m_state); + pushbytes(st, bytes, len); } -void janet_marshal_janet(JanetMarshalContext *ctx,Janet x) { - MarshalState *st =(MarshalState *)(ctx->m_state); - marshal_one(st,x,ctx->flags + 1); +void janet_marshal_janet(JanetMarshalContext *ctx, Janet x) { + MarshalState *st = (MarshalState *)(ctx->m_state); + marshal_one(st, x, ctx->flags + 1); } #define MARK_SEEN() \ @@ -314,18 +314,18 @@ void janet_marshal_janet(JanetMarshalContext *ctx,Janet x) { static int marshal_one_abstract(MarshalState *st, Janet x, int flags) { - const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); - const JanetAbstractTypeInfo *info = janet_get_abstract_type_info_byname(at->name); - if (! info) return 1 ; /* unregistered type skip marshalling*/ - if (info->marshal) { - MARK_SEEN(); - JanetMarshalContext context={st,NULL,flags,NULL}; - pushbyte(st, LB_ABSTRACT); - pushint(st,info->tag); - info->marshal(janet_unwrap_abstract(x),&context); - return 1; - } - return 0; + const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); + const JanetAbstractTypeInfo *info = janet_get_abstract_type_info_byname(at->name); + if (! info) return 1 ; /* unregistered type skip marshalling*/ + if (info->marshal) { + MARK_SEEN(); + JanetMarshalContext context = {st, NULL, flags, NULL}; + pushbyte(st, LB_ABSTRACT); + pushint(st, info->tag); + info->marshal(janet_unwrap_abstract(x), &context); + return 1; + } + return 0; } @@ -488,12 +488,12 @@ static void marshal_one(MarshalState *st, Janet x, int flags) { } goto done; case JANET_ABSTRACT: { - if (marshal_one_abstract(st,x,flags)) { - goto done; - } else { - goto noregval; - } - } + if (marshal_one_abstract(st, x, flags)) { + goto done; + } else { + goto noregval; + } + } case JANET_CFUNCTION: goto noregval; case JANET_FUNCTION: { @@ -957,50 +957,50 @@ error: } -void janet_unmarshal_int(JanetMarshalContext *ctx,int32_t* i) { - UnmarshalState *st =(UnmarshalState *)(ctx->u_state); - *i=readint(st,&(ctx->data)); +void janet_unmarshal_int(JanetMarshalContext *ctx, int32_t *i) { + UnmarshalState *st = (UnmarshalState *)(ctx->u_state); + *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_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)); +void janet_unmarshal_size(JanetMarshalContext *ctx, size_t *i) { + UnmarshalState *st = (UnmarshalState *)(ctx->u_state); + *i = (size_t)readint(st, &(ctx->data)); }; -void janet_unmarshal_byte(JanetMarshalContext *ctx,uint8_t* b) { - *b=*(ctx->data++); +void janet_unmarshal_byte(JanetMarshalContext *ctx, uint8_t *b) { + *b = *(ctx->data++); }; -void janet_unmarshal_bytes(JanetMarshalContext *ctx,uint8_t *dest, int32_t len) { - memcpy(dest,ctx->data,len); - ctx->data+=len; +void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, int32_t len) { + memcpy(dest, ctx->data, len); + ctx->data += len; } -void janet_unmarshal_janet(JanetMarshalContext *ctx,Janet *out) { - UnmarshalState *st =(UnmarshalState *)(ctx->u_state); - ctx->data=unmarshal_one(st,ctx->data,out,ctx->flags); +void janet_unmarshal_janet(JanetMarshalContext *ctx, Janet *out) { + UnmarshalState *st = (UnmarshalState *)(ctx->u_state); + ctx->data = unmarshal_one(st, ctx->data, out, ctx->flags); } static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t *data, Janet *out, int flags) { - uint32_t tag=readint(st,&data); - const JanetAbstractTypeInfo *info = janet_get_abstract_type_info(tag); - if (info==NULL) goto error; - if (info->unmarshal) { - void *p = janet_abstract(info->at,info->size); - JanetMarshalContext context={NULL,st,flags,data}; - info->unmarshal(p,&context); - *out=janet_wrap_abstract(p); - return data; - } - return 0; - error: + uint32_t tag = readint(st, &data); + const JanetAbstractTypeInfo *info = janet_get_abstract_type_info(tag); + if (info == NULL) goto error; + if (info->unmarshal) { + void *p = janet_abstract(info->at, info->size); + JanetMarshalContext context = {NULL, st, flags, data}; + info->unmarshal(p, &context); + *out = janet_wrap_abstract(p); + return data; + } + return 0; +error: longjmp(st->err, UMR_INVALID_ABSTRACT); return NULL; } @@ -1123,9 +1123,9 @@ static const uint8_t *unmarshal_one( return data; } case LB_ABSTRACT: { - data++; - return unmarshal_one_abstract(st,data,out,flags); - } + data++; + return unmarshal_one_abstract(st, data, out, flags); + } case LB_REFERENCE: case LB_ARRAY: case LB_TUPLE: diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 02f66153..20d25b7d 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -120,31 +120,31 @@ static int ta_buffer_gc(void *p, size_t s) { } 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); + 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 void ta_buffer_unmarshal(void *p, JanetMarshalContext *ctx) { - TA_Buffer *buf = (TA_Buffer *)p; - uint32_t size; - janet_unmarshal_uint(ctx,&size); - ta_buffer_init(buf,size); // warning if indianess <> platform ?? - janet_unmarshal_uint(ctx,&(buf->flags)); - janet_unmarshal_bytes(ctx,buf->data,buf->size); + TA_Buffer *buf = (TA_Buffer *)p; + uint32_t size; + janet_unmarshal_uint(ctx, &size); + ta_buffer_init(buf, size); // warning if indianess <> platform ?? + janet_unmarshal_uint(ctx, &(buf->flags)); + janet_unmarshal_bytes(ctx, buf->data, buf->size); } -static const JanetAbstractType ta_buffer_type={"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}; +static const JanetAbstractType ta_buffer_type = {"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}; -static const JanetAbstractTypeInfo ta_buffer_typeinfo={ - &ta_buffer_type, - sizeof(TA_Buffer), - 1000, - 0, - ta_buffer_marshal, - ta_buffer_unmarshal, +static const JanetAbstractTypeInfo ta_buffer_typeinfo = { + &ta_buffer_type, + sizeof(TA_Buffer), + 1000, + 0, + ta_buffer_marshal, + ta_buffer_unmarshal, }; @@ -165,27 +165,27 @@ static int ta_mark(void *p, size_t s) { } static void ta_view_marshal(void *p, JanetMarshalContext *ctx) { - TA_View *view = (TA_View *)p; - size_t offset = (view->buffer->data - (uint8_t *)(view->data)); - janet_marshal_int(ctx,view->size); - janet_marshal_int(ctx,view->stride); - janet_marshal_int(ctx,view->type); - janet_marshal_int(ctx,offset); - janet_marshal_janet(ctx,janet_wrap_abstract(view->buffer)); + TA_View *view = (TA_View *)p; + size_t offset = (view->buffer->data - (uint8_t *)(view->data)); + janet_marshal_int(ctx, view->size); + janet_marshal_int(ctx, view->stride); + janet_marshal_int(ctx, view->type); + janet_marshal_int(ctx, offset); + janet_marshal_janet(ctx, janet_wrap_abstract(view->buffer)); } static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) { - TA_View *view = (TA_View *)p; - size_t offset; - Janet buffer; - janet_unmarshal_size(ctx,&(view->size)); - janet_unmarshal_size(ctx,&(view->stride)); - janet_unmarshal_uint(ctx,&(view->type)); - janet_unmarshal_size(ctx,&offset); - janet_unmarshal_janet(ctx,&buffer); - view->buffer=(TA_Buffer *)janet_unwrap_abstract(buffer); - view->data=view->buffer->data+offset; + TA_View *view = (TA_View *)p; + size_t offset; + Janet buffer; + janet_unmarshal_size(ctx, &(view->size)); + janet_unmarshal_size(ctx, &(view->stride)); + janet_unmarshal_uint(ctx, &(view->type)); + janet_unmarshal_size(ctx, &offset); + janet_unmarshal_janet(ctx, &buffer); + view->buffer = (TA_Buffer *)janet_unwrap_abstract(buffer); + view->data = view->buffer->data + offset; } @@ -254,13 +254,13 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ #define DEFINE_VIEW_ABSTRACT_TYPE(type) static const JanetAbstractType ta_view_##type##_t = {"ta/"#type,NULL,ta_mark,ta_get_##type,ta_put_##type}; - + #define BUILD_TYPE(type) \ DEFINE_VIEW_TYPE(type) \ DEFINE_VIEW_GETTER(type) \ DEFINE_VIEW_SETTER(type) \ DEFINE_VIEW_INITIALIZER(type) \ -DEFINE_VIEW_ABSTRACT_TYPE(type) +DEFINE_VIEW_ABSTRACT_TYPE(type) BUILD_TYPE(uint8) BUILD_TYPE(int8) @@ -282,16 +282,16 @@ BUILD_TYPE(float64) #define VIEW_ABSTRACT_INFO_INIT(type,salt) {&ta_view_##type##_t,sizeof(TA_View),salt,0,ta_view_marshal,ta_view_unmarshal} static const JanetAbstractTypeInfo ta_array_types[] = { - VIEW_ABSTRACT_INFO_INIT(uint8,1001), - VIEW_ABSTRACT_INFO_INIT(int8,1002), - VIEW_ABSTRACT_INFO_INIT(uint16,1003), - VIEW_ABSTRACT_INFO_INIT(int16,1004), - VIEW_ABSTRACT_INFO_INIT(uint32,1005), - VIEW_ABSTRACT_INFO_INIT(int32,1006), - VIEW_ABSTRACT_INFO_INIT(uint64,1007), - VIEW_ABSTRACT_INFO_INIT(int64,1008), - VIEW_ABSTRACT_INFO_INIT(float32,1009), - VIEW_ABSTRACT_INFO_INIT(float64,1010), + VIEW_ABSTRACT_INFO_INIT(uint8, 1001), + VIEW_ABSTRACT_INFO_INIT(int8, 1002), + VIEW_ABSTRACT_INFO_INIT(uint16, 1003), + VIEW_ABSTRACT_INFO_INIT(int16, 1004), + VIEW_ABSTRACT_INFO_INIT(uint32, 1005), + VIEW_ABSTRACT_INFO_INIT(int32, 1006), + VIEW_ABSTRACT_INFO_INIT(uint64, 1007), + VIEW_ABSTRACT_INFO_INIT(int64, 1008), + VIEW_ABSTRACT_INFO_INIT(float32, 1009), + VIEW_ABSTRACT_INFO_INIT(float64, 1010), }; static int is_ta_type(Janet x) { @@ -328,7 +328,7 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { stride *= view->stride; buffer = view->buffer; } else { - buffer = (TA_Buffer *)janet_getabstract(argv, 4,&ta_buffer_type); + buffer = (TA_Buffer *)janet_getabstract(argv, 4, &ta_buffer_type); } } TA_View *view = janet_abstract(ta_array_types[type].at, sizeof(TA_View)); @@ -367,7 +367,7 @@ static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); return janet_wrap_number(view->size); } - TA_Buffer *buf = (TA_Buffer *)janet_getabstract(argv, 0,&ta_buffer_type); + TA_Buffer *buf = (TA_Buffer *)janet_getabstract(argv, 0, &ta_buffer_type); return janet_wrap_number(buf->size); } @@ -389,23 +389,23 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { /* TODO for test it's not the good place for this function */ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - JanetAbstractTypeInfo * info; - if (janet_checktype(argv[0],JANET_KEYWORD)) { - const uint8_t *keyw = janet_unwrap_keyword(argv[0]); - info=janet_get_abstract_type_info_byname((const char*)keyw); + JanetAbstractTypeInfo *info; + if (janet_checktype(argv[0], JANET_KEYWORD)) { + const uint8_t *keyw = janet_unwrap_keyword(argv[0]); + info = janet_get_abstract_type_info_byname((const char *)keyw); } else { - uint32_t tag = (uint32_t)janet_getinteger(argv, 0); - info=janet_get_abstract_type_info(tag); + uint32_t tag = (uint32_t)janet_getinteger(argv, 0); + info = janet_get_abstract_type_info(tag); } - if (info==NULL) { - return janet_wrap_nil(); + if (info == NULL) { + return janet_wrap_nil(); } JanetKV *props = janet_struct_begin(5); janet_struct_put(props, janet_ckeywordv("tag"), janet_wrap_number(info->tag)); janet_struct_put(props, janet_ckeywordv("salt"), janet_wrap_number(info->salt)); janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->at->name)); janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number(info->size)); - janet_struct_put(props, janet_ckeywordv("marshal"), janet_wrap_boolean((info->marshal !=NULL) && (info->unmarshal!=NULL))); + janet_struct_put(props, janet_ckeywordv("marshal"), janet_wrap_boolean((info->marshal != NULL) && (info->unmarshal != NULL))); return janet_wrap_struct(janet_struct_end(props)); } @@ -413,30 +413,29 @@ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { janet_arity(argc, 4, 5); 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 count=(argc == 5)? (size_t)janet_getinteger(argv, 4) : 1; - size_t src_atom_size=ta_type_sizes[src->type]; - size_t dst_atom_size=ta_type_sizes[dst->type]; - size_t step_src=src->stride*src_atom_size; - size_t step_dst=dst->stride*dst_atom_size; - size_t pos_src=((uint8_t *)(src->data) - src->buffer->data)+(index_src*step_src); - size_t pos_dst=((uint8_t *)(dst->data) - dst->buffer->data)+(index_dst*step_dst); - uint8_t * ps=src->buffer->data+pos_src,* 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)) { - for (size_t i=0;itype]; + size_t dst_atom_size = ta_type_sizes[dst->type]; + size_t step_src = src->stride * src_atom_size; + size_t step_dst = dst->stride * dst_atom_size; + size_t pos_src = ((uint8_t *)(src->data) - src->buffer->data) + (index_src * step_src); + size_t pos_dst = ((uint8_t *)(dst->data) - dst->buffer->data) + (index_dst * step_dst); + uint8_t *ps = src->buffer->data + pos_src, * 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)) { + for (size_t i = 0; i < count; i++) { + memmove(pd, ps, src_atom_size); + pd += step_dst; + ps += step_src; + } + } else + janet_panic("typed array copy out of bound"); } else { - janet_panic("expected typed array"); + janet_panic("expected typed array"); } return janet_wrap_nil(); } @@ -444,33 +443,32 @@ static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) { janet_arity(argc, 4, 5); 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 count=(argc == 5)? (size_t)janet_getinteger(argv, 4) : 1; - size_t src_atom_size=ta_type_sizes[src->type]; - size_t dst_atom_size=ta_type_sizes[dst->type]; - size_t step_src=src->stride*src_atom_size; - size_t step_dst=dst->stride*dst_atom_size; - size_t pos_src=((uint8_t *)(src->data) - src->buffer->data)+(index_src*step_src); - size_t pos_dst=((uint8_t *)(dst->data) - 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)) { - for (size_t i=0;itype]; + size_t dst_atom_size = ta_type_sizes[dst->type]; + size_t step_src = src->stride * src_atom_size; + size_t step_dst = dst->stride * dst_atom_size; + size_t pos_src = ((uint8_t *)(src->data) - src->buffer->data) + (index_src * step_src); + size_t pos_dst = ((uint8_t *)(dst->data) - 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)) { + for (size_t i = 0; i < count; i++) { + memcpy(temp, ps, src_atom_size); + memcpy(ps, pd, src_atom_size); + memcpy(pd, temp, src_atom_size); + pd += step_dst; + ps += step_src; + } + } else + janet_panic("typed array swap out of bound"); } else { - janet_panic("expected typed array"); + janet_panic("expected typed array"); } return janet_wrap_nil(); } @@ -503,16 +501,16 @@ static const JanetReg ta_cfuns[] = { JDOC("(tarray/copy-bytes src sindex dst dindex [count=1])\n\n" "copy count elements of src array from index sindex \n" "to dst array at position dindex \n" - "memory can overlap" - ) + "memory can overlap" + ) }, { "tarray/swap-bytes", cfun_typed_array_swap_bytes, JDOC("(tarray/swap-bytes src sindex dst dindex [count=1])\n\n" "swap count elements between src array from index sindex \n" "and dst array at position dindex \n" - "memory can overlap" - ) + "memory can overlap" + ) }, { "abstract/properties", cfun_abstract_properties, @@ -530,7 +528,7 @@ static const JanetReg ta_cfuns[] = { void janet_lib_typed_array(JanetTable *env) { janet_core_cfuns(env, NULL, ta_cfuns); janet_register_abstract_type(&ta_buffer_typeinfo); - for (size_t i=0;itag=janet_abstract_type_gentag(info->at->name,info->salt); - if (!(janet_checktype(janet_table_get(janet_vm_registry,janet_wrap_number(abstract->tag)),JANET_NIL)) || - !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(abstract->at->name)),JANET_NIL))) { - janet_panic("Register abstract type fail, a type with same name or tag exist"); - } - janet_table_put(janet_vm_registry,janet_wrap_number(abstract->tag), janet_wrap_abstract(abstract)); - janet_table_put(janet_vm_registry,janet_ckeywordv(abstract->at->name), janet_wrap_abstract(abstract)); +void janet_register_abstract_type(const JanetAbstractTypeInfo *info) { + JanetAbstractTypeInfo *abstract = (JanetAbstractTypeInfo *)janet_abstract(&type_info, sizeof(JanetAbstractTypeInfo)); + memcpy(abstract, info, sizeof(JanetAbstractTypeInfo)); + abstract->tag = janet_abstract_type_gentag(info->at->name, info->salt); + if (!(janet_checktype(janet_table_get(janet_vm_registry, janet_wrap_number(abstract->tag)), JANET_NIL)) || + !(janet_checktype(janet_table_get(janet_vm_registry, janet_ckeywordv(abstract->at->name)), JANET_NIL))) { + janet_panic("Register abstract type fail, a type with same name or tag exist"); + } + janet_table_put(janet_vm_registry, janet_wrap_number(abstract->tag), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry, janet_ckeywordv(abstract->at->name), janet_wrap_abstract(abstract)); } -JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag) { - Janet info=janet_table_get(janet_vm_registry,janet_wrap_number(tag)); - if (janet_checktype(info, JANET_NIL)) { - return NULL; - } - if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { - janet_panic("expected type_info"); - } - JanetAbstractTypeInfo * type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); - return type_info; +JanetAbstractTypeInfo *janet_get_abstract_type_info(uint32_t tag) { + Janet info = janet_table_get(janet_vm_registry, janet_wrap_number(tag)); + if (janet_checktype(info, JANET_NIL)) { + return NULL; + } + if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { + janet_panic("expected type_info"); + } + JanetAbstractTypeInfo *type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); + return type_info; } -JanetAbstractTypeInfo * janet_get_abstract_type_info_byname(const char * name) { - Janet info=janet_table_get(janet_vm_registry,janet_ckeywordv(name)); - if (janet_checktype(info, JANET_NIL)) { - return NULL; - } - if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { - janet_panic("expected type_info"); - } - JanetAbstractTypeInfo * type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); - return type_info; +JanetAbstractTypeInfo *janet_get_abstract_type_info_byname(const char *name) { + Janet info = janet_table_get(janet_vm_registry, janet_ckeywordv(name)); + if (janet_checktype(info, JANET_NIL)) { + return NULL; + } + if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { + janet_panic("expected type_info"); + } + JanetAbstractTypeInfo *type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); + return type_info; } - + #ifndef JANET_BOOTSTRAP diff --git a/src/include/janet.h b/src/include/janet.h index c2ecd015..ab8bbb17 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1244,41 +1244,41 @@ JANET_API int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t lengt JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which); typedef struct { - void * m_state; /* void* to not expose MarshalState ?*/ - void * u_state; - int flags; - const uint8_t * data; + void *m_state; /* void* to not expose MarshalState ?*/ + void *u_state; + int flags; + const uint8_t *data; } JanetMarshalContext; -JANET_API void janet_marshal_int(JanetMarshalContext *ctx,int32_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_marshal_int(JanetMarshalContext *ctx, int32_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); -JANET_API void janet_unmarshal_janet(JanetMarshalContext *ctx,Janet *out); +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); +JANET_API void janet_unmarshal_janet(JanetMarshalContext *ctx, Janet *out); typedef struct { - const JanetAbstractType *at; - size_t size; /* abstract type size */ - const uint32_t salt; /* salt */ - uint32_t tag; /* unique tag computed by janet (hash of name and salt) */ - void (* marshal)(void *p,JanetMarshalContext *ctx); - void (* unmarshal)(void *p,JanetMarshalContext *ctx); + const JanetAbstractType *at; + size_t size; /* abstract type size */ + const uint32_t salt; /* salt */ + uint32_t tag; /* unique tag computed by janet (hash of name and salt) */ + void (* marshal)(void *p, JanetMarshalContext *ctx); + void (* unmarshal)(void *p, JanetMarshalContext *ctx); } JanetAbstractTypeInfo; -JANET_API void janet_register_abstract_type(const JanetAbstractTypeInfo * info); +JANET_API void janet_register_abstract_type(const JanetAbstractTypeInfo *info); + +JANET_API JanetAbstractTypeInfo *janet_get_abstract_type_info(uint32_t tag); +JANET_API JanetAbstractTypeInfo *janet_get_abstract_type_info_byname(const char *name); + -JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag); -JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info_byname(const char * name); - - /***** END SECTION MAIN *****/ #ifdef __cplusplus From db64a682befbd6515f1844e876fc245fca92acbe Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Sat, 23 Feb 2019 17:54:09 +0100 Subject: [PATCH 09/18] fix incompatibilities with upstream/master changes in marsh.c --- src/core/marsh.c | 45 ++++++--------------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/src/core/marsh.c b/src/core/marsh.c index 99bbee8c..58a598f9 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -291,19 +291,18 @@ void janet_marshal_janet(JanetMarshalContext *ctx, Janet x) { janet_table_put(&st->seen, x, janet_wrap_integer(st->nextid++)) -static int marshal_one_abstract(MarshalState *st, Janet x, int flags) { +static void marshal_one_abstract(MarshalState *st, Janet x, int flags) { const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); const JanetAbstractTypeInfo *info = janet_get_abstract_type_info_byname(at->name); - if (! info) return 1 ; /* unregistered type skip marshalling*/ - if (info->marshal) { + if (info && info->marshal) { MARK_SEEN(); JanetMarshalContext context = {st, NULL, flags, NULL}; pushbyte(st, LB_ABSTRACT); pushint(st, info->tag); info->marshal(janet_unwrap_abstract(x), &context); - return 1; + } else { + janet_panicf("try to marshal unregistered absttact type, cannot marshal %p", x); } - return 0; } @@ -463,9 +462,8 @@ static void marshal_one(MarshalState *st, Janet x, int flags) { return; } case JANET_ABSTRACT: { - if (marshal_one_abstract(st, x, flags)) { - return; - } + marshal_one_abstract(st, x, flags); + return; } case JANET_FUNCTION: { pushbyte(st, LB_FUNCTION); @@ -520,41 +518,10 @@ typedef struct { const uint8_t *end; } UnmarshalState; -<<<<<<< HEAD -enum { - UMR_OK, - UMR_STACKOVERFLOW, - UMR_EOS, - UMR_UNKNOWN, - UMR_EXPECTED_INTEGER, - UMR_EXPECTED_TABLE, - UMR_EXPECTED_FIBER, - UMR_EXPECTED_STRING, - UMR_INVALID_REFERENCE, - UMR_INVALID_BYTECODE, - UMR_INVALID_FIBER, - UMR_INVALID_ABSTRACT -} UnmarshalResult; -const char *umr_strings[] = { - "", - "stack overflow", - "unexpected end of source", - "unmarshal error", - "expected integer", - "expected table", - "expected fiber", - "expected string", - "invalid reference", - "invalid bytecode", - "invalid fiber", - "invalid abstract", -}; -======= #define MARSH_EOS(st, data) do { \ if ((data) >= (st)->end) janet_panic("unexpected end of source");\ } while (0) ->>>>>>> upstream/master /* Helper to read a 32 bit integer from an unmarshal state */ static int32_t readint(UnmarshalState *st, const uint8_t **atdata) { From af48912f11962f1b717360911884b80e5fcab990 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Sun, 24 Feb 2019 02:02:54 +0100 Subject: [PATCH 10/18] Simplify Abstract type introspection --- src/core/io.c | 3 ++ src/core/marsh.c | 31 ++++++++-------- src/core/parse.c | 3 ++ src/core/peg.c | 3 ++ src/core/typedarray.c | 83 ++++++++++++++++++++++++------------------- src/core/util.c | 62 ++++++++++++++------------------ src/include/janet.h | 34 +++++++++--------- 7 files changed, 115 insertions(+), 104 deletions(-) diff --git a/src/core/io.c b/src/core/io.c index 44904517..e4b5b28c 100644 --- a/src/core/io.c +++ b/src/core/io.c @@ -53,9 +53,12 @@ static Janet io_file_get(void *p, Janet); JanetAbstractType cfun_io_filetype = { "core/file", + 0, cfun_io_gc, NULL, io_file_get, + NULL, + NULL, NULL }; diff --git a/src/core/marsh.c b/src/core/marsh.c index 58a598f9..b32129e3 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -292,16 +292,17 @@ void janet_marshal_janet(JanetMarshalContext *ctx, Janet x) { static void marshal_one_abstract(MarshalState *st, Janet x, int flags) { - const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); - const JanetAbstractTypeInfo *info = janet_get_abstract_type_info_byname(at->name); - if (info && info->marshal) { + void *abstract = janet_unwrap_abstract(x); + const JanetAbstractType *at = janet_abstract_type(abstract); + if (at->marshal) { MARK_SEEN(); JanetMarshalContext context = {st, NULL, flags, NULL}; pushbyte(st, LB_ABSTRACT); - pushint(st, info->tag); - info->marshal(janet_unwrap_abstract(x), &context); + pushint(st, at->id); + pushint(st, janet_abstract_size(abstract)); + at->marshal(abstract, &context); } else { - janet_panicf("try to marshal unregistered absttact type, cannot marshal %p", x); + janet_panicf("try to marshal unregistered abstract type, cannot marshal %p", x); } } @@ -462,9 +463,9 @@ static void marshal_one(MarshalState *st, Janet x, int flags) { return; } case JANET_ABSTRACT: { - marshal_one_abstract(st, x, flags); - return; - } + marshal_one_abstract(st, x, flags); + return; + } case JANET_FUNCTION: { pushbyte(st, LB_FUNCTION); JanetFunction *func = janet_unwrap_function(x); @@ -932,13 +933,13 @@ void janet_unmarshal_janet(JanetMarshalContext *ctx, Janet *out) { } static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t *data, Janet *out, int flags) { - uint32_t tag = readint(st, &data); - const JanetAbstractTypeInfo *info = janet_get_abstract_type_info(tag); - if (info == NULL) return NULL; - if (info->unmarshal) { - void *p = janet_abstract(info->at, info->size); + uint32_t id = readint(st, &data); + const JanetAbstractType *at = janet_get_abstract_type(id); + if (at == NULL) return NULL; + if (at->unmarshal) { + void *p = janet_abstract(at, readint(st, &data)); JanetMarshalContext context = {NULL, st, flags, data}; - info->unmarshal(p, &context); + at->unmarshal(p, &context); *out = janet_wrap_abstract(p); return data; } diff --git a/src/core/parse.c b/src/core/parse.c index 841440b3..2c33454d 100644 --- a/src/core/parse.c +++ b/src/core/parse.c @@ -624,9 +624,12 @@ static Janet parserget(void *p, Janet key); static JanetAbstractType janet_parse_parsertype = { "core/parser", + 0, parsergc, parsermark, parserget, + NULL, + NULL, NULL }; diff --git a/src/core/peg.c b/src/core/peg.c index 2ab2244f..19ca9254 100644 --- a/src/core/peg.c +++ b/src/core/peg.c @@ -981,9 +981,12 @@ static int peg_mark(void *p, size_t size) { static JanetAbstractType peg_type = { "core/peg", + 0, NULL, peg_mark, NULL, + NULL, + NULL, NULL }; diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 20d25b7d..9d960ac6 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -136,18 +136,17 @@ static void ta_buffer_unmarshal(void *p, JanetMarshalContext *ctx) { } -static const JanetAbstractType ta_buffer_type = {"ta/buffer", ta_buffer_gc, NULL, NULL, NULL}; - -static const JanetAbstractTypeInfo ta_buffer_typeinfo = { - &ta_buffer_type, - sizeof(TA_Buffer), +static const JanetAbstractType ta_buffer_type = { + "ta/buffer", 1000, - 0, + ta_buffer_gc, + NULL, + NULL, + NULL, ta_buffer_marshal, ta_buffer_unmarshal, }; - typedef struct { TA_Buffer *buffer; void *data; /* pointer inside buffer->data */ @@ -252,15 +251,13 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ return view; \ }; -#define DEFINE_VIEW_ABSTRACT_TYPE(type) static const JanetAbstractType ta_view_##type##_t = {"ta/"#type,NULL,ta_mark,ta_get_##type,ta_put_##type}; #define BUILD_TYPE(type) \ DEFINE_VIEW_TYPE(type) \ DEFINE_VIEW_GETTER(type) \ DEFINE_VIEW_SETTER(type) \ -DEFINE_VIEW_INITIALIZER(type) \ -DEFINE_VIEW_ABSTRACT_TYPE(type) +DEFINE_VIEW_INITIALIZER(type) BUILD_TYPE(uint8) BUILD_TYPE(int8) @@ -277,28 +274,42 @@ BUILD_TYPE(float64) #undef DEFINE_VIEW_GETTER #undef DEFINE_VIEW_SETTER #undef DEFINE_VIEW_INITIALIZER + + +#define DEFINE_VIEW_ABSTRACT_TYPE(type,tag) \ +{ \ + "ta/"#type, \ + tag, \ + NULL, \ + ta_mark, \ + ta_get_##type, \ + ta_put_##type, \ + ta_view_marshal, \ + ta_view_unmarshal \ +} + +static const JanetAbstractType ta_array_types[] = { + DEFINE_VIEW_ABSTRACT_TYPE(uint8, 1001), + DEFINE_VIEW_ABSTRACT_TYPE(int8, 1002), + DEFINE_VIEW_ABSTRACT_TYPE(uint16, 1003), + DEFINE_VIEW_ABSTRACT_TYPE(int16, 1004), + DEFINE_VIEW_ABSTRACT_TYPE(uint32, 1005), + DEFINE_VIEW_ABSTRACT_TYPE(int32, 1006), + DEFINE_VIEW_ABSTRACT_TYPE(uint64, 1007), + DEFINE_VIEW_ABSTRACT_TYPE(int64, 1008), + DEFINE_VIEW_ABSTRACT_TYPE(float32, 1009), + DEFINE_VIEW_ABSTRACT_TYPE(float64, 1010) +}; + #undef DEFINE_VIEW_ABSTRACT_TYPE -#define VIEW_ABSTRACT_INFO_INIT(type,salt) {&ta_view_##type##_t,sizeof(TA_View),salt,0,ta_view_marshal,ta_view_unmarshal} -static const JanetAbstractTypeInfo ta_array_types[] = { - VIEW_ABSTRACT_INFO_INIT(uint8, 1001), - VIEW_ABSTRACT_INFO_INIT(int8, 1002), - VIEW_ABSTRACT_INFO_INIT(uint16, 1003), - VIEW_ABSTRACT_INFO_INIT(int16, 1004), - VIEW_ABSTRACT_INFO_INIT(uint32, 1005), - VIEW_ABSTRACT_INFO_INIT(int32, 1006), - VIEW_ABSTRACT_INFO_INIT(uint64, 1007), - VIEW_ABSTRACT_INFO_INIT(int64, 1008), - VIEW_ABSTRACT_INFO_INIT(float32, 1009), - VIEW_ABSTRACT_INFO_INIT(float64, 1010), -}; static int is_ta_type(Janet x) { if (janet_checktype(x, JANET_ABSTRACT)) { const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); for (size_t i = 0; i < TA_COUNT_TYPES; i++) { - if (at == ta_array_types[i].at) return 1; + if (at == ta_array_types + i) return 1; } } return 0; @@ -331,7 +342,7 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { buffer = (TA_Buffer *)janet_getabstract(argv, 4, &ta_buffer_type); } } - TA_View *view = janet_abstract(ta_array_types[type].at, sizeof(TA_View)); + TA_View *view = janet_abstract(&ta_array_types[type], sizeof(TA_View)); switch (type) { CASE_TYPE_INITIALIZE(uint8); CASE_TYPE_INITIALIZE(int8); @@ -389,23 +400,21 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { /* TODO for test it's not the good place for this function */ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - JanetAbstractTypeInfo *info; + const JanetAbstractType *at; if (janet_checktype(argv[0], JANET_KEYWORD)) { const uint8_t *keyw = janet_unwrap_keyword(argv[0]); - info = janet_get_abstract_type_info_byname((const char *)keyw); + at = janet_get_abstract_type_byname((const char *)keyw); } else { - uint32_t tag = (uint32_t)janet_getinteger(argv, 0); - info = janet_get_abstract_type_info(tag); + uint32_t id = (uint32_t)janet_getinteger(argv, 0); + at = janet_get_abstract_type(id); } - if (info == NULL) { + if (at == NULL) { return janet_wrap_nil(); } - JanetKV *props = janet_struct_begin(5); - janet_struct_put(props, janet_ckeywordv("tag"), janet_wrap_number(info->tag)); - janet_struct_put(props, janet_ckeywordv("salt"), janet_wrap_number(info->salt)); - janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->at->name)); - janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number(info->size)); - janet_struct_put(props, janet_ckeywordv("marshal"), janet_wrap_boolean((info->marshal != NULL) && (info->unmarshal != NULL))); + JanetKV *props = janet_struct_begin(3); + janet_struct_put(props, janet_ckeywordv("id"), janet_wrap_number(at->id)); + janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(at->name)); + janet_struct_put(props, janet_ckeywordv("marshal"), janet_wrap_boolean((at->marshal != NULL) && (at->unmarshal != NULL))); return janet_wrap_struct(janet_struct_end(props)); } @@ -527,7 +536,7 @@ static const JanetReg ta_cfuns[] = { /* Module entry point */ void janet_lib_typed_array(JanetTable *env) { janet_core_cfuns(env, NULL, ta_cfuns); - janet_register_abstract_type(&ta_buffer_typeinfo); + janet_register_abstract_type(&ta_buffer_type); for (size_t i = 0; i < TA_COUNT_TYPES; i++) { janet_register_abstract_type(ta_array_types + i); } diff --git a/src/core/util.c b/src/core/util.c index 9093cdc5..8777ae0a 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -286,58 +286,50 @@ void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns) /* Abstract type introspection */ -static const JanetAbstractType type_info = {"core/type_info", NULL, NULL, NULL, NULL}; +static const JanetAbstractType type_wrap = {"core/type_info", 0, NULL, NULL, NULL, NULL, NULL, NULL}; -static uint32_t janet_abstract_type_gentag(const char *name, uint32_t salt) { - /* something smarter should propably done here ? */ - int32_t len = strlen(name); - const char *end = name + len; - uint32_t hash = 5381 + salt; - while (name < end) - hash = (hash << 5) + hash + *name++; - return (int32_t) hash; -} +typedef struct { + const JanetAbstractType *at; +} JanetAbstractTypeWrap; -void janet_register_abstract_type(const JanetAbstractTypeInfo *info) { - JanetAbstractTypeInfo *abstract = (JanetAbstractTypeInfo *)janet_abstract(&type_info, sizeof(JanetAbstractTypeInfo)); - memcpy(abstract, info, sizeof(JanetAbstractTypeInfo)); - abstract->tag = janet_abstract_type_gentag(info->at->name, info->salt); - if (!(janet_checktype(janet_table_get(janet_vm_registry, janet_wrap_number(abstract->tag)), JANET_NIL)) || - !(janet_checktype(janet_table_get(janet_vm_registry, janet_ckeywordv(abstract->at->name)), JANET_NIL))) { - janet_panic("Register abstract type fail, a type with same name or tag exist"); + +void janet_register_abstract_type(const JanetAbstractType *at) { + JanetAbstractTypeWrap *abstract = (JanetAbstractTypeWrap *)janet_abstract(&type_wrap, sizeof(JanetAbstractTypeWrap)); + abstract->at = at; + if (!(janet_checktype(janet_table_get(janet_vm_registry, janet_wrap_number(at->id)), JANET_NIL)) || + !(janet_checktype(janet_table_get(janet_vm_registry, janet_ckeywordv(at->name)), JANET_NIL))) { + janet_panic("Register abstract type fail, a type with same name or id exists"); } - janet_table_put(janet_vm_registry, janet_wrap_number(abstract->tag), janet_wrap_abstract(abstract)); - janet_table_put(janet_vm_registry, janet_ckeywordv(abstract->at->name), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry, janet_wrap_number(at->id), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry, janet_ckeywordv(at->name), janet_wrap_abstract(abstract)); } -JanetAbstractTypeInfo *janet_get_abstract_type_info(uint32_t tag) { - Janet info = janet_table_get(janet_vm_registry, janet_wrap_number(tag)); - if (janet_checktype(info, JANET_NIL)) { +const JanetAbstractType *janet_get_abstract_type(uint32_t id) { + Janet twrap = janet_table_get(janet_vm_registry, janet_wrap_number(id)); + if (janet_checktype(twrap, JANET_NIL)) { return NULL; } - if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { - janet_panic("expected type_info"); + if (!janet_checktype(twrap, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(twrap)) != &type_wrap)) { + janet_panic("expected abstract type"); } - JanetAbstractTypeInfo *type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); - return type_info; + JanetAbstractTypeWrap *w = (JanetAbstractTypeWrap *)janet_unwrap_abstract(twrap); + return w->at; } -JanetAbstractTypeInfo *janet_get_abstract_type_info_byname(const char *name) { - Janet info = janet_table_get(janet_vm_registry, janet_ckeywordv(name)); - if (janet_checktype(info, JANET_NIL)) { +const JanetAbstractType *janet_get_abstract_type_byname(const char *name) { + Janet twrap = janet_table_get(janet_vm_registry, janet_ckeywordv(name)); + if (janet_checktype(twrap, JANET_NIL)) { return NULL; } - if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { - janet_panic("expected type_info"); + if (!janet_checktype(twrap, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(twrap)) != &type_wrap)) { + janet_panic("expected abstract type"); } - JanetAbstractTypeInfo *type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); - return type_info; + JanetAbstractTypeWrap *w = (JanetAbstractTypeWrap *)janet_unwrap_abstract(twrap); + return w->at; } - - #ifndef JANET_BOOTSTRAP void janet_core_def(JanetTable *env, const char *name, Janet x, const void *p) { (void) p; diff --git a/src/include/janet.h b/src/include/janet.h index b732d47a..75655955 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -804,13 +804,23 @@ struct JanetParser { int lookback; }; +typedef struct { + void *m_state; /* void* to not expose MarshalState ?*/ + void *u_state; + int flags; + const uint8_t *data; +} JanetMarshalContext; + /* Defines an abstract type */ struct JanetAbstractType { const char *name; + uint32_t id; int (*gc)(void *data, size_t len); int (*gcmark)(void *data, size_t len); Janet(*get)(void *data, Janet key); void (*put)(void *data, Janet key, Janet value); + void (*marshal)(void *p, JanetMarshalContext *ctx); + void (*unmarshal)(void *p, JanetMarshalContext *ctx); }; struct JanetReg { @@ -1241,12 +1251,7 @@ 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 struct { - void *m_state; /* void* to not expose MarshalState ?*/ - void *u_state; - int flags; - const uint8_t *data; -} JanetMarshalContext; + JANET_API void janet_marshal_int(JanetMarshalContext *ctx, int32_t value); JANET_API void janet_marshal_byte(JanetMarshalContext *ctx, uint8_t value); @@ -1260,19 +1265,14 @@ 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_janet(JanetMarshalContext *ctx, Janet *out); -typedef struct { - const JanetAbstractType *at; - size_t size; /* abstract type size */ - const uint32_t salt; /* salt */ - uint32_t tag; /* unique tag computed by janet (hash of name and salt) */ - void (* marshal)(void *p, JanetMarshalContext *ctx); - void (* unmarshal)(void *p, JanetMarshalContext *ctx); -} JanetAbstractTypeInfo; -JANET_API void janet_register_abstract_type(const JanetAbstractTypeInfo *info); -JANET_API JanetAbstractTypeInfo *janet_get_abstract_type_info(uint32_t tag); -JANET_API JanetAbstractTypeInfo *janet_get_abstract_type_info_byname(const char *name); + + +JANET_API void janet_register_abstract_type(const JanetAbstractType *at); + +JANET_API const JanetAbstractType *janet_get_abstract_type(uint32_t id); +JANET_API const JanetAbstractType *janet_get_abstract_type_byname(const char *name); From 9c1c7fb3844be87354cbfb001b4e101f3faa13b5 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Sun, 24 Feb 2019 02:51:34 +0100 Subject: [PATCH 11/18] Remove AT id use name as tag --- src/core/io.c | 1 - src/core/marsh.c | 7 ++++--- src/core/parse.c | 1 - src/core/peg.c | 1 - src/core/typedarray.c | 37 ++++++++++++++----------------------- src/core/util.c | 24 +++++------------------- src/include/janet.h | 4 +--- 7 files changed, 24 insertions(+), 51 deletions(-) diff --git a/src/core/io.c b/src/core/io.c index e4b5b28c..0a6534d4 100644 --- a/src/core/io.c +++ b/src/core/io.c @@ -53,7 +53,6 @@ static Janet io_file_get(void *p, Janet); JanetAbstractType cfun_io_filetype = { "core/file", - 0, cfun_io_gc, NULL, io_file_get, diff --git a/src/core/marsh.c b/src/core/marsh.c index b32129e3..2d0155b0 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -298,7 +298,7 @@ static void marshal_one_abstract(MarshalState *st, Janet x, int flags) { MARK_SEEN(); JanetMarshalContext context = {st, NULL, flags, NULL}; pushbyte(st, LB_ABSTRACT); - pushint(st, at->id); + marshal_one(st, janet_ckeywordv(at->name), flags + 1); pushint(st, janet_abstract_size(abstract)); at->marshal(abstract, &context); } else { @@ -933,8 +933,9 @@ void janet_unmarshal_janet(JanetMarshalContext *ctx, Janet *out) { } static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t *data, Janet *out, int flags) { - uint32_t id = readint(st, &data); - const JanetAbstractType *at = janet_get_abstract_type(id); + Janet key; + data = unmarshal_one(st, data, &key, flags + 1); + const JanetAbstractType *at = janet_get_abstract_type(key); if (at == NULL) return NULL; if (at->unmarshal) { void *p = janet_abstract(at, readint(st, &data)); diff --git a/src/core/parse.c b/src/core/parse.c index 2c33454d..807bee42 100644 --- a/src/core/parse.c +++ b/src/core/parse.c @@ -624,7 +624,6 @@ static Janet parserget(void *p, Janet key); static JanetAbstractType janet_parse_parsertype = { "core/parser", - 0, parsergc, parsermark, parserget, diff --git a/src/core/peg.c b/src/core/peg.c index 19ca9254..35af390b 100644 --- a/src/core/peg.c +++ b/src/core/peg.c @@ -981,7 +981,6 @@ static int peg_mark(void *p, size_t size) { static JanetAbstractType peg_type = { "core/peg", - 0, NULL, peg_mark, NULL, diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 9d960ac6..6b1f20ae 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -138,7 +138,6 @@ static void ta_buffer_unmarshal(void *p, JanetMarshalContext *ctx) { static const JanetAbstractType ta_buffer_type = { "ta/buffer", - 1000, ta_buffer_gc, NULL, NULL, @@ -276,10 +275,9 @@ BUILD_TYPE(float64) #undef DEFINE_VIEW_INITIALIZER -#define DEFINE_VIEW_ABSTRACT_TYPE(type,tag) \ +#define DEFINE_VIEW_ABSTRACT_TYPE(type) \ { \ "ta/"#type, \ - tag, \ NULL, \ ta_mark, \ ta_get_##type, \ @@ -289,16 +287,16 @@ BUILD_TYPE(float64) } static const JanetAbstractType ta_array_types[] = { - DEFINE_VIEW_ABSTRACT_TYPE(uint8, 1001), - DEFINE_VIEW_ABSTRACT_TYPE(int8, 1002), - DEFINE_VIEW_ABSTRACT_TYPE(uint16, 1003), - DEFINE_VIEW_ABSTRACT_TYPE(int16, 1004), - DEFINE_VIEW_ABSTRACT_TYPE(uint32, 1005), - DEFINE_VIEW_ABSTRACT_TYPE(int32, 1006), - DEFINE_VIEW_ABSTRACT_TYPE(uint64, 1007), - DEFINE_VIEW_ABSTRACT_TYPE(int64, 1008), - DEFINE_VIEW_ABSTRACT_TYPE(float32, 1009), - DEFINE_VIEW_ABSTRACT_TYPE(float64, 1010) + DEFINE_VIEW_ABSTRACT_TYPE(uint8), + DEFINE_VIEW_ABSTRACT_TYPE(int8), + DEFINE_VIEW_ABSTRACT_TYPE(uint16), + DEFINE_VIEW_ABSTRACT_TYPE(int16), + DEFINE_VIEW_ABSTRACT_TYPE(uint32), + DEFINE_VIEW_ABSTRACT_TYPE(int32), + DEFINE_VIEW_ABSTRACT_TYPE(uint64), + DEFINE_VIEW_ABSTRACT_TYPE(int64), + DEFINE_VIEW_ABSTRACT_TYPE(float32), + DEFINE_VIEW_ABSTRACT_TYPE(float64) }; #undef DEFINE_VIEW_ABSTRACT_TYPE @@ -400,19 +398,12 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { /* TODO for test it's not the good place for this function */ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - const JanetAbstractType *at; - if (janet_checktype(argv[0], JANET_KEYWORD)) { - const uint8_t *keyw = janet_unwrap_keyword(argv[0]); - at = janet_get_abstract_type_byname((const char *)keyw); - } else { - uint32_t id = (uint32_t)janet_getinteger(argv, 0); - at = janet_get_abstract_type(id); - } + const uint8_t *key = janet_getkeyword(argv, 0); + const JanetAbstractType *at = janet_get_abstract_type(janet_wrap_keyword(key)); if (at == NULL) { return janet_wrap_nil(); } - JanetKV *props = janet_struct_begin(3); - janet_struct_put(props, janet_ckeywordv("id"), janet_wrap_number(at->id)); + JanetKV *props = janet_struct_begin(2); janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(at->name)); janet_struct_put(props, janet_ckeywordv("marshal"), janet_wrap_boolean((at->marshal != NULL) && (at->unmarshal != NULL))); return janet_wrap_struct(janet_struct_end(props)); diff --git a/src/core/util.c b/src/core/util.c index 8777ae0a..0351a929 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -286,7 +286,7 @@ void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns) /* Abstract type introspection */ -static const JanetAbstractType type_wrap = {"core/type_info", 0, NULL, NULL, NULL, NULL, NULL, NULL}; +static const JanetAbstractType type_wrap = {"core/type_info", NULL, NULL, NULL, NULL, NULL, NULL}; typedef struct { const JanetAbstractType *at; @@ -296,29 +296,15 @@ typedef struct { void janet_register_abstract_type(const JanetAbstractType *at) { JanetAbstractTypeWrap *abstract = (JanetAbstractTypeWrap *)janet_abstract(&type_wrap, sizeof(JanetAbstractTypeWrap)); abstract->at = at; - if (!(janet_checktype(janet_table_get(janet_vm_registry, janet_wrap_number(at->id)), JANET_NIL)) || - !(janet_checktype(janet_table_get(janet_vm_registry, janet_ckeywordv(at->name)), JANET_NIL))) { - janet_panic("Register abstract type fail, a type with same name or id exists"); + if (!(janet_checktype(janet_table_get(janet_vm_registry, janet_ckeywordv(at->name)), JANET_NIL))) { + janet_panic("Register abstract type fail, a type with same name exists"); } - janet_table_put(janet_vm_registry, janet_wrap_number(at->id), janet_wrap_abstract(abstract)); janet_table_put(janet_vm_registry, janet_ckeywordv(at->name), janet_wrap_abstract(abstract)); } -const JanetAbstractType *janet_get_abstract_type(uint32_t id) { - Janet twrap = janet_table_get(janet_vm_registry, janet_wrap_number(id)); - if (janet_checktype(twrap, JANET_NIL)) { - return NULL; - } - if (!janet_checktype(twrap, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(twrap)) != &type_wrap)) { - janet_panic("expected abstract type"); - } - JanetAbstractTypeWrap *w = (JanetAbstractTypeWrap *)janet_unwrap_abstract(twrap); - return w->at; -} - -const JanetAbstractType *janet_get_abstract_type_byname(const char *name) { - Janet twrap = janet_table_get(janet_vm_registry, janet_ckeywordv(name)); +const JanetAbstractType *janet_get_abstract_type(Janet key) { + Janet twrap = janet_table_get(janet_vm_registry, key); if (janet_checktype(twrap, JANET_NIL)) { return NULL; } diff --git a/src/include/janet.h b/src/include/janet.h index 75655955..0430e103 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -814,7 +814,6 @@ typedef struct { /* Defines an abstract type */ struct JanetAbstractType { const char *name; - uint32_t id; int (*gc)(void *data, size_t len); int (*gcmark)(void *data, size_t len); Janet(*get)(void *data, Janet key); @@ -1271,8 +1270,7 @@ JANET_API void janet_unmarshal_janet(JanetMarshalContext *ctx, Janet *out); JANET_API void janet_register_abstract_type(const JanetAbstractType *at); -JANET_API const JanetAbstractType *janet_get_abstract_type(uint32_t id); -JANET_API const JanetAbstractType *janet_get_abstract_type_byname(const char *name); +JANET_API const JanetAbstractType *janet_get_abstract_type(Janet key); From 0eae75a5c299b83ebd64a3ed23826888d3ffed95 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Sun, 24 Feb 2019 18:45:14 +0100 Subject: [PATCH 12/18] added MARSH_EOS check --- examples/tarray.janet | 12 ++++++++++++ src/core/marsh.c | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/examples/tarray.janet b/examples/tarray.janet index 1210a6f6..689c56c6 100644 --- a/examples/tarray.janet +++ b/examples/tarray.janet @@ -72,3 +72,15 @@ (printf "properties:\n%p" (tarray/properties (A :array))) (printf "row properties:\n%p" (tarray/properties (matrix/row A 1))) + + +# test marshalling + +(def a (tarray/new :float64 20)) +(set (a 0) math/pi) +(set (a 1) 1234) + +(def b (unmarshal (marshal a))) +(printf "%p" (tarray/properties b)) +(print (b 0)) +(print (b 1)) diff --git a/src/core/marsh.c b/src/core/marsh.c index 2d0155b0..238e999d 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -919,10 +919,14 @@ void janet_unmarshal_size(JanetMarshalContext *ctx, size_t *i) { void janet_unmarshal_byte(JanetMarshalContext *ctx, uint8_t *b) { + UnmarshalState *st = (UnmarshalState *)(ctx->u_state); + MARSH_EOS(st, ctx->data); *b = *(ctx->data++); }; void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, int32_t len) { + UnmarshalState *st = (UnmarshalState *)(ctx->u_state); + MARSH_EOS(st, ctx->data+len-1); memcpy(dest, ctx->data, len); ctx->data += len; } From 4147c0ce1fcf5ca1b4216a84c03bc6521b7b2b4a Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Sun, 24 Feb 2019 22:24:18 +0100 Subject: [PATCH 13/18] Added typed array C API --- src/core/typedarray.c | 266 ++++++++++++++++++++++-------------------- src/include/janet.h | 44 ++++++- 2 files changed, 178 insertions(+), 132 deletions(-) diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 6b1f20ae..3de3205c 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -40,19 +40,6 @@ typedef int64_t ta_int64_t; typedef float ta_float32_t; typedef double ta_float64_t; -typedef enum TA_Type { - TA_TYPE_uint8, - TA_TYPE_int8, - TA_TYPE_uint16, - TA_TYPE_int16, - TA_TYPE_uint32, - TA_TYPE_int32, - TA_TYPE_uint64, - TA_TYPE_int64, - TA_TYPE_float32, - TA_TYPE_float64, -} TA_Type; - static char *ta_type_names[] = { "uint8", @@ -65,6 +52,7 @@ static char *ta_type_names[] = { "int64", "float32", "float64", + "any", }; static size_t ta_type_sizes[] = { @@ -79,11 +67,11 @@ static size_t ta_type_sizes[] = { sizeof(ta_float32_t), sizeof(ta_float64_t), }; -#define TA_COUNT_TYPES (TA_TYPE_float64 + 1) +#define TA_COUNT_TYPES (JANET_TARRAY_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) { +static JanetTArrayType get_ta_type_by_name(const uint8_t *name) { size_t nt = sizeof(ta_type_names) / sizeof(char *); for (size_t i = 0; i < nt; i++) { if (!janet_cstrcmp(name, ta_type_names[i])) @@ -95,13 +83,9 @@ static TA_Type get_ta_type_by_name(const uint8_t *name) { -typedef struct { - uint8_t *data; - size_t size; - uint32_t flags; -} TA_Buffer; -static TA_Buffer *ta_buffer_init(TA_Buffer *buf, size_t size) { + +static JanetTArrayBuffer *ta_buffer_init(JanetTArrayBuffer *buf, size_t size) { buf->data = (uint8_t *)calloc(size, sizeof(uint8_t)); buf->size = size; #ifdef JANET_BIG_ENDIAN @@ -114,20 +98,20 @@ static TA_Buffer *ta_buffer_init(TA_Buffer *buf, size_t size) { static int ta_buffer_gc(void *p, size_t s) { (void) s; - TA_Buffer *buf = (TA_Buffer *)p; + JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p; free(buf->data); return 0; } static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) { - TA_Buffer *buf = (TA_Buffer *)p; + JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p; janet_marshal_int(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) { - TA_Buffer *buf = (TA_Buffer *)p; + JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p; uint32_t size; janet_unmarshal_uint(ctx, &size); ta_buffer_init(buf, size); // warning if indianess <> platform ?? @@ -146,24 +130,18 @@ static const JanetAbstractType ta_buffer_type = { ta_buffer_unmarshal, }; -typedef struct { - TA_Buffer *buffer; - void *data; /* pointer inside buffer->data */ - size_t size; - size_t stride; - TA_Type type; -} TA_View; + static int ta_mark(void *p, size_t s) { (void) s; - TA_View *view = (TA_View *)p; + JanetTArrayView *view = (JanetTArrayView *)p; janet_mark(janet_wrap_abstract(view->buffer)); return 0; } static void ta_view_marshal(void *p, JanetMarshalContext *ctx) { - TA_View *view = (TA_View *)p; + JanetTArrayView *view = (JanetTArrayView *)p; size_t offset = (view->buffer->data - (uint8_t *)(view->data)); janet_marshal_int(ctx, view->size); janet_marshal_int(ctx, view->stride); @@ -174,7 +152,7 @@ static void ta_view_marshal(void *p, JanetMarshalContext *ctx) { static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) { - TA_View *view = (TA_View *)p; + JanetTArrayView *view = (JanetTArrayView *)p; size_t offset; Janet buffer; janet_unmarshal_size(ctx, &(view->size)); @@ -182,7 +160,7 @@ static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) { janet_unmarshal_uint(ctx, &(view->type)); janet_unmarshal_size(ctx, &offset); janet_unmarshal_janet(ctx, &buffer); - view->buffer = (TA_Buffer *)janet_unwrap_abstract(buffer); + view->buffer = (JanetTArrayBuffer *)janet_unwrap_abstract(buffer); view->data = view->buffer->data + offset; } @@ -192,11 +170,11 @@ static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) { #define DEFINE_VIEW_TYPE(thetype) \ typedef struct { \ - TA_Buffer * buffer; \ + JanetTArrayBuffer * buffer; \ ta_##thetype##_t * data; \ size_t size; \ size_t stride; \ - TA_Type type; \ + JanetTArrayType type; \ } TA_View_##thetype ; @@ -232,11 +210,11 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ } #define DEFINE_VIEW_INITIALIZER(thetype) \ - static TA_View * ta_init_##thetype(TA_View * view,TA_Buffer * 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) { \ TA_View_##thetype * tview=(TA_View_##thetype *) view; \ size_t buf_size=offset+(size-1)*(sizeof(ta_##thetype##_t))*stride+1; \ if (buf==NULL) { \ - buf=(TA_Buffer *)janet_abstract(&ta_buffer_type,sizeof(TA_Buffer)); \ + buf=(JanetTArrayBuffer *)janet_abstract(&ta_buffer_type,sizeof(JanetTArrayBuffer)); \ ta_buffer_init(buf,buf_size); \ } \ if (buf->sizestride=stride; \ tview->size=size; \ tview->data=(ta_##thetype##_t *)(buf->data+offset); \ - tview->type=TA_TYPE_##thetype; \ + tview->type=JANET_TARRAY_TYPE_##thetype; \ return view; \ }; @@ -303,7 +281,7 @@ static const JanetAbstractType ta_array_types[] = { -static int is_ta_type(Janet x) { +static int is_ta_anytype(Janet x) { if (janet_checktype(x, JANET_ABSTRACT)) { const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); for (size_t i = 0; i < TA_COUNT_TYPES; i++) { @@ -313,34 +291,22 @@ static int is_ta_type(Janet x) { return 0; } -#undef VIEW_ABSTRACT_INFO_INIT +static int is_ta_type(Janet x, JanetTArrayType type) { + return (janet_checktype(x, JANET_ABSTRACT) && (type < TA_COUNT_TYPES) && + (janet_abstract_type(janet_unwrap_abstract(x))== &ta_array_types[type])) ? 1 : 0; +} -#define CASE_TYPE_INITIALIZE(type) case TA_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 -static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { - janet_arity(argc, 2, 5); - size_t offset = 0; - size_t stride = 1; - TA_Buffer *buffer = NULL; - const uint8_t *keyw = janet_getkeyword(argv, 0); - TA_Type type = get_ta_type_by_name(keyw); - size_t size = (size_t)janet_getinteger(argv, 1); - if (argc > 2) - stride = (size_t)janet_getinteger(argv, 2); - if (argc > 3) - offset = (size_t)janet_getinteger(argv, 3); - if (argc > 4) { - if (is_ta_type(argv[4])) { - TA_View *view = (TA_View *)janet_unwrap_abstract(argv[4]); - offset = (view->buffer->data - (uint8_t *)(view->data)) + offset * ta_type_sizes[view->type]; - stride *= view->stride; - buffer = view->buffer; - } else { - buffer = (TA_Buffer *)janet_getabstract(argv, 4, &ta_buffer_type); - } - } - TA_View *view = janet_abstract(&ta_array_types[type], sizeof(TA_View)); +JanetTArrayBuffer * janet_tarray_buffer(size_t size) { + JanetTArrayBuffer *buf = (JanetTArrayBuffer *)janet_abstract(&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) { + JanetTArrayView *view = janet_abstract(&ta_array_types[type], sizeof(JanetTArrayView)); switch (type) { CASE_TYPE_INITIALIZE(uint8); CASE_TYPE_INITIALIZE(int8); @@ -352,39 +318,93 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { CASE_TYPE_INITIALIZE(int64); CASE_TYPE_INITIALIZE(float32); CASE_TYPE_INITIALIZE(float64); + default : janet_panic("bad typed array type"); + } - return janet_wrap_abstract(view); + return view; } #undef CASE_TYPE_INITIALIZE +JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n) { + return (JanetTArrayBuffer *)janet_getabstract(argv, n, &ta_buffer_type); +} + +int janet_is_tarray_view(Janet x,JanetTArrayType type) { + return (type==JANET_TARRAY_TYPE_any) ? is_ta_anytype(x) : is_ta_type(x,type); +} + +int janet_tarray_type_size(JanetTArrayType type) { + return (type 2) + stride = (size_t)janet_getinteger(argv, 2); + if (argc > 3) + offset = (size_t)janet_getinteger(argv, 3); + if (argc > 4) { + if (is_ta_anytype(argv[4])) { + JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[4]); + offset = (view->buffer->data - (uint8_t *)(view->data)) + offset * ta_type_sizes[view->type]; + stride *= view->stride; + buffer = view->buffer; + } else { + buffer = (JanetTArrayBuffer *)janet_getabstract(argv, 4, &ta_buffer_type); + } + } + JanetTArrayView * view =janet_tarray_view(type,size,stride,offset,buffer); + return janet_wrap_abstract(view); +} + + static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - if (is_ta_type(argv[0])) { - TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); + if (is_ta_anytype(argv[0])) { + JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[0]); return janet_wrap_abstract(view->buffer); } size_t size = (size_t)janet_getinteger(argv, 0); - TA_Buffer *buf = (TA_Buffer *)janet_abstract(&ta_buffer_type, sizeof(TA_Buffer)); - ta_buffer_init(buf, size); + JanetTArrayBuffer *buf = janet_tarray_buffer(size); return janet_wrap_abstract(buf); } static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - if (is_ta_type(argv[0])) { - TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); + if (is_ta_anytype(argv[0])) { + JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[0]); return janet_wrap_number(view->size); } - TA_Buffer *buf = (TA_Buffer *)janet_getabstract(argv, 0, &ta_buffer_type); + JanetTArrayBuffer *buf = (JanetTArrayBuffer *)janet_getabstract(argv, 0, &ta_buffer_type); return janet_wrap_number(buf->size); } static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - if (!is_ta_type(argv[0])) + if (!is_ta_anytype(argv[0])) janet_panic("expected typed array"); - TA_View *view = (TA_View *)janet_unwrap_abstract(argv[0]); + JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[0]); JanetKV *props = janet_struct_begin(6); janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number(view->size)); janet_struct_put(props, janet_ckeywordv("byte-offset"), janet_wrap_number((uint8_t *)(view->data) - view->buffer->data)); @@ -412,63 +432,57 @@ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { janet_arity(argc, 4, 5); - 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 count = (argc == 5) ? (size_t)janet_getinteger(argv, 4) : 1; - size_t src_atom_size = ta_type_sizes[src->type]; - size_t dst_atom_size = ta_type_sizes[dst->type]; - size_t step_src = src->stride * src_atom_size; - size_t step_dst = dst->stride * dst_atom_size; - size_t pos_src = ((uint8_t *)(src->data) - src->buffer->data) + (index_src * step_src); - size_t pos_dst = ((uint8_t *)(dst->data) - dst->buffer->data) + (index_dst * step_dst); - uint8_t *ps = src->buffer->data + pos_src, * 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)) { - for (size_t i = 0; i < count; i++) { - memmove(pd, ps, src_atom_size); - pd += step_dst; - ps += step_src; - } - } else - janet_panic("typed array copy out of bound"); + JanetTArrayView *src = janet_gettarray_view(argv,0,JANET_TARRAY_TYPE_any); + size_t index_src = (size_t)janet_getinteger(argv, 1); + JanetTArrayView *dst = janet_gettarray_view(argv,2,JANET_TARRAY_TYPE_any); + size_t index_dst = (size_t)janet_getinteger(argv, 3); + size_t count = (argc == 5) ? (size_t)janet_getinteger(argv, 4) : 1; + size_t src_atom_size = ta_type_sizes[src->type]; + size_t dst_atom_size = ta_type_sizes[dst->type]; + size_t step_src = src->stride * src_atom_size; + size_t step_dst = dst->stride * dst_atom_size; + size_t pos_src = ((uint8_t *)(src->data) - src->buffer->data) + (index_src * step_src); + size_t pos_dst = ((uint8_t *)(dst->data) - dst->buffer->data) + (index_dst * step_dst); + uint8_t *ps = src->buffer->data + pos_src, * 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)) { + for (size_t i = 0; i < count; i++) { + memmove(pd, ps, src_atom_size); + pd += step_dst; + ps += step_src; + } } else { - janet_panic("expected typed array"); - } + janet_panic("typed array copy out of bound"); + } return janet_wrap_nil(); } static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) { janet_arity(argc, 4, 5); - 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 count = (argc == 5) ? (size_t)janet_getinteger(argv, 4) : 1; - size_t src_atom_size = ta_type_sizes[src->type]; - size_t dst_atom_size = ta_type_sizes[dst->type]; - size_t step_src = src->stride * src_atom_size; - size_t step_dst = dst->stride * dst_atom_size; - size_t pos_src = ((uint8_t *)(src->data) - src->buffer->data) + (index_src * step_src); - size_t pos_dst = ((uint8_t *)(dst->data) - 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)) { - for (size_t i = 0; i < count; i++) { - memcpy(temp, ps, src_atom_size); - memcpy(ps, pd, src_atom_size); - memcpy(pd, temp, src_atom_size); - pd += step_dst; - ps += step_src; - } - } else - janet_panic("typed array swap out of bound"); + JanetTArrayView *src = janet_gettarray_view(argv,0,JANET_TARRAY_TYPE_any); + size_t index_src = (size_t)janet_getinteger(argv, 1); + JanetTArrayView *dst = janet_gettarray_view(argv,2,JANET_TARRAY_TYPE_any); + size_t index_dst = (size_t)janet_getinteger(argv, 3); + size_t count = (argc == 5) ? (size_t)janet_getinteger(argv, 4) : 1; + size_t src_atom_size = ta_type_sizes[src->type]; + size_t dst_atom_size = ta_type_sizes[dst->type]; + size_t step_src = src->stride * src_atom_size; + size_t step_dst = dst->stride * dst_atom_size; + size_t pos_src = ((uint8_t *)(src->data) - src->buffer->data) + (index_src * step_src); + size_t pos_dst = ((uint8_t *)(dst->data) - 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)) { + for (size_t i = 0; i < count; i++) { + memcpy(temp, ps, src_atom_size); + memcpy(ps, pd, src_atom_size); + memcpy(pd, temp, src_atom_size); + pd += step_dst; + ps += step_src; + } } else { - janet_panic("expected typed array"); + janet_panic("typed array swap out of bound"); } return janet_wrap_nil(); } diff --git a/src/include/janet.h b/src/include/janet.h index 0430e103..21ee2d80 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1251,7 +1251,7 @@ JANET_API int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t lengt JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which); - +/* Marshal API */ JANET_API void janet_marshal_int(JanetMarshalContext *ctx, int32_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); @@ -1264,15 +1264,47 @@ 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_janet(JanetMarshalContext *ctx, Janet *out); - - - - JANET_API void janet_register_abstract_type(const JanetAbstractType *at); - JANET_API const JanetAbstractType *janet_get_abstract_type(Janet key); +#ifdef JANET_TYPED_ARRAY +typedef enum { + JANET_TARRAY_TYPE_uint8, + JANET_TARRAY_TYPE_int8, + JANET_TARRAY_TYPE_uint16, + JANET_TARRAY_TYPE_int16, + JANET_TARRAY_TYPE_uint32, + JANET_TARRAY_TYPE_int32, + JANET_TARRAY_TYPE_uint64, + JANET_TARRAY_TYPE_int64, + JANET_TARRAY_TYPE_float32, + JANET_TARRAY_TYPE_float64, + JANET_TARRAY_TYPE_any, +} JanetTArrayType; + +typedef struct { + uint8_t *data; + size_t size; + uint32_t flags; +} JanetTArrayBuffer; + +typedef struct { + JanetTArrayBuffer *buffer; + void *data; /* pointer inside buffer->data */ + size_t size; + 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 int janet_is_tarray_view(Janet x,JanetTArrayType type); +JANET_API int janet_tarray_type_size(JanetTArrayType type); +JANET_API JanetTArrayBuffer * janet_gettarray_buffer(const Janet *argv, int32_t n); +JANET_API JanetTArrayView * janet_gettarray_view(const Janet *argv, int32_t n,JanetTArrayType type); + +#endif /***** END SECTION MAIN *****/ From 632b920e972b038df8348df678109be33f4268d9 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Sun, 24 Feb 2019 22:36:35 +0100 Subject: [PATCH 14/18] fix C format --- src/core/marsh.c | 2 +- src/core/typedarray.c | 87 ++++++++++++++++++++++--------------------- src/include/janet.h | 14 +++---- 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/src/core/marsh.c b/src/core/marsh.c index 238e999d..f91db881 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -926,7 +926,7 @@ void janet_unmarshal_byte(JanetMarshalContext *ctx, uint8_t *b) { void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, int32_t len) { UnmarshalState *st = (UnmarshalState *)(ctx->u_state); - MARSH_EOS(st, ctx->data+len-1); + MARSH_EOS(st, ctx->data + len - 1); memcpy(dest, ctx->data, len); ctx->data += len; } diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 3de3205c..a203c368 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -292,20 +292,20 @@ static int is_ta_anytype(Janet x) { } static int is_ta_type(Janet x, JanetTArrayType type) { - return (janet_checktype(x, JANET_ABSTRACT) && (type < TA_COUNT_TYPES) && - (janet_abstract_type(janet_unwrap_abstract(x))== &ta_array_types[type])) ? 1 : 0; + return (janet_checktype(x, JANET_ABSTRACT) && (type < TA_COUNT_TYPES) && + (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) { - JanetTArrayBuffer *buf = (JanetTArrayBuffer *)janet_abstract(&ta_buffer_type, sizeof(JanetTArrayBuffer)); - ta_buffer_init(buf, size); - return buf; +JanetTArrayBuffer *janet_tarray_buffer(size_t size) { + JanetTArrayBuffer *buf = (JanetTArrayBuffer *)janet_abstract(&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) { +JanetTArrayView *janet_tarray_view(JanetTArrayType type, size_t size, size_t stride, size_t offset, JanetTArrayBuffer *buffer) { JanetTArrayView *view = janet_abstract(&ta_array_types[type], sizeof(JanetTArrayView)); switch (type) { CASE_TYPE_INITIALIZE(uint8); @@ -318,8 +318,9 @@ JanetTArrayView * janet_tarray_view(JanetTArrayType type,size_t size,size_t stri CASE_TYPE_INITIALIZE(int64); CASE_TYPE_INITIALIZE(float32); CASE_TYPE_INITIALIZE(float64); - default : janet_panic("bad typed array type"); - + default : + janet_panic("bad typed array type"); + } return view; } @@ -327,25 +328,25 @@ JanetTArrayView * janet_tarray_view(JanetTArrayType type,size_t size,size_t stri #undef CASE_TYPE_INITIALIZE JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n) { - return (JanetTArrayBuffer *)janet_getabstract(argv, n, &ta_buffer_type); + return (JanetTArrayBuffer *)janet_getabstract(argv, n, &ta_buffer_type); } -int janet_is_tarray_view(Janet x,JanetTArrayType type) { - return (type==JANET_TARRAY_TYPE_any) ? is_ta_anytype(x) : is_ta_type(x,type); +int janet_is_tarray_view(Janet x, JanetTArrayType type) { + return (type == JANET_TARRAY_TYPE_any) ? is_ta_anytype(x) : is_ta_type(x, type); } int janet_tarray_type_size(JanetTArrayType type) { - return (typetype]; @@ -445,23 +446,23 @@ static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { size_t pos_dst = ((uint8_t *)(dst->data) - dst->buffer->data) + (index_dst * step_dst); uint8_t *ps = src->buffer->data + pos_src, * 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)) { - for (size_t i = 0; i < count; i++) { - memmove(pd, ps, src_atom_size); - pd += step_dst; - ps += step_src; - } + (pos_src + (count - 1)*step_src + src_atom_size <= src->buffer->size)) { + for (size_t i = 0; i < count; i++) { + memmove(pd, ps, src_atom_size); + pd += step_dst; + ps += step_src; + } } else { - janet_panic("typed array copy out of bound"); - } + janet_panic("typed array copy out of bound"); + } return janet_wrap_nil(); } static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) { janet_arity(argc, 4, 5); - JanetTArrayView *src = janet_gettarray_view(argv,0,JANET_TARRAY_TYPE_any); + JanetTArrayView *src = janet_gettarray_view(argv, 0, JANET_TARRAY_TYPE_any); size_t index_src = (size_t)janet_getinteger(argv, 1); - JanetTArrayView *dst = janet_gettarray_view(argv,2,JANET_TARRAY_TYPE_any); + JanetTArrayView *dst = janet_gettarray_view(argv, 2, JANET_TARRAY_TYPE_any); size_t index_dst = (size_t)janet_getinteger(argv, 3); size_t count = (argc == 5) ? (size_t)janet_getinteger(argv, 4) : 1; size_t src_atom_size = ta_type_sizes[src->type]; @@ -473,16 +474,16 @@ static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) { 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)) { - for (size_t i = 0; i < count; i++) { - memcpy(temp, ps, src_atom_size); - memcpy(ps, pd, src_atom_size); - memcpy(pd, temp, src_atom_size); - pd += step_dst; - ps += step_src; - } + (pos_src + (count - 1)*step_src + src_atom_size <= src->buffer->size)) { + for (size_t i = 0; i < count; i++) { + memcpy(temp, ps, src_atom_size); + memcpy(ps, pd, src_atom_size); + memcpy(pd, temp, src_atom_size); + pd += step_dst; + ps += step_src; + } } else { - janet_panic("typed array swap out of bound"); + janet_panic("typed array swap out of bound"); } return janet_wrap_nil(); } diff --git a/src/include/janet.h b/src/include/janet.h index 5a46b5a0..d1e811e1 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1296,14 +1296,14 @@ typedef struct { 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 int janet_is_tarray_view(Janet x,JanetTArrayType type); + +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 int janet_is_tarray_view(Janet x, JanetTArrayType type); JANET_API int janet_tarray_type_size(JanetTArrayType type); -JANET_API JanetTArrayBuffer * janet_gettarray_buffer(const Janet *argv, int32_t n); -JANET_API JanetTArrayView * janet_gettarray_view(const Janet *argv, int32_t n,JanetTArrayType type); - +JANET_API JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n); +JANET_API JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, JanetTArrayType type); + #endif From febfefa4b20f013b914858f5b91dc4d7aa75f178 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Mon, 25 Feb 2019 02:21:10 +0100 Subject: [PATCH 15/18] Added tarray/slice and fix buffer size --- examples/tarray.janet | 7 ++-- src/core/typedarray.c | 77 +++++++++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/examples/tarray.janet b/examples/tarray.janet index 689c56c6..eca7749b 100644 --- a/examples/tarray.janet +++ b/examples/tarray.janet @@ -59,11 +59,11 @@ (matrix/print A) (loop (i :range (0 nr) j :range (0 nc)) - (matrix/set* A i j i))) + (matrix/set* A i j i)) (matrix/print A) (loop (i :range (0 nr) j :range (0 nc)) - (matrix/set** A i j i))) + (matrix/set** A i j i)) (matrix/print A) (print "tarray") @@ -84,3 +84,6 @@ (printf "%p" (tarray/properties b)) (print (b 0)) (print (b 1)) + + + diff --git a/src/core/typedarray.c b/src/core/typedarray.c index a203c368..f3863748 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -66,6 +66,7 @@ static size_t ta_type_sizes[] = { sizeof(ta_int64_t), sizeof(ta_float32_t), sizeof(ta_float64_t), + 0, }; #define TA_COUNT_TYPES (JANET_TARRAY_TYPE_float64 + 1) #define TA_ATOM_MAXSIZE 8 @@ -211,8 +212,11 @@ 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) { \ + if ((stride<1) || (size <1)) { \ + janet_panic("stride and size should be > 0"); \ + }; \ TA_View_##thetype * tview=(TA_View_##thetype *) view; \ - size_t buf_size=offset+(size-1)*(sizeof(ta_##thetype##_t))*stride+1; \ + size_t buf_size=offset+(sizeof(ta_##thetype##_t))*((size-1)*stride+1); \ if (buf==NULL) { \ buf=(JanetTArrayBuffer *)janet_abstract(&ta_buffer_type,sizeof(JanetTArrayBuffer)); \ ta_buffer_init(buf,buf_size); \ @@ -349,10 +353,6 @@ JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, JanetTArrayT } } - - - - static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { janet_arity(argc, 2, 5); size_t offset = 0; @@ -403,20 +403,27 @@ static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - if (!is_ta_anytype(argv[0])) - janet_panic("expected typed array"); - JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[0]); - JanetKV *props = janet_struct_begin(6); - janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number(view->size)); - janet_struct_put(props, janet_ckeywordv("byte-offset"), janet_wrap_number((uint8_t *)(view->data) - view->buffer->data)); - janet_struct_put(props, janet_ckeywordv("stride"), janet_wrap_number(view->stride)); - janet_struct_put(props, janet_ckeywordv("type"), janet_ckeywordv(ta_type_names[view->type])); - janet_struct_put(props, janet_ckeywordv("type-size"), janet_wrap_number(ta_type_sizes[view->type])); - janet_struct_put(props, janet_ckeywordv("buffer"), janet_wrap_abstract(view->buffer)); - return janet_wrap_struct(janet_struct_end(props)); + if (is_ta_anytype(argv[0])) { + JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[0]); + JanetKV *props = janet_struct_begin(6); + janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number(view->size)); + janet_struct_put(props, janet_ckeywordv("byte-offset"), janet_wrap_number((uint8_t *)(view->data) - view->buffer->data)); + janet_struct_put(props, janet_ckeywordv("stride"), janet_wrap_number(view->stride)); + janet_struct_put(props, janet_ckeywordv("type"), janet_ckeywordv(ta_type_names[view->type])); + janet_struct_put(props, janet_ckeywordv("type-size"), janet_wrap_number(ta_type_sizes[view->type])); + janet_struct_put(props, janet_ckeywordv("buffer"), janet_wrap_abstract(view->buffer)); + return janet_wrap_struct(janet_struct_end(props)); + } else { + JanetTArrayBuffer *buffer = janet_gettarray_buffer(argv, 0); + JanetKV *props = janet_struct_begin(3); + janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number(buffer->size)); + 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 for test 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); @@ -430,6 +437,34 @@ static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { return janet_wrap_struct(janet_struct_end(props)); } +static Janet cfun_typed_array_slice(int32_t argc, Janet *argv) { + janet_arity(argc, 1, 3); + JanetTArrayView *src = janet_gettarray_view(argv, 0, JANET_TARRAY_TYPE_any); + const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(argv[0])); + JanetRange range; + int32_t length = (int32_t)src->size; + if (argc == 1) { + range.start = 0; + range.end = length; + } else if (argc == 2) { + range.start = janet_gethalfrange(argv, 1, length, "start"); + range.end = length; + } else { + range.start = janet_gethalfrange(argv, 1, length, "start"); + range.end = janet_gethalfrange(argv, 2, length, "end"); + if (range.end < range.start) + range.end = range.start; + } + JanetArray *array = janet_array(range.end - range.start); + if (array->data) { + for (int32_t i = range.start; i < range.end; i++) { + array->data[i - range.start] = at->get(src, janet_wrap_number(i)); + } + } + array->count = range.end - range.start; + return janet_wrap_array(array); +} + static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { janet_arity(argc, 4, 5); @@ -527,6 +562,14 @@ static const JanetReg ta_cfuns[] = { "memory can overlap" ) }, + { + "tarray/slice", cfun_typed_array_slice, + JDOC("(tarray/slice tarr [, start=0 [, end=(size tarr)]])\n\n" + "Takes a slice of typed array from start to end. The range is half" + "open, [start, end). Indexes can also be negative, indicating indexing" + "from the end of the end of the typed array. By default, start is 0 and end is" + "the size of the typed array. Returns a new janet array.") + }, { "abstract/properties", cfun_abstract_properties, JDOC("(abstract/properties tag)\n\n" From fb5119bf43fcb4bd6890b05977f2c204b7a231ad Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Mon, 25 Feb 2019 18:49:04 +0100 Subject: [PATCH 16/18] Added some tests (suite 5) --- examples/tarray.janet | 26 ++++++++------------ src/core/typedarray.c | 8 +++---- test/suite5.janet | 55 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 test/suite5.janet diff --git a/examples/tarray.janet b/examples/tarray.janet index eca7749b..b55fa58b 100644 --- a/examples/tarray.janet +++ b/examples/tarray.janet @@ -1,3 +1,5 @@ +# naive matrix implementation for testing typed array + (defmacro printf [& xs] ['print ['string/format (splice xs)]]) (defn matrix [nrow ncol] {:nrow nrow :ncol ncol :array (tarray/new :float64 (* nrow ncol))}) @@ -66,24 +68,16 @@ (matrix/set** A i j i)) (matrix/print A) -(print "tarray") -(tarray/print (A :array)) (printf "properties:\n%p" (tarray/properties (A :array))) - -(printf "row properties:\n%p" (tarray/properties (matrix/row A 1))) - - -# test marshalling - -(def a (tarray/new :float64 20)) -(set (a 0) math/pi) -(set (a 1) 1234) - -(def b (unmarshal (marshal a))) -(printf "%p" (tarray/properties b)) -(print (b 0)) -(print (b 1)) +(for i 0 nr + (printf "row properties:[%i]\n%p" i (tarray/properties (matrix/row A i)))) +(for i 0 nc + (printf "col properties:[%i]\n%p" i (tarray/properties (matrix/column A i)))) + + + + diff --git a/src/core/typedarray.c b/src/core/typedarray.c index f3863748..9c519164 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -205,7 +205,7 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ index = (size_t)janet_unwrap_integer(key); \ TA_View_##type * array=(TA_View_##type *)p; \ if (index >= array->size) { \ - janet_panic("typed array out of bound"); \ + janet_panic("typed array out of bounds"); \ } \ array->data[index*array->stride]=(ta_##type##_t)janet_unwrap_number(value); \ } @@ -222,7 +222,7 @@ void ta_put_##type(void *p, Janet key,Janet value) { \ ta_buffer_init(buf,buf_size); \ } \ if (buf->sizesize,buf_size); \ } \ tview->buffer=buf; \ tview->stride=stride; \ @@ -488,7 +488,7 @@ static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { ps += step_src; } } else { - janet_panic("typed array copy out of bound"); + janet_panic("typed array copy out of bounds"); } return janet_wrap_nil(); } @@ -518,7 +518,7 @@ static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) { ps += step_src; } } else { - janet_panic("typed array swap out of bound"); + janet_panic("typed array swap out of bounds"); } return janet_wrap_nil(); } diff --git a/test/suite5.janet b/test/suite5.janet new file mode 100644 index 00000000..083e9e54 --- /dev/null +++ b/test/suite5.janet @@ -0,0 +1,55 @@ +# Copyright (c) 2019 Calvin Rose & contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +(import test/helper :prefix "" :exit true) +(start-suite 5) +# some tests typed array + +(assert-no-error + "create some typed array" + (do + (def a (tarray/new :float64 10)) + (def b (tarray/new :float64 5 2 0 a)) + (def c (tarray/new :uint32 20)) + )) + +(assert-no-error + "create some typed array from buffer" + (do + (def buf (tarray/buffer (+ 64 (* (+ 1 (* (- 10 1) 2)) 8)))) + (def b (tarray/new :float64 10 2 64 buf)))) + +(def a (tarray/new :float64 10)) +(def b (tarray/new :float64 5 2 0 a)) + +(assert-no-error + "fill tarray" + (for i 0 (tarray/length a) + (set (a i) i))) + +(assert (= (tarray/buffer a) (tarray/buffer b)) "tarray views pointing same buffer") +(assert (= (a 2) (b 1) ) "tarray views pointing same buffer") +(assert (= ((tarray/slice b) 3) (b 3) (a 6) 6) "tarray slice") +(assert (= ((tarray/slice b 1) 2) (b 3) (a 6) 6) "tarray slice") + +(assert (= ((unmarshal (marshal b)) 3) (b 3)) "marshal") + +(end-suite) + From 3eb44f1f79f1820dcf9394a6fe7ea3caa6895b12 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Tue, 26 Feb 2019 00:21:03 +0100 Subject: [PATCH 17/18] Fix buffer allocation --- src/core/typedarray.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 9c519164..3e5ffac2 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -83,11 +83,14 @@ static JanetTArrayType get_ta_type_by_name(const uint8_t *name) { - - - static JanetTArrayBuffer *ta_buffer_init(JanetTArrayBuffer *buf, size_t size) { - buf->data = (uint8_t *)calloc(size, sizeof(uint8_t)); + buf->data = NULL; + if (size > 0) { + buf->data = (uint8_t *)calloc(size, sizeof(uint8_t)); + if (buf->data == NULL) { + JANET_OUT_OF_MEMORY; + } + } buf->size = size; #ifdef JANET_BIG_ENDIAN buf->flags = TA_FLAG_BIG_ENDIAN; From 59393fc73bd0f2a9d626cb8abcae4f22f6027029 Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Tue, 26 Feb 2019 02:28:24 +0100 Subject: [PATCH 18/18] Added some guards in ta_view unmarshalling to protect against bad marshalled data. --- src/core/typedarray.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 3e5ffac2..fb802ecf 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -165,6 +165,9 @@ static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) { janet_unmarshal_size(ctx, &offset); janet_unmarshal_janet(ctx, &buffer); view->buffer = (JanetTArrayBuffer *)janet_unwrap_abstract(buffer); + size_t buf_need_size = offset + (janet_tarray_type_size(view->type)) * ((view->size - 1) * view->stride + 1); + if (view->buffer->size < buf_need_size) + janet_panic("bad typed array offset in marshalled data"); view->data = view->buffer->data + offset; }