add read/write methods for interfaces

This commit is contained in:
James McKaskill 2013-05-12 23:01:53 -04:00
parent 21e7c29a96
commit 7731509861
5 changed files with 323 additions and 172 deletions

View file

@ -2,9 +2,10 @@
#define CAT2(A,B) A ## B #define CAT2(A,B) A ## B
#define CAT(A,B) CAT2(A, B) #define CAT(A,B) CAT2(A, B)
#define UINT_T CAT(CAT(uint, SZ), _t) #define UINT_T CAT(CAT(uint, SZ), _t)
#define LIST_T CAT(capn_list, SZ)
#define FLIP CAT(capn_flip, SZ) #define FLIP CAT(capn_flip, SZ)
UINT_T CAT(capn_get,SZ) (CAT(capn_list,SZ) l, int off) { UINT_T CAT(capn_get,SZ) (LIST_T l, int off) {
char *d; char *d;
capn_ptr p = l.p; capn_ptr p = l.p;
if (off >= p.len) { if (off >= p.len) {
@ -32,7 +33,7 @@ UINT_T CAT(capn_get,SZ) (CAT(capn_list,SZ) l, int off) {
} }
} }
int CAT(capn_getv,SZ) (CAT(capn_list,SZ) l, int off, UINT_T *to, int sz) { int CAT(capn_getv,SZ) (LIST_T l, int off, UINT_T *to, int sz) {
int i; int i;
capn_ptr p = l.p; capn_ptr p = l.p;
if (off + sz > p.len) { if (off + sz > p.len) {
@ -71,7 +72,7 @@ int CAT(capn_getv,SZ) (CAT(capn_list,SZ) l, int off, UINT_T *to, int sz) {
} }
} }
int CAT(capn_set,SZ) (CAT(capn_list,SZ) l, int off, UINT_T v) { int CAT(capn_set,SZ) (LIST_T l, int off, UINT_T v) {
char *d; char *d;
capn_ptr p = l.p; capn_ptr p = l.p;
if (off >= p.len) { if (off >= p.len) {
@ -100,7 +101,7 @@ int CAT(capn_set,SZ) (CAT(capn_list,SZ) l, int off, UINT_T v) {
} }
} }
int CAT(capn_setv,SZ) (CAT(capn_list,SZ) l, int off, const UINT_T *from, int sz) { int CAT(capn_setv,SZ) (LIST_T l, int off, const UINT_T *from, int sz) {
int i; int i;
capn_ptr p = l.p; capn_ptr p = l.p;
if (off + sz > p.len) { if (off + sz > p.len) {
@ -139,6 +140,15 @@ int CAT(capn_setv,SZ) (CAT(capn_list,SZ) l, int off, const UINT_T *from, int sz)
} }
} }
LIST_T CAT(capn_new_list,SZ) (struct capn_segment *seg, int sz) {
LIST_T l = {{CAPN_LIST}};
l.p.seg = seg;
l.p.len = sz;
l.p.datasz = SZ/8;
new_object(&l.p, sz*(SZ/8));
return l;
}
#undef FLIP #undef FLIP
#undef UINT_T #undef UINT_T
#undef CAT #undef CAT

39
capn.c
View file

@ -903,22 +903,6 @@ int capn_setv1(capn_list1 l, int off, const uint8_t *data, int sz) {
} }
} }
#define SZ 8
#include "capn-list.inc"
#undef SZ
#define SZ 16
#include "capn-list.inc"
#undef SZ
#define SZ 32
#include "capn-list.inc"
#undef SZ
#define SZ 64
#include "capn-list.inc"
#undef SZ
/* pull out whether we add a tag or not as a define so the unit test can /* pull out whether we add a tag or not as a define so the unit test can
* test double far pointers by not creating tags */ * test double far pointers by not creating tags */
#ifndef ADD_TAG #ifndef ADD_TAG
@ -928,6 +912,11 @@ int capn_setv1(capn_list1 l, int off, const uint8_t *data, int sz) {
static void new_object(capn_ptr *p, int bytes) { static void new_object(capn_ptr *p, int bytes) {
struct capn_segment *s = p->seg; struct capn_segment *s = p->seg;
if (!s) {
memset(p, 0, sizeof(*p));
return;
}
if (!bytes) if (!bytes)
return; return;
@ -1069,7 +1058,7 @@ int capn_set_text(capn_ptr p, int off, capn_text tgt) {
m.data = (char*)tgt.str; m.data = (char*)tgt.str;
m.len = tgt.len + 1; m.len = tgt.len + 1;
m.datasz = 1; m.datasz = 1;
} else if (p.seg && tgt.str) { } else if (tgt.str) {
m = capn_new_string(p.seg, tgt.str, tgt.len); m = capn_new_string(p.seg, tgt.str, tgt.len);
} }
return capn_setp(p, off, m); return capn_setp(p, off, m);
@ -1083,3 +1072,19 @@ capn_data capn_get_data(capn_ptr p, int off) {
} }
return ret; return ret;
} }
#define SZ 8
#include "capn-list.inc"
#undef SZ
#define SZ 16
#include "capn-list.inc"
#undef SZ
#define SZ 32
#include "capn-list.inc"
#undef SZ
#define SZ 64
#include "capn-list.inc"
#undef SZ

37
capn.h
View file

@ -118,6 +118,13 @@ typedef struct {capn_ptr p;} capn_list16;
typedef struct {capn_ptr p;} capn_list32; typedef struct {capn_ptr p;} capn_list32;
typedef struct {capn_ptr p;} capn_list64; typedef struct {capn_ptr p;} capn_list64;
struct capn_msg {
struct capn_segment *seg;
uint64_t iface;
uint16_t method;
capn_ptr args;
};
/* capn_append_segment appends a segment to a session */ /* capn_append_segment appends a segment to a session */
void capn_append_segment(struct capn*, struct capn_segment*); void capn_append_segment(struct capn*, struct capn_segment*);
@ -178,13 +185,13 @@ int capn_setv64(capn_list64 p, int off, const uint64_t *data, int sz);
*/ */
capn_ptr capn_new_struct(struct capn_segment *seg, int datasz, int ptrs); capn_ptr capn_new_struct(struct capn_segment *seg, int datasz, int ptrs);
capn_ptr capn_new_interface(struct capn_segment *seg, int datasz, int ptrs); capn_ptr capn_new_interface(struct capn_segment *seg, int datasz, int ptrs);
capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz);
capn_ptr capn_new_list(struct capn_segment *seg, int sz, int datasz, int ptrs); capn_ptr capn_new_list(struct capn_segment *seg, int sz, int datasz, int ptrs);
capn_list1 capn_new_list1(struct capn_segment *seg, int sz); capn_list1 capn_new_list1(struct capn_segment *seg, int sz);
capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz); capn_list8 capn_new_list8(struct capn_segment *seg, int sz);
CAPN_INLINE capn_list8 capn_new_list8(struct capn_segment *seg, int sz); capn_list16 capn_new_list16(struct capn_segment *seg, int sz);
CAPN_INLINE capn_list16 capn_new_list16(struct capn_segment *seg, int sz); capn_list32 capn_new_list32(struct capn_segment *seg, int sz);
CAPN_INLINE capn_list32 capn_new_list32(struct capn_segment *seg, int sz); capn_list64 capn_new_list64(struct capn_segment *seg, int sz);
CAPN_INLINE capn_list64 capn_new_list64(struct capn_segment *seg, int sz);
/* capn_read|write_* functions read/write struct values /* capn_read|write_* functions read/write struct values
* off is the offset into the structure in bytes * off is the offset into the structure in bytes
@ -367,26 +374,6 @@ CAPN_INLINE uint64_t capn_from_f64(double v) {
return u.u; return u.u;
} }
CAPN_INLINE capn_list8 capn_new_list8(struct capn_segment *seg, int sz) {
capn_list8 p;
p.p = capn_new_list(seg, sz, 1, 0);
return p;
}
CAPN_INLINE capn_list16 capn_new_list16(struct capn_segment *seg, int sz) {
capn_list16 p;
p.p = capn_new_list(seg, sz, 2, 0);
return p;
}
CAPN_INLINE capn_list32 capn_new_list32(struct capn_segment *seg, int sz) {
capn_list32 p;
p.p = capn_new_list(seg, sz, 4, 0);
return p;
}
CAPN_INLINE capn_list64 capn_new_list64(struct capn_segment *seg, int sz) {
capn_list64 p;
p.p = capn_new_list(seg, sz, 8, 0);
return p;
}
CAPN_INLINE int capn_set_data(capn_ptr p, int off, capn_data d) { CAPN_INLINE int capn_set_data(capn_ptr p, int off, capn_data d) {
return capn_setp(p, off, d.p); return capn_setp(p, off, d.p);
} }

View file

@ -81,123 +81,115 @@ static void define_enum(struct node *n) {
fprintf(HDR, "\n};\n"); fprintf(HDR, "\n};\n");
} }
struct type {
struct Type t;
struct Type lt;
const char *name;
struct str buf;
};
struct value { struct value {
struct type t; struct Type t;
const char *tname;
struct str buf;
struct Value v; struct Value v;
capn_ptr ptr; capn_ptr ptr;
int64_t num; int64_t num;
}; };
static void decode_type(struct type *t, Type_ptr p) { static void decode_value(struct value* v, Type_ptr type, Value_ptr value, const char *symbol) {
read_Type(&t->t, p); struct Type lt;
memset(v, 0, sizeof(*v));
read_Type(&v->t, type);
read_Value(&v->v, value);
switch (t->t.body_tag) { switch (v->t.body_tag) {
case Type_voidType: case Type_voidType:
t->name = "void"; v->tname = "void";
break; break;
case Type_boolType: case Type_boolType:
t->name = "unsigned int"; v->tname = "unsigned";
break; break;
case Type_int8Type: case Type_int8Type:
t->name = "int8_t"; v->tname = "int8_t";
break; break;
case Type_int16Type: case Type_int16Type:
t->name = "int16_t"; v->tname = "int16_t";
break; break;
case Type_int32Type: case Type_int32Type:
t->name = "int32_t"; v->tname = "int32_t";
break; break;
case Type_int64Type: case Type_int64Type:
t->name = "int64_t"; v->tname = "int64_t";
break; break;
case Type_uint8Type: case Type_uint8Type:
t->name = "uint8_t"; v->tname = "uint8_t";
break; break;
case Type_uint16Type: case Type_uint16Type:
t->name = "uint16_t"; v->tname = "uint16_t";
break; break;
case Type_uint32Type: case Type_uint32Type:
t->name = "uint32_t"; v->tname = "uint32_t";
break; break;
case Type_uint64Type: case Type_uint64Type:
t->name = "uint64_t"; v->tname = "uint64_t";
break; break;
case Type_float32Type: case Type_float32Type:
t->name = "float"; v->tname = "float";
break; break;
case Type_float64Type: case Type_float64Type:
t->name = "double"; v->tname = "double";
break; break;
case Type_textType: case Type_textType:
t->name = "capn_text"; v->tname = "capn_text";
break; break;
case Type_dataType: case Type_dataType:
t->name = "capn_data"; v->tname = "capn_data";
break; break;
case Type_enumType: case Type_enumType:
t->name = strf(&t->buf, "enum %s", find_node(t->t.body.enumType)->name.str); v->tname = strf(&v->buf, "enum %s", find_node(v->t.body.enumType)->name.str);
break; break;
case Type_structType: case Type_structType:
case Type_interfaceType: case Type_interfaceType:
t->name = strf(&t->buf, "%s_ptr", find_node(t->t.body.structType)->name.str); v->tname = strf(&v->buf, "%s_ptr", find_node(v->t.body.structType)->name.str);
break; break;
case Type_objectType: case Type_objectType:
t->name = "capn_ptr"; v->tname = "capn_ptr";
break; break;
case Type_listType: case Type_listType:
read_Type(&t->lt, t->t.body.listType); read_Type(&lt, v->t.body.listType);
switch (t->lt.body_tag) { switch (lt.body_tag) {
case Type_voidType: case Type_voidType:
t->name = "capn_ptr"; v->tname = "capn_ptr";
break; break;
case Type_boolType: case Type_boolType:
t->name = "capn_list1"; v->tname = "capn_list1";
break; break;
case Type_int8Type: case Type_int8Type:
case Type_uint8Type: case Type_uint8Type:
t->name = "capn_list8"; v->tname = "capn_list8";
break; break;
case Type_int16Type: case Type_int16Type:
case Type_uint16Type: case Type_uint16Type:
case Type_enumType: case Type_enumType:
t->name = "capn_list16"; v->tname = "capn_list16";
break; break;
case Type_int32Type: case Type_int32Type:
case Type_uint32Type: case Type_uint32Type:
case Type_float32Type: case Type_float32Type:
t->name = "capn_list32"; v->tname = "capn_list32";
break; break;
case Type_int64Type: case Type_int64Type:
case Type_uint64Type: case Type_uint64Type:
case Type_float64Type: case Type_float64Type:
t->name = "capn_list64"; v->tname = "capn_list64";
break; break;
case Type_textType: case Type_textType:
case Type_dataType: case Type_dataType:
case Type_objectType: case Type_objectType:
case Type_listType: case Type_listType:
t->name = "capn_ptr"; v->tname = "capn_ptr";
break; break;
case Type_structType: case Type_structType:
case Type_interfaceType: case Type_interfaceType:
t->name = strf(&t->buf, "%s_list", find_node(t->lt.body.structType)->name.str); v->tname = strf(&v->buf, "%s_list", find_node(lt.body.structType)->name.str);
break; break;
} }
} }
}
static void decode_value(struct value* v, Type_ptr type, Value_ptr value, const char *symbol) {
memset(v, 0, sizeof(*v));
decode_type(&v->t, type);
read_Value(&v->v, value);
switch (v->v.body_tag) { switch (v->v.body_tag) {
case Value_boolValue: case Value_boolValue:
@ -284,8 +276,8 @@ static void decode_value(struct value* v, Type_ptr type, Value_ptr value, const
v->num = 1; v->num = 1;
} }
str_addf(&SRC, "%s%s %s = {", scope, v->t.name, symbol); str_addf(&SRC, "%s%s %s = {", scope, v->tname, symbol);
if (strcmp(v->t.name, "capn_ptr")) if (strcmp(v->tname, "capn_ptr"))
str_addf(&SRC, "{"); str_addf(&SRC, "{");
str_addf(&SRC, "%d,%d,%d,%d,%d,(char*)&capn_buf[%d],(struct capn_segment*)&capn_seg", str_addf(&SRC, "%d,%d,%d,%d,%d,(char*)&capn_buf[%d],(struct capn_segment*)&capn_seg",
@ -293,7 +285,7 @@ static void decode_value(struct value* v, Type_ptr type, Value_ptr value, const
p.datasz, p.ptrsz, p.datasz, p.ptrsz,
p.len, (int) (p.data-p.seg->data-8)); p.len, (int) (p.data-p.seg->data-8));
if (strcmp(v->t.name, "capn_ptr")) if (strcmp(v->tname, "capn_ptr"))
str_addf(&SRC, "}"); str_addf(&SRC, "}");
str_addf(&SRC, "};\n"); str_addf(&SRC, "};\n");
@ -315,26 +307,26 @@ static void define_const(struct node *n) {
case Value_int8Value: case Value_int8Value:
case Value_int16Value: case Value_int16Value:
case Value_int32Value: case Value_int32Value:
fprintf(HDR, "extern %s %s;\n", v.t.name, n->name.str); fprintf(HDR, "extern %s %s;\n", v.tname, n->name.str);
str_addf(&SRC, "%s %s = %d;\n", v.t.name, n->name.str, (int) v.num); str_addf(&SRC, "%s %s = %d;\n", v.tname, n->name.str, (int) v.num);
break; break;
case Value_uint8Value: case Value_uint8Value:
case Value_uint16Value: case Value_uint16Value:
case Value_uint32Value: case Value_uint32Value:
fprintf(HDR, "extern %s %s;\n", v.t.name, n->name.str); fprintf(HDR, "extern %s %s;\n", v.tname, n->name.str);
str_addf(&SRC, "%s %s = %uu;\n", v.t.name, n->name.str, (uint32_t) v.num); str_addf(&SRC, "%s %s = %uu;\n", v.tname, n->name.str, (uint32_t) v.num);
break; break;
case Value_enumValue: case Value_enumValue:
fprintf(HDR, "extern %s %s;\n", v.t.name, n->name.str); fprintf(HDR, "extern %s %s;\n", v.tname, n->name.str);
str_addf(&SRC, "%s %s = (%s) %uu;\n", v.t.name, n->name.str, v.t.name, (uint32_t) v.num); str_addf(&SRC, "%s %s = (%s) %uu;\n", v.tname, n->name.str, v.tname, (uint32_t) v.num);
break; break;
case Value_int64Value: case Value_int64Value:
case Value_uint64Value: case Value_uint64Value:
fprintf(HDR, "extern %s %s;\n", v.t.name, n->name.str); fprintf(HDR, "extern %s %s;\n", v.tname, n->name.str);
str_addf(&SRC, "%s %s = ((uint64_t) %#xu << 32) | %#xu;\n", v.t.name, n->name.str, str_addf(&SRC, "%s %s = ((uint64_t) %#xu << 32) | %#xu;\n", v.tname, n->name.str,
(uint32_t) (v.num >> 32), (uint32_t) v.num); (uint32_t) (v.num >> 32), (uint32_t) v.num);
break; break;
@ -354,9 +346,9 @@ static void define_const(struct node *n) {
case Value_structValue: case Value_structValue:
case Value_objectValue: case Value_objectValue:
case Value_listValue: case Value_listValue:
fprintf(HDR, "extern %s %s;\n", v.t.name, n->name.str); fprintf(HDR, "extern %s %s;\n", v.tname, n->name.str);
if (!v.num) { if (!v.num) {
str_addf(&SRC, "%s %s;\n", v.t.name, n->name.str); str_addf(&SRC, "%s %s;\n", v.tname, n->name.str);
} }
break; break;
@ -365,7 +357,7 @@ static void define_const(struct node *n) {
break; break;
} }
str_release(&v.t.buf); str_release(&v.buf);
} }
struct member { struct member {
@ -432,58 +424,71 @@ static const char *xor_member(struct member *m) {
} }
} }
static void set_member(struct member *m, const char *tab, const char *var) { static const char *ptr_member(struct member *m, const char *var) {
const char *mbr, *xor = xor_member(m); static struct str buf = STR_INIT;
if (!strcmp(m->v.tname, "capn_ptr")) {
return var;
} else if (var[0] == '*') {
return strf(&buf, "%s->p", var+1);
} else {
return strf(&buf, "%s.p", var);
}
}
if (m->v.t.t.body_tag == Type_voidType) static void set_member(struct member *m, const char *ptr, const char *tab, const char *var) {
const char *xor = xor_member(m);
const char *pvar = ptr_member(m, var);
if (m->v.t.body_tag == Type_voidType)
return; return;
str_add(&SRC, tab, -1); str_add(&SRC, tab, -1);
switch (m->v.t.t.body_tag) { switch (m->v.t.body_tag) {
case Type_voidType: case Type_voidType:
break; break;
case Type_boolType: case Type_boolType:
str_addf(&SRC, "err = err || capn_write1(p.p, %d, %s != %d);\n", m->f.offset, var, (int) m->v.num); str_addf(&SRC, "err = err || capn_write1(%s, %d, %s != %d);\n", ptr, m->f.offset, var, (int) m->v.num);
break; break;
case Type_int8Type: case Type_int8Type:
str_addf(&SRC, "err = err || capn_write8(p.p, %d, (uint8_t) %s%s);\n", m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write8(%s, %d, (uint8_t) %s%s);\n", ptr, m->f.offset, var, xor);
break; break;
case Type_int16Type: case Type_int16Type:
case Type_enumType: case Type_enumType:
str_addf(&SRC, "err = err || capn_write16(p.p, %d, (uint16_t) %s%s);\n", 2*m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write16(%s, %d, (uint16_t) %s%s);\n", ptr, 2*m->f.offset, var, xor);
break; break;
case Type_int32Type: case Type_int32Type:
str_addf(&SRC, "err = err || capn_write32(p.p, %d, (uint32_t) %s%s);\n", 4*m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write32(%s, %d, (uint32_t) %s%s);\n", ptr, 4*m->f.offset, var, xor);
break; break;
case Type_int64Type: case Type_int64Type:
str_addf(&SRC, "err = err || capn_write64(p.p, %d, (uint64_t) %s%s);\n", 8*m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write64(%s, %d, (uint64_t) %s%s);\n", ptr, 8*m->f.offset, var, xor);
break; break;
case Type_uint8Type: case Type_uint8Type:
str_addf(&SRC, "err = err || capn_write8(p.p, %d, %s%s);\n", m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write8(%s, %d, %s%s);\n", ptr, m->f.offset, var, xor);
break; break;
case Type_uint16Type: case Type_uint16Type:
str_addf(&SRC, "err = err || capn_write16(p.p, %d, %s%s);\n", 2*m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write16(%s, %d, %s%s);\n", ptr, 2*m->f.offset, var, xor);
break; break;
case Type_uint32Type: case Type_uint32Type:
str_addf(&SRC, "err = err || capn_write32(p.p, %d, %s%s);\n", 4*m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write32(%s, %d, %s%s);\n", ptr, 4*m->f.offset, var, xor);
break; break;
case Type_float32Type: case Type_float32Type:
str_addf(&SRC, "err = err || capn_write32(p.p, %d, capn_from_f32(%s)%s);\n", 4*m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write32(%s, %d, capn_from_f32(%s)%s);\n", ptr, 4*m->f.offset, var, xor);
break; break;
case Type_uint64Type: case Type_uint64Type:
str_addf(&SRC, "err = err || capn_write64(p.p, %d, %s%s);\n", 8*m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write64(%s, %d, %s%s);\n", ptr, 8*m->f.offset, var, xor);
break; break;
case Type_float64Type: case Type_float64Type:
str_addf(&SRC, "err = err || capn_write64(p.p, %d, capn_from_f64(%s)%s);\n", 8*m->f.offset, var, xor); str_addf(&SRC, "err = err || capn_write64(%s, %d, capn_from_f64(%s)%s);\n", ptr, 8*m->f.offset, var, xor);
break; break;
case Type_textType: case Type_textType:
if (m->v.num) { if (m->v.num) {
g_val0used = 1; g_val0used = 1;
str_addf(&SRC, "err = err || capn_set_text(p.p, %d, (%s.str != capn_val%d.str) ? %s : capn_val0);\n", str_addf(&SRC, "err = err || capn_set_text(%s, %d, (%s.str != capn_val%d.str) ? %s : capn_val0);\n",
m->f.offset, var, (int)m->v.num, var); ptr, m->f.offset, var, (int)m->v.num, var);
} else { } else {
str_addf(&SRC, "err = err || capn_set_text(p.p, %d, %s);\n", m->f.offset, var); str_addf(&SRC, "err = err || capn_set_text(%s, %d, %s);\n",
ptr, m->f.offset, var);
} }
break; break;
case Type_dataType: case Type_dataType:
@ -491,88 +496,90 @@ static void set_member(struct member *m, const char *tab, const char *var) {
case Type_interfaceType: case Type_interfaceType:
case Type_listType: case Type_listType:
case Type_objectType: case Type_objectType:
mbr = strcmp(m->v.t.name, "capn_ptr") ? ".p" : ""; if (!m->v.num) {
if (m->v.num) { str_addf(&SRC, "err = err || capn_setp(%s, %d, %s);\n",
ptr, m->f.offset, pvar);
} else if (!strcmp(m->v.tname, "capn_ptr")) {
g_nullused = 1; g_nullused = 1;
str_addf(&SRC, "err = err || capn_setp(p.p, %d, (%s%s.data != capn_val%d%s.data) ? %s%s : capn_null);\n", str_addf(&SRC, "err = err || capn_setp(%s, %d, (%s.data != capn_val%d.data) ? %s : capn_null);\n",
m->f.offset, var, mbr, (int)m->v.num, mbr, var, mbr); ptr, m->f.offset, pvar, (int)m->v.num, pvar);
} else { } else {
str_addf(&SRC, "err = err || capn_setp(p.p, %d, %s%s);\n", m->f.offset, var, mbr); g_nullused = 1;
str_addf(&SRC, "err = err || capn_setp(%s, %d, (%s.data != capn_val%d.p.data) ? %s : capn_null);\n",
ptr, m->f.offset, pvar, (int)m->v.num, pvar);
} }
break; break;
} }
} }
static void get_member(struct member *m, const char *tab, const char *var) { static void get_member(struct member *m, const char *ptr, const char *tab, const char *var) {
const char *mbr, *xor = xor_member(m); const char *xor = xor_member(m);
const char *pvar = ptr_member(m, var);
if (m->v.t.t.body_tag == Type_voidType) if (m->v.t.body_tag == Type_voidType)
return; return;
str_add(&SRC, tab, -1); str_add(&SRC, tab, -1);
str_add(&SRC, var, -1);
switch (m->v.t.t.body_tag) { switch (m->v.t.body_tag) {
case Type_voidType: case Type_voidType:
return; return;
case Type_boolType: case Type_boolType:
str_addf(&SRC, " = (capn_read8(p.p, %d) & %d) != %d;\n", str_addf(&SRC, "%s = (capn_read8(%s, %d) & %d) != %d;\n",
m->f.offset/8, 1 << (m->f.offset%8), (int)m->v.num); var, ptr, m->f.offset/8, 1 << (m->f.offset%8), (int)m->v.num);
return; return;
case Type_int8Type: case Type_int8Type:
str_addf(&SRC, " = (int8_t) capn_read8(p.p, %d)%s;\n", m->f.offset, xor); str_addf(&SRC, "%s = (int8_t) capn_read8(%s, %d)%s;\n", var, ptr, m->f.offset, xor);
return; return;
case Type_int16Type: case Type_int16Type:
str_addf(&SRC, " = (int16_t) capn_read16(p.p, %d)%s;\n", 2*m->f.offset, xor); str_addf(&SRC, "%s = (int16_t) capn_read16(%s, %d)%s;\n", var, ptr, 2*m->f.offset, xor);
return; return;
case Type_int32Type: case Type_int32Type:
str_addf(&SRC, " = (int32_t) capn_read32(p.p, %d)%s;\n", 4*m->f.offset, xor); str_addf(&SRC, "%s = (int32_t) capn_read32(%s, %d)%s;\n", var, ptr, 4*m->f.offset, xor);
return; return;
case Type_int64Type: case Type_int64Type:
str_addf(&SRC, " = (int64_t) capn_read64(p.p, %d)%s;\n", 8*m->f.offset, xor); str_addf(&SRC, "%s = (int64_t) capn_read64(%s, %d)%s;\n", var, ptr, 8*m->f.offset, xor);
return; return;
case Type_uint8Type: case Type_uint8Type:
str_addf(&SRC, " = capn_read8(p.p, %d)%s;\n", m->f.offset, xor); str_addf(&SRC, "%s = capn_read8(%s, %d)%s;\n", var, ptr, m->f.offset, xor);
return; return;
case Type_uint16Type: case Type_uint16Type:
str_addf(&SRC, " = capn_read16(p.p, %d)%s;\n", 2*m->f.offset, xor); str_addf(&SRC, "%s = capn_read16(%s, %d)%s;\n", var, ptr, 2*m->f.offset, xor);
return; return;
case Type_uint32Type: case Type_uint32Type:
str_addf(&SRC, " = capn_read32(p.p, %d)%s;\n", 4*m->f.offset, xor); str_addf(&SRC, "%s = capn_read32(%s, %d)%s;\n", var, ptr, 4*m->f.offset, xor);
return; return;
case Type_uint64Type: case Type_uint64Type:
str_addf(&SRC, " = capn_read64(p.p, %d)%s;\n", 8*m->f.offset, xor); str_addf(&SRC, "%s = capn_read64(%s, %d)%s;\n", var, ptr, 8*m->f.offset, xor);
return; return;
case Type_float32Type: case Type_float32Type:
str_addf(&SRC, " = capn_to_f32(capn_read32(p.p, %d)%s);\n", 4*m->f.offset, xor); str_addf(&SRC, "%s = capn_to_f32(capn_read32(%s, %d)%s);\n", var, ptr, 4*m->f.offset, xor);
return; return;
case Type_float64Type: case Type_float64Type:
str_addf(&SRC, " = capn_to_f64(capn_read64(p.p, %d)%s);\n", 8*m->f.offset, xor); str_addf(&SRC, "%s = capn_to_f64(capn_read64(%s, %d)%s);\n", var, ptr, 8*m->f.offset, xor);
return; return;
case Type_enumType: case Type_enumType:
str_addf(&SRC, " = (%s) capn_read16(p.p, %d)%s;\n", m->v.t.name, 2*m->f.offset, xor); str_addf(&SRC, "%s = (%s) capn_read16(%s, %d)%s;\n", var, m->v.tname, ptr, 2*m->f.offset, xor);
return; return;
case Type_textType: case Type_textType:
if (!m->v.num) if (!m->v.num)
g_val0used = 1; g_val0used = 1;
str_addf(&SRC, " = capn_get_text(p.p, %d, capn_val%d);\n", m->f.offset, (int)m->v.num); str_addf(&SRC, "%s = capn_get_text(%s, %d, capn_val%d);\n", var, ptr, m->f.offset, (int)m->v.num);
return; return;
case Type_dataType: case Type_dataType:
mbr = ".p"; str_addf(&SRC, "%s = capn_get_data(%s, %d);\n", var, ptr, m->f.offset);
str_addf(&SRC, " = capn_get_data(p.p, %d);\n", m->f.offset);
break; break;
case Type_structType: case Type_structType:
case Type_interfaceType: case Type_interfaceType:
case Type_objectType: case Type_objectType:
case Type_listType: case Type_listType:
mbr = strcmp(m->v.t.name, "capn_ptr") ? ".p" : ""; str_addf(&SRC, "%s = capn_getp(%s, %d);\n", pvar, ptr, m->f.offset);
str_addf(&SRC, "%s = capn_getp(p.p, %d);\n", mbr, m->f.offset);
break; break;
} }
if (m->v.num) { if (m->v.num) {
str_addf(&SRC, "%sif (!%s%s.type) {\n", tab, var, mbr); str_addf(&SRC, "%sif (!%s.type) {\n", tab, pvar);
str_addf(&SRC, "%s\t%s = capn_val%d;\n", tab, var, (int)m->v.num); str_addf(&SRC, "%s\t%s = capn_val%d;\n", tab, var, (int)m->v.num);
str_addf(&SRC, "%s}\n", tab); str_addf(&SRC, "%s}\n", tab);
} }
@ -581,9 +588,9 @@ static void get_member(struct member *m, const char *tab, const char *var) {
static void union_block(struct member *m, struct member *u, int set) { static void union_block(struct member *m, struct member *u, int set) {
static struct str buf = STR_INIT; static struct str buf = STR_INIT;
if (set) { if (set) {
set_member(u, "\t\t", strf(&buf, "s->%s.%s", m->m.name.str, u->m.name.str)); set_member(u, "p.p", "\t\t", strf(&buf, "s->%s.%s", m->m.name.str, u->m.name.str));
} else { } else {
get_member(u, "\t\t", strf(&buf, "s->%s.%s", m->m.name.str, u->m.name.str)); get_member(u, "p.p", "\t\t", strf(&buf, "s->%s.%s", m->m.name.str, u->m.name.str));
} }
str_addf(&SRC, "\t\tbreak;\n"); str_addf(&SRC, "\t\tbreak;\n");
@ -594,7 +601,7 @@ static void union_cases(struct node *n, struct member *m, int set, int mask) {
int j; int j;
for (j = 0; j < m->u.members.p.len; j++) { for (j = 0; j < m->u.members.p.len; j++) {
if (!m->mbrs[j].v.num && (mask & (1 << m->mbrs[j].v.t.t.body_tag))) { if (!m->mbrs[j].v.num && (mask & (1 << m->mbrs[j].v.t.body_tag))) {
u = &m->mbrs[j]; u = &m->mbrs[j];
str_addf(&SRC, "\tcase %s_%s:\n", n->name.str, u->m.name.str); str_addf(&SRC, "\tcase %s_%s:\n", n->name.str, u->m.name.str);
} }
@ -643,14 +650,14 @@ static void do_union(struct node *n, struct member *m, int set) {
} }
static void print_member(struct member *m, const char *tab) { static void print_member(struct member *m, const char *tab) {
switch (m->v.t.t.body_tag) { switch (m->v.t.body_tag) {
case Type_voidType: case Type_voidType:
break; break;
case Type_boolType: case Type_boolType:
fprintf(HDR, "%s%s %s:1;\n", tab, m->v.t.name, m->m.name.str); fprintf(HDR, "%s%s %s:1;\n", tab, m->v.tname, m->m.name.str);
break; break;
default: default:
fprintf(HDR, "%s%s %s;\n", tab, m->v.t.name, m->m.name.str); fprintf(HDR, "%s%s %s;\n", tab, m->v.tname, m->m.name.str);
break; break;
} }
} }
@ -731,7 +738,7 @@ static void define_struct(struct node *n) {
switch (m->m.body_tag) { switch (m->m.body_tag) {
case StructNode_Member_fieldMember: case StructNode_Member_fieldMember:
get_member(m, "\t", strf(&buf, "s->%s", m->m.name.str)); get_member(m, "p.p", "\t", strf(&buf, "s->%s", m->m.name.str));
break; break;
case StructNode_Member_unionMember: case StructNode_Member_unionMember:
do_union(n, m, 0); do_union(n, m, 0);
@ -748,7 +755,7 @@ static void define_struct(struct node *n) {
switch (m->m.body_tag) { switch (m->m.body_tag) {
case StructNode_Member_fieldMember: case StructNode_Member_fieldMember:
set_member(m, "\t", strf(&buf, "s->%s", m->m.name.str)); set_member(m, "p.p", "\t", strf(&buf, "s->%s", m->m.name.str));
break; break;
case StructNode_Member_unionMember: case StructNode_Member_unionMember:
do_union(n, m, 1); do_union(n, m, 1);
@ -770,6 +777,143 @@ static void define_struct(struct node *n) {
str_addf(&SRC, "}\n"); str_addf(&SRC, "}\n");
} }
static int find_offset(struct str *v, int inc, uint64_t mask) {
int i, j;
union {uint64_t u; char c[8];} umask;
umask.u = capn_flip64(mask);
for (i = 0; i < v->len*8; i += inc) {
for (j = i; j < i+inc; j++) {
if (((uint8_t*)v->str)[j/8] & (1 << (j%8))) {
goto loop;
}
}
for (j = i; j < i+inc; j++) {
((uint8_t*)v->str)[j/8] |= 1 << (j%8);
}
return j/inc;
loop:
continue;
}
str_add(v, umask.c, 8);
return (v->len-8)/inc;
}
static void define_method(struct node *iface, int ord) {
static struct str buf = STR_INIT;
struct member *mbrs;
struct InterfaceNode_Method method;
int i, ptrs = 0, datasz;
get_InterfaceNode_Method(&method, iface->i.methods, ord);
mbrs = calloc(method.params.p.len, sizeof(*mbrs));
str_reset(&buf);
for (i = 0; i < method.params.p.len; i++) {
struct InterfaceNode_Method_Param param;
struct member *m = &mbrs[i];
get_InterfaceNode_Method_Param(&param, method.params, i);
decode_value(&m->v, param.type, param.defaultValue, NULL);
m->m.name = param.name;
m->m.annotations = param.annotations;
m->m.ordinal = i;
switch (m->v.t.body_tag) {
case Type_voidType:
break;
case Type_boolType:
m->f.offset = find_offset(&buf, 1, 1);
break;
case Type_int8Type:
case Type_uint8Type:
m->f.offset = find_offset(&buf, 8, 0xFF);
break;
case Type_int16Type:
case Type_uint16Type:
case Type_enumType:
m->f.offset = find_offset(&buf, 16, 0xFFFF);
break;
case Type_int32Type:
case Type_uint32Type:
case Type_float32Type:
m->f.offset = find_offset(&buf, 32, 0xFFFFFFFFu);
break;
case Type_int64Type:
case Type_uint64Type:
case Type_float64Type:
m->f.offset = find_offset(&buf, 64, ~((uint64_t) 0));
break;
case Type_textType:
case Type_dataType:
case Type_listType:
case Type_structType:
case Type_interfaceType:
case Type_objectType:
m->f.offset = ptrs++;
break;
}
}
datasz = buf.len;
/* write function to initiate a call */
fprintf(HDR, "\nint write_%s_%s(struct capn_msg*", iface->name.str, method.name.str);
str_addf(&SRC, "\nint write_%s_%s(struct capn_msg *m", iface->name.str, method.name.str);
for (i = 0; i < method.params.p.len; i++) {
struct member *m = &mbrs[i];
fprintf(HDR, ", %s %s", m->v.tname, m->m.name.str);
str_addf(&SRC, ", %s a%d", m->v.tname, i);
}
fprintf(HDR, ");\n");
str_addf(&SRC, ") {\n");
str_addf(&SRC, "\tint err = 0;\n");
str_addf(&SRC, "\tm->method = %d;\n", ord);
str_addf(&SRC, "\tm->iface = ((uint64_t) %#xu << 32) | %#xu;\n", (uint32_t) (iface->n.id >> 32), (uint32_t) iface->n.id);
if (datasz || ptrs) {
str_addf(&SRC, "\tm->args = capn_new_struct(m->seg, %d, %d);\n", datasz, ptrs);
} else {
g_nullused = 1;
str_addf(&SRC, "\tm->args = capn_null;\n");
}
for (i = 0; i < method.params.p.len; i++) {
set_member(&mbrs[i], "m->args", "\t", strf(&buf, "a%d", i));
}
str_addf(&SRC, "\treturn err;\n");
str_addf(&SRC, "}\n");
/* read function to handle a call */
if (datasz || ptrs) {
fprintf(HDR, "void read_%s_%s(struct capn_msg*", iface->name.str, method.name.str);
str_addf(&SRC, "void read_%s_%s(struct capn_msg *m", iface->name.str, method.name.str);
for (i = 0; i < method.params.p.len; i++) {
struct member *m = &mbrs[i];
fprintf(HDR, ", %s *%s", m->v.tname, m->m.name.str);
str_addf(&SRC, ", %s *a%d", m->v.tname, i);
}
fprintf(HDR, ");\n");
str_addf(&SRC, ") {\n");
for (i = 0; i < method.params.p.len; i++) {
get_member(&mbrs[i], "m->args", "\t", strf(&buf, "*a%d", i));
}
str_addf(&SRC, "}\n");
}
free(mbrs);
}
static void declare(struct node *n, enum Node_body type, const char *format, int num) { static void declare(struct node *n, enum Node_body type, const char *format, int num) {
fprintf(HDR, "\n"); fprintf(HDR, "\n");
for (n = n->first_child; n != NULL; n = n->next_child) { for (n = n->first_child; n != NULL; n = n->next_child) {
@ -793,7 +937,7 @@ int main() {
CodeGeneratorRequest_ptr root; CodeGeneratorRequest_ptr root;
struct CodeGeneratorRequest req; struct CodeGeneratorRequest req;
struct node *n; struct node *n;
int i; int i, j;
if (capn_init_fp(&capn, stdin, 0)) { if (capn_init_fp(&capn, stdin, 0)) {
fprintf(stderr, "failed to read schema from stdin\n"); fprintf(stderr, "failed to read schema from stdin\n");
@ -905,6 +1049,11 @@ int main() {
case Node_constNode: case Node_constNode:
define_const(s); define_const(s);
break; break;
case Node_interfaceNode:
for (j = 0; j < s->i.methods.p.len; j++) {
define_method(s, j);
}
break;
default: default:
break; break;
} }

View file

@ -157,7 +157,7 @@ enum Value_body {
struct Value { struct Value {
enum Value_body body_tag; enum Value_body body_tag;
union { union {
unsigned int boolValue:1; unsigned boolValue:1;
int8_t int8Value; int8_t int8Value;
int16_t int16Value; int16_t int16Value;
int32_t int32Value; int32_t int32Value;
@ -274,17 +274,17 @@ struct ConstNode {
struct AnnotationNode { struct AnnotationNode {
Type_ptr type; Type_ptr type;
unsigned int targetsFile:1; unsigned targetsFile:1;
unsigned int targetsConst:1; unsigned targetsConst:1;
unsigned int targetsEnum:1; unsigned targetsEnum:1;
unsigned int targetsEnumerant:1; unsigned targetsEnumerant:1;
unsigned int targetsStruct:1; unsigned targetsStruct:1;
unsigned int targetsField:1; unsigned targetsField:1;
unsigned int targetsUnion:1; unsigned targetsUnion:1;
unsigned int targetsInterface:1; unsigned targetsInterface:1;
unsigned int targetsMethod:1; unsigned targetsMethod:1;
unsigned int targetsParam:1; unsigned targetsParam:1;
unsigned int targetsAnnotation:1; unsigned targetsAnnotation:1;
}; };
struct CodeGeneratorRequest { struct CodeGeneratorRequest {