diff --git a/.ikc3_history b/.ikc3_history
index be370d5..b11d533 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,15 +1,3 @@
-type(1234567890123456789)
-type(123456789012345678901234)
-type(123456789012345678901234/2)
-123456789012345678901234/2
-123456789012345678901234/2 * 0.1
-(123456789012345678901234/2) * 0.1
-(F128) 123456789012345678901234/2 * 0.1
-List.to_array
-0 - 2
-Tuple[]
-type(Tuple[])
-type((Tuple[]) {{1, 2, 3}})
type((Tuple[]) {1, 2, 3})
[1][0]
([1])[0]
@@ -97,3 +85,15 @@ quote t = Thread.new(fn () { puts("ok") })
List.count(10)
List.map(List.count(10), fn (x) { {x, x} })
List.map(List.count(10), fn (x) { %{id: x} })
+s = Serialize.new()
+Serialize.tag(s, 123)
+s = Serialize.new()
+Serialize.tag(s, 123)
+s = Serialize.new()
+Serialize.tag(s, 123)
+Serialize.to_str(s)
+'U+123'
+'U+123'
+Serialize.tag(s, 66)
+Serialize.to_str(s)
+Serialize.delete(s)
diff --git a/lib/kc3/0.1/serialize.kc3 b/lib/kc3/0.1/serialize.kc3
index 2322ea8..28633cd 100644
--- a/lib/kc3/0.1/serialize.kc3
+++ b/lib/kc3/0.1/serialize.kc3
@@ -6,4 +6,6 @@ defmodule Serialize do
def tag = cfn Bool "kc3_serialize_tag" (Ptr, Tag)
+ def to_str = cfn Str "kc3_serialize_to_str" (Ptr, Result)
+
end
diff --git a/libkc3/callable.c b/libkc3/callable.c
index a089aec..102e474 100644
--- a/libkc3/callable.c
+++ b/libkc3/callable.c
@@ -16,12 +16,13 @@
#include "callable.h"
#include "cfn.h"
#include "fn.h"
+#include "mutex.h"
#include "tag.h"
void callable_delete (s_callable *callable)
{
assert(callable);
- /* FIXME: lock callable lock. */
+ mutex_lock(&callable->mutex);
if (callable->reference_count <= 0)
goto clean;
if (--callable->reference_count > 0)
@@ -31,12 +32,12 @@ void callable_delete (s_callable *callable)
case CALLABLE_FN: fn_clean(&callable->data.fn); break;
case CALLABLE_VOID: break;
}
- /* FIXME: unlock callable lock. */
+ mutex_unlock(&callable->mutex);
+ mutex_clean(&callable->mutex);
free(callable);
return;
clean:
- /* FIXME: unlock callable lock. */
- return;
+ mutex_unlock(&callable->mutex);
}
s_callable * callable_new (void)
@@ -44,6 +45,7 @@ s_callable * callable_new (void)
s_callable *callable;
if (! (callable = alloc(sizeof(s_callable))))
return NULL;
+ mutex_init(&callable->mutex);
return callable;
}
@@ -75,8 +77,14 @@ s_callable * callable_new_copy (s_callable *src)
s_callable * callable_new_ref (s_callable *callable)
{
assert(callable);
- assert(callable->reference_count > 0);
+ mutex_lock(&callable->mutex);
+ if (callable->reference_count <= 0) {
+ err_puts("callable_new_ref: reference count <= 0");
+ assert(! "callable_new_ref: reference count <= 0");
+ abort();
+ }
callable->reference_count++;
+ mutex_unlock(&callable->mutex);
return callable;
}
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index bc6f6e3..fc9e7b1 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -550,6 +550,18 @@ s_list ** kc3_search_modules (s_list **dest)
return env_search_modules(g_kc3_env, dest);
}
+void kc3_serialize_delete (s_serialize **serialize)
+{
+ serialize_delete(*serialize);
+}
+
+s_serialize ** kc3_serialize_new (s_serialize **serialize)
+{
+ assert(serialize);
+ *serialize = serialize_new();
+ return serialize;
+}
+
bool kc3_serialize_tag (s_serialize **serialize, const s_tag *tag)
{
if (! serialize_tag(*serialize, tag))
@@ -557,6 +569,11 @@ bool kc3_serialize_tag (s_serialize **serialize, const s_tag *tag)
return true;
}
+s_str * kc3_serialize_to_str (s_serialize **serialize, s_str *dest)
+{
+ return serialize_to_str(*serialize, dest);
+}
+
s_list ** kc3_stacktrace (s_list **dest)
{
return env_stacktrace(g_kc3_env, dest);
diff --git a/libkc3/serialize.c b/libkc3/serialize.c
index 873b6de..db91924 100644
--- a/libkc3/serialize.c
+++ b/libkc3/serialize.c
@@ -31,7 +31,8 @@ DEF_SERIALIZE(bool)
void serialize_clean (s_serialize *serialize)
{
assert(serialize);
- (void) serialize;
+ buf_clean(&serialize->buf);
+ buf_clean(&serialize->heap);
}
void serialize_delete (s_serialize *serialize)
@@ -40,13 +41,24 @@ void serialize_delete (s_serialize *serialize)
free(serialize);
}
+s_serialize * serialize_character (s_serialize *serialize,
+ character c)
+{
+ return serialize_u32(serialize, c);
+}
+
s_serialize * serialize_init (s_serialize *serialize)
{
s_serialize tmp = {0};
+ buf_init_alloc(&tmp.heap, 1024024);
+ buf_init_alloc(&tmp.buf, 1024024);
*serialize = tmp;
return serialize;
}
+s_serialize * serialize_list (s_serialize *serialize,
+ const s_list *list);
+
s_serialize * serialize_new (void)
{
s_serialize *serialize;
@@ -56,40 +68,63 @@ s_serialize * serialize_new (void)
return serialize;
}
-s_str * serialize_to_buf (const s_serialize *serialize, s_buf *buf);
-
-s_str * serialize_to_str (const s_serialize *serialize, s_str *dest);
-
-s_serialize * serialize_bool (s_serialize *serialize, bool b);
+DEF_SERIALIZE(s8)
+DEF_SERIALIZE(s16)
+DEF_SERIALIZE(s32)
+DEF_SERIALIZE(s64)
-s_serialize * serialize_character (s_serialize *serialize,
- character c);
+s_serialize * serialize_str (s_serialize *serialize, const s_str *src)
+{
+ sw r;
+ assert(serialize);
+ assert(src);
+ if (! serialize_u32(serialize, src->size))
+ return NULL;
+ if ((r = buf_write(&serialize->buf, src->ptr.pchar, src->size)) <= 0)
+ return NULL;
+ return serialize;
+}
-s_serialize * serialize_list (s_serialize *serialize,
- const s_list *list);
+DEF_SERIALIZE(sw)
s_serialize * serialize_tag (s_serialize *serialize, const s_tag *tag)
{
switch (tag->type){
- case TAG_U8: return serialize_u8(serialize, tag->data.u8);
- default: break;
+ case TAG_BOOL: return serialize_bool(serialize, tag->data.bool);
+ case TAG_CHARACTER:
+ return serialize_character(serialize, tag->data.character);
+ case TAG_S8: return serialize_s8(serialize, tag->data.s8);
+ case TAG_S16: return serialize_s16(serialize, tag->data.s16);
+ case TAG_S32: return serialize_s32(serialize, tag->data.s32);
+ case TAG_S64: return serialize_s64(serialize, tag->data.s64);
+ case TAG_STR: return serialize_str(serialize, &tag->data.str);
+ case TAG_SW: return serialize_sw(serialize, tag->data.sw);
+ case TAG_U8: return serialize_u8(serialize, tag->data.u8);
+ case TAG_U16: return serialize_u16(serialize, tag->data.u16);
+ case TAG_U32: return serialize_u32(serialize, tag->data.u32);
+ case TAG_U64: return serialize_u64(serialize, tag->data.u64);
+ case TAG_UW: return serialize_uw(serialize, tag->data.uw);
+ default: break;
}
err_puts("serialize_tag: not implemented");
assert(! "serialize_tag: not implemented");
return NULL;
}
-s_serialize * serialize_tuple (s_serialize *serialize,
- const s_tuple *tuple);
+sw serialize_to_buf (s_serialize *serialize, s_buf *buf)
+{
+ return buf_xfer(&serialize->buf, buf,
+ serialize->buf.wpos - serialize->buf.rpos);
+}
-DEF_SERIALIZE(s8)
-DEF_SERIALIZE(s16)
-DEF_SERIALIZE(s32)
-DEF_SERIALIZE(s64)
+s_str * serialize_to_str (s_serialize *serialize, s_str *dest)
+{
+ return buf_read_to_str(&serialize->buf, dest);
+}
-s_serialize * serialize_str (s_serialize *serialize, const s_str *str);
+s_serialize * serialize_tuple (s_serialize *serialize,
+ const s_tuple *tuple);
-DEF_SERIALIZE(sw)
DEF_SERIALIZE(u8)
DEF_SERIALIZE(u16)
DEF_SERIALIZE(u32)
diff --git a/libkc3/serialize.h b/libkc3/serialize.h
index 7b4f0cb..40d5403 100644
--- a/libkc3/serialize.h
+++ b/libkc3/serialize.h
@@ -30,9 +30,9 @@
void serialize_clean (s_serialize *serialize);
s_serialize * serialize_init (s_serialize *serialize);
-/* Observers. */
-s_str * serialize_to_buf (const s_serialize *serialize, s_buf *buf);
-s_str * serialize_to_str (const s_serialize *serialize, s_str *dest);
+/* Heap-allocation functions, call serialize_delete after use. */
+void serialize_delete (s_serialize *serialize);
+s_serialize * serialize_new (void);
/* Operators. */
PROTO_SERIALIZE(bool);
@@ -41,6 +41,10 @@ s_serialize * serialize_list (s_serialize *serialize,
const s_list *list);
s_serialize * serialize_tag (s_serialize *serialize,
const s_tag *tag);
+sw serialize_to_buf (s_serialize *serialize,
+ s_buf *buf);
+s_str * serialize_to_str (s_serialize *serialize,
+ s_str *dest);
s_serialize * serialize_tuple (s_serialize *serialize,
const s_tuple *tuple);
PROTO_SERIALIZE(s8);
diff --git a/libkc3/types.h b/libkc3/types.h
index 27597b5..d0d0c85 100644
--- a/libkc3/types.h
+++ b/libkc3/types.h
@@ -454,7 +454,7 @@ struct integer {
struct str {
u_ptr_w free; /**< Pointer to free or NULL. */
- uw size; /**< Size in bytes. */
+ u32 size; /**< Size in bytes. */
u_ptr ptr; /**< Pointer to memory. */
};
@@ -561,6 +561,7 @@ struct callable {
e_callable_type type;
sw reference_count;
u_callable_data data;
+ s_mutex mutex;
};
union tag_data {