klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 8f824bfe0693d5b047a311f7c7e66c3276c4cd9d
parent 378080ecf1439d64c9530388647d791cbda57c42
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed, 16 Nov 2011 19:51:02 -0300

Changed the bytevector constructors in preparation for new copy applicatives.

Diffstat:
Msrc/kbytevector.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/kbytevector.h | 30++++++++++++++++++++++++------
Msrc/kgbytevectors.c | 24++++++------------------
Msrc/kgffi.c | 18++++++++++++++----
Msrc/kstate.c | 2+-
Msrc/kstring.c | 1+
Msrc/kstring.h | 21---------------------
7 files changed, 125 insertions(+), 63 deletions(-)

diff --git a/src/kbytevector.c b/src/kbytevector.c @@ -13,38 +13,104 @@ #include "kgc.h" /* Constructors */ -TValue kbytevector_new_g(klisp_State *K, bool m, uint32_t size) + +/* General constructor for bytevectors */ +TValue kbytevector_new_bs_g(klisp_State *K, bool m, const uint8_t *buf, + uint32_t size) +{ + return m? kbytevector_new_bs(K, buf, size) : + kbytevector_new_bs_imm(K, buf, size); +} + +/* +** Constructors for immutable bytevectors +*/ + +/* main constructor for immutable bytevectors */ +TValue kbytevector_new_bs_imm(klisp_State *K, const uint8_t *buf, uint32_t size) { - Bytevector *new_bytevector; + /* Does it make sense to put them in the string table + (i.e. interning them)?, we have two different constructors just in case */ /* XXX: find a better way to do this! */ if (size == 0 && ttisbytevector(K->empty_bytevector)) { return K->empty_bytevector; } - new_bytevector = klispM_malloc(K, sizeof(Bytevector) + size); + Bytevector *new_bb; + + if (size > (SIZE_MAX - sizeof(Bytevector))) + klispM_toobig(K); + + new_bb = (Bytevector *) klispM_malloc(K, sizeof(Bytevector) + size); /* header + gc_fields */ - klispC_link(K, (GCObject *) new_bytevector, K_TBYTEVECTOR, m? 0 : K_FLAG_IMMUTABLE); + klispC_link(K, (GCObject *) new_bb, K_TBYTEVECTOR, K_FLAG_IMMUTABLE); /* bytevector specific fields */ - new_bytevector->mark = KFALSE; - new_bytevector->size = size; + new_bb->mark = KFALSE; + new_bb->size = size; - /* clear the buffer */ - memset(new_bytevector->b, 0, size); + if (size != 0) { + memcpy(new_bb->b, buf, size); + } + + return gc2bytevector(new_bb); +} + +/* +** Constructors for mutable bytevectors +*/ - return gc2bytevector(new_bytevector); +/* main constructor for mutable bytevectors */ +/* with just size */ +TValue kbytevector_new_s(klisp_State *K, uint32_t size) +{ + Bytevector *new_bb; + + if (size == 0) { + klisp_assert(ttisbytevector(K->empty_bytevector)); + return K->empty_bytevector; + } + + new_bb = klispM_malloc(K, sizeof(Bytevector) + size); + + /* header + gc_fields */ + klispC_link(K, (GCObject *) new_bb, K_TBYTEVECTOR, 0); + + /* bytevector specific fields */ + new_bb->mark = KFALSE; + new_bb->size = size; + + /* the buffer is initialized elsewhere */ + + return gc2bytevector(new_bb); } -TValue kbytevector_new(klisp_State *K, uint32_t size) +/* with buffer & size */ +TValue kbytevector_new_bs(klisp_State *K, const uint8_t *buf, uint32_t size) { - return kbytevector_new_g(K, true, size); + if (size == 0) { + klisp_assert(ttisbytevector(K->empty_bytevector)); + return K->empty_bytevector; + } + + TValue new_bb = kbytevector_new_s(K, size); + memcpy(kbytevector_buf(new_bb), buf, size); + return new_bb; } -TValue kbytevector_new_imm(klisp_State *K, uint32_t size) +/* with size and fill uint8_t */ +TValue kbytevector_new_sf(klisp_State *K, uint32_t size, uint8_t fill) { - return kbytevector_new_g(K, false, size); + if (size == 0) { + klisp_assert(ttisbytevector(K->empty_bytevector)); + return K->empty_bytevector; + } + + TValue new_bb = kbytevector_new_s(K, size); + memset(kbytevector_buf(new_bb), fill, size); + return new_bb; } /* both obj1 and obj2 should be bytevectors */ diff --git a/src/kbytevector.h b/src/kbytevector.h @@ -10,13 +10,31 @@ #include "kobject.h" #include "kstate.h" -/* TODO change bytevector constructors to string like constructors */ -/* TODO change names to lua-like (e.g. klispB_new, etc) */ +/* TODO change names to be lua-like (e.g. klispBB_new, etc) */ -/* Constructors for bytevectors */ -TValue kbytevector_new_g(klisp_State *K, bool m, uint32_t size); -TValue kbytevector_new_imm(klisp_State *K, uint32_t size); -TValue kbytevector_new(klisp_State *K, uint32_t size); +/* General constructor for bytevectors */ +TValue kbytevector_new_bs_g(klisp_State *K, bool m, const uint8_t *buf, + uint32_t size); + +/* +** Constructors for immutable bytevectors +*/ + +/* main immutable bytevector constructor */ +/* with buffer & size */ +TValue kbytevector_new_bs_imm(klisp_State *K, const uint8_t *buf, uint32_t size); + +/* +** Constructors for mutable bytevectors +*/ + +/* main mutable bytevector constructor */ +/* with just size */ +TValue kbytevector_new_s(klisp_State *K, uint32_t size); +/* with buffer & size */ +TValue kbytevector_new_bs(klisp_State *K, const uint8_t *buf, uint32_t size); +/* with size & fill byte */ +TValue kbytevector_new_sf(klisp_State *K, uint32_t size, uint8_t fill); /* both obj1 and obj2 should be bytevectors, this compares byte by byte and doesn't differentiate immutable from mutable bytevectors */ diff --git a/src/kgbytevectors.c b/src/kgbytevectors.c @@ -51,16 +51,7 @@ void make_bytevector(klisp_State *K, TValue *xparams, TValue ptree, klispE_throw_simple(K, "size is too big"); return; } -/* XXX/TODO */ -/* TValue new_bytevector = kbytevector_new_sf(K, ivalue(tv_s), fill); */ - TValue new_bytevector = kbytevector_new(K, ivalue(tv_s)); - if (fill != 0) { - int32_t s = ivalue(tv_s); - uint8_t *ptr = kbytevector_buf(new_bytevector); - while(s--) - *ptr++ = fill; - } - + TValue new_bytevector = kbytevector_new_sf(K, ivalue(tv_s), fill); kapply_cc(K, new_bytevector); } @@ -148,14 +139,13 @@ void bytevector_copy(klisp_State *K, TValue *xparams, TValue ptree, if (tv_equal(bytevector, K->empty_bytevector)) { new_bytevector = bytevector; } else { - new_bytevector = kbytevector_new(K, kbytevector_size(bytevector)); - memcpy(kbytevector_buf(new_bytevector), - kbytevector_buf(bytevector), - kbytevector_size(bytevector)); + new_bytevector = kbytevector_new_bs(K, kbytevector_buf(bytevector), + kbytevector_size(bytevector)); } kapply_cc(K, new_bytevector); } + /* 13.2.9? bytevector->immutable-bytevector */ void bytevector_to_immutable_bytevector(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) @@ -169,10 +159,8 @@ void bytevector_to_immutable_bytevector(klisp_State *K, TValue *xparams, /* this includes the empty bytevector */ res_bytevector = bytevector; } else { - res_bytevector = kbytevector_new_imm(K, kbytevector_size(bytevector)); - memcpy(kbytevector_buf(res_bytevector), - kbytevector_buf(bytevector), - kbytevector_size(bytevector)); + res_bytevector = kbytevector_new_bs_imm(K, kbytevector_buf(bytevector), + kbytevector_size(bytevector)); } kapply_cc(K, res_bytevector); } diff --git a/src/kgffi.c b/src/kgffi.c @@ -484,10 +484,10 @@ void ffi_make_call_interface(klisp_State *K, TValue *xparams, TValue key = xparams[0]; krooted_tvs_push(K, key); size_t bytevector_size = sizeof(ffi_call_interface_t) + (sizeof(ffi_codec_t *) + sizeof(ffi_type)) * nargs; - TValue bytevector = kbytevector_new_imm(K, bytevector_size); - krooted_tvs_push(K, bytevector); - TValue enc = kmake_encapsulation(K, key, bytevector); - krooted_tvs_pop(K); + /* XXX was immutable, but there is no immutable bytevector constructor + without buffer now, is it really immutable?? see end of function + Andres Navarro */ + TValue bytevector = kbytevector_new_sf(K, bytevector_size, 0); krooted_tvs_pop(K); krooted_tvs_pop(K); krooted_tvs_pop(K); @@ -533,6 +533,16 @@ void ffi_make_call_interface(klisp_State *K, TValue *xparams, klispE_throw_simple(K, "unknown error in ffi_prep_cif"); return; } + /* XXX if it should really be immutable this is the only sane way I can + think of. If not, just remove. + Andres Navarro */ + krooted_tvs_push(K, bytevector); + bytevector = kbytevector_new_bs_imm(K, kbytevector_buf(bytevector), + kbytevector_size(bytevector)); + krooted_tvs_push(K, bytevector); + TValue enc = kmake_encapsulation(K, key, bytevector); + krooted_tvs_pop(K); + krooted_tvs_pop(K); kapply_cc(K, enc); } diff --git a/src/kstate.c b/src/kstate.c @@ -157,7 +157,7 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { /* MAYBE: fix it so we can remove empty_bytevector from roots */ /* XXX: find a better way to do this */ K->empty_bytevector = KNIL; /* trick constructor to create empty bytevector */ - K->empty_bytevector = kbytevector_new_imm(K, 0); + K->empty_bytevector = kbytevector_new_bs_imm(K, NULL, 0); /* initialize tokenizer */ diff --git a/src/kstring.c b/src/kstring.c @@ -156,6 +156,7 @@ TValue kstring_new_s(klisp_State *K, uint32_t size) String *new_str; if (size == 0) { + klisp_assert(ttisstring(K->empty_string)); return K->empty_string; } diff --git a/src/kstring.h b/src/kstring.h @@ -46,27 +46,6 @@ TValue kstring_new_b(klisp_State *K, const char *buf); /* with size & fill char */ TValue kstring_new_sf(klisp_State *K, uint32_t size, char fill); -/* macros for mutable & immutable versions of the above */ -#if 0 -#define kstring_new_s(K_, size_) \ - kstring_new_s_g(K_, true, size_) -#define kstring_new_bs(K_, buf_, size_) \ - kstring_new_bs_g(K_, true, buf_, size_) -#define kstring_new_b(K_, buf_) \ - kstring_new_b_g(K_, true, buf_) -#define kstring_new_sf(K_, size_, fill_) \ - kstring_new_sf_g(K_, true, size_, fill_) - -#define kstring_new_s_imm(K_, size_) \ - kstring_new_s_g(K_, false, size_) -#define kstring_new_bs_imm(K_, buf_, size_) \ - kstring_new_bs_g(K_, false, buf_, size_) -#define kstring_new_b_imm(K_, buf_) \ - kstring_new_b_g(K_, false, buf_) -#define kstring_new_sf_imm(K_, size_, fill_) \ - kstring_new_sf_g(K_, false, size_, fill_) -#endif - /* some macros to access the parts of the string */ #define kstring_buf(tv_) (tv2str(tv_)->b) #define kstring_size(tv_) (tv2str(tv_)->size)