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:
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)