From 21e7c29a9624f7b02fa71a24fc41ea4fdbfe2580 Mon Sep 17 00:00:00 2001 From: James McKaskill Date: Sun, 12 May 2013 18:28:29 -0400 Subject: [PATCH] add interface to base lib and improve handling of empty lists --- capn-list.inc | 4 ++ capn-test.cpp | 48 +++++++------ capn.c | 171 +++++++++++++++++++++++++------------------- capn.h | 10 +-- compiler/capnpc-c.c | 5 +- 5 files changed, 137 insertions(+), 101 deletions(-) diff --git a/capn-list.inc b/capn-list.inc index 7302df2..a05ff0a 100644 --- a/capn-list.inc +++ b/capn-list.inc @@ -13,6 +13,7 @@ UINT_T CAT(capn_get,SZ) (CAT(capn_list,SZ) l, int off) { switch (p.type) { case CAPN_LIST: + case CAPN_COMPOSITE_LIST: if (p.datasz < SZ/8) return 0; d = p.data + off * (p.datasz + p.ptrsz); @@ -40,6 +41,7 @@ int CAT(capn_getv,SZ) (CAT(capn_list,SZ) l, int off, UINT_T *to, int sz) { switch (p.type) { case CAPN_LIST: + case CAPN_COMPOSITE_LIST: if (p.datasz == SZ/8 && !p.ptrsz && (SZ == 8 || CAPN_LITTLE)) { memcpy(to, p.data + off, sz * (SZ/8)); return sz; @@ -78,6 +80,7 @@ int CAT(capn_set,SZ) (CAT(capn_list,SZ) l, int off, UINT_T v) { switch (p.type) { case CAPN_LIST: + case CAPN_COMPOSITE_LIST: if (p.datasz < SZ/8) return -1; d = p.data + off * (p.datasz + p.ptrsz); @@ -106,6 +109,7 @@ int CAT(capn_setv,SZ) (CAT(capn_list,SZ) l, int off, const UINT_T *from, int sz) switch (p.type) { case CAPN_LIST: + case CAPN_COMPOSITE_LIST: if (p.datasz == SZ/8 && !p.ptrsz && (SZ == 8 || CAPN_LITTLE)) { memcpy(p.data + off, from, sz * (SZ/8)); return sz; diff --git a/capn-test.cpp b/capn-test.cpp index aee722f..7614cd2 100644 --- a/capn-test.cpp +++ b/capn-test.cpp @@ -72,10 +72,10 @@ static void setupStruct(struct capn *ctx) { ASSERT_EQ(CAPN_PTR_LIST, root.type); ASSERT_EQ(1, root.len); - struct capn_ptr ptr = capn_new_struct(root.seg, 16, 5); + struct capn_ptr ptr = capn_new_struct(root.seg, 16, 6); ASSERT_EQ(CAPN_STRUCT, ptr.type); EXPECT_EQ(16, ptr.datasz); - EXPECT_EQ(40, ptr.ptrsz); + EXPECT_EQ(48, ptr.ptrsz); EXPECT_EQ(0, capn_setp(root, 0, ptr)); EXPECT_EQ(0, capn_write64(ptr, 0, UINT64_C(0x1011121314151617))); @@ -105,16 +105,14 @@ static void setupStruct(struct capn *ctx) { EXPECT_EQ(0, capn_setp(ptr, 1, list32.p)); capn_ptr list = capn_new_list(ptr.seg, 4, 4, 1); - ASSERT_EQ(CAPN_LIST, list.type); - EXPECT_EQ(1, list.has_composite_tag); + ASSERT_EQ(CAPN_COMPOSITE_LIST, list.type); EXPECT_EQ(4, list.len); EXPECT_EQ(8, list.datasz); EXPECT_EQ(8, list.ptrsz); EXPECT_EQ(0, capn_setp(ptr, 2, list)); for (int i = 0; i < 4; i++) { capn_ptr element = capn_getp(list, i); - ASSERT_EQ(CAPN_STRUCT, element.type); - EXPECT_EQ(1, element.is_list_member); + ASSERT_EQ(CAPN_LIST_MEMBER, element.type); EXPECT_EQ(8, element.datasz); EXPECT_EQ(8, element.ptrsz); EXPECT_EQ(0, capn_write32(element, 0, 300+i)); @@ -149,13 +147,19 @@ static void setupStruct(struct capn *ctx) { EXPECT_EQ(16, recurse.ptrsz); EXPECT_EQ(0, capn_setp(recurse, 0, recurse)); EXPECT_EQ(0, capn_setp(ptr, 4, recurse)); + + capn_ptr interface = capn_new_interface(ptr.seg, 0, 0); + EXPECT_EQ(CAPN_INTERFACE, interface.type); + EXPECT_EQ(0, interface.datasz); + EXPECT_EQ(0, interface.ptrsz); + EXPECT_EQ(0, capn_setp(ptr, 5, interface)); } static void checkStruct(struct capn *ctx) { capn_ptr ptr = capn_getp(capn_root(ctx), 0); EXPECT_EQ(CAPN_STRUCT, ptr.type); EXPECT_EQ(16, ptr.datasz); - EXPECT_EQ(40, ptr.ptrsz); + EXPECT_EQ(48, ptr.ptrsz); EXPECT_EQ(UINT64_C(0x1011121314151617), capn_read64(ptr, 0)); EXPECT_EQ(UINT32_C(0x20212223), capn_read32(ptr, 8)); EXPECT_EQ(0x3031, capn_read16(ptr, 12)); @@ -185,15 +189,14 @@ static void checkStruct(struct capn *ctx) { EXPECT_EQ(202, capn_get16(list16, 2)); capn_ptr list = capn_getp(ptr, 2); - EXPECT_EQ(CAPN_LIST, list.type); + EXPECT_EQ(CAPN_COMPOSITE_LIST, list.type); EXPECT_EQ(4, list.len); EXPECT_EQ(8, list.datasz); EXPECT_EQ(8, list.ptrsz); for (int i = 0; i < 4; i++) { capn_ptr element = capn_getp(list, i); - EXPECT_EQ(CAPN_STRUCT, element.type); - EXPECT_EQ(1, element.is_list_member); + EXPECT_EQ(CAPN_LIST_MEMBER, element.type); EXPECT_EQ(8, element.datasz); EXPECT_EQ(8, element.ptrsz); EXPECT_EQ(300+i, capn_read32(element,0)); @@ -230,6 +233,11 @@ static void checkStruct(struct capn *ctx) { EXPECT_EQ(recurse.seg, recurse_mbr.seg); EXPECT_EQ(recurse.data, recurse_mbr.data); EXPECT_EQ(CAPN_NULL, capn_getp(recurse, 1).type); + + capn_ptr interface = capn_getp(ptr, 5); + EXPECT_EQ(CAPN_INTERFACE, interface.type); + EXPECT_EQ(0, interface.datasz); + EXPECT_EQ(0, interface.ptrsz); } TEST(WireFormat, StructRoundTrip_OneSegment) { @@ -238,7 +246,7 @@ TEST(WireFormat, StructRoundTrip_OneSegment) { // word count: // 1 root reference - // 7 root struct + // 8 root struct // 1 sub message // 2 3-element int32 list // 13 struct list @@ -252,9 +260,9 @@ TEST(WireFormat, StructRoundTrip_OneSegment) { // 6 sub-lists (4x 1 word, 1x 2 words) // 2 recurse // ----- - // 37 + // 38 ASSERT_EQ(1, ctx.capn.segnum); - EXPECT_EQ(37*8, ctx.capn.seglist->len); + EXPECT_EQ(38*8, ctx.capn.seglist->len); checkStruct(&ctx.capn); @@ -296,7 +304,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) { // Check that each segment has the expected size. Recall that the first word of each segment will // actually be a reference to the first thing allocated within that segment. EXPECT_EQ( 8, segments[ 0]->len); // root ref - EXPECT_EQ(64, segments[ 1]->len); // root struct + EXPECT_EQ(72, segments[ 1]->len); // root struct EXPECT_EQ(16, segments[ 2]->len); // sub-struct EXPECT_EQ(24, segments[ 3]->len); // 3-element int32 list EXPECT_EQ(80, segments[ 4]->len); // struct list @@ -337,7 +345,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation_NoTag) { // Check that each segment has the expected size. Note that we have plenty // of 16 byte double far ptrs. EXPECT_EQ( 8, segments[ 0]->len); // root ref - EXPECT_EQ(56, segments[ 1]->len); // root struct + EXPECT_EQ(64, segments[ 1]->len); // root struct EXPECT_EQ(16, segments[ 2]->len); // root struct ptr EXPECT_EQ( 8, segments[ 3]->len); // sub-struct EXPECT_EQ(16, segments[ 4]->len); // sub-struct ptr @@ -411,12 +419,12 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) { // Check that each segment has the expected size. Recall that each object will be prefixed by an // extra word if its parent is in a different segment. - EXPECT_EQ(64, segments[0]->len); // root ref + struct (48) - EXPECT_EQ(56, segments[1]->len); // sub (8+tag) + 3-element int32 list (16+tag) + struct list substructs 1 (8+tag) + EXPECT_EQ(64, segments[0]->len); // root ref (8), sub-struct (8+tag), 3-element list (16+tag), list substruct 1 (8+tag) + EXPECT_EQ(72, segments[1]->len); // root struct (64+tag) EXPECT_EQ(80, segments[2]->len); // struct list (72+tag) - EXPECT_EQ(64, segments[3]->len); // struct list substructs 2+3+4 3*(8+tag) + list list sublist 3 (8+tag) - EXPECT_EQ(64, segments[4]->len); // list list (40+tag) + sublist 1,2 2*(8) - EXPECT_EQ(64, segments[5]->len); // list list sublist 4 (8+tag), 5 (16+tag) + recurse struct (16+tag) + EXPECT_EQ(64, segments[3]->len); // list substruct 2,3,4 3*(8+tag), sublist 3 (8+tag) + EXPECT_EQ(64, segments[4]->len); // list list (40+tag), sublist 1,2 2*8 + EXPECT_EQ(64, segments[5]->len); // sublist 4 (8+tag), 5 (16+tag), recurse struct (16+tag) checkStruct(&ctx.capn); diff --git a/capn.c b/capn.c index 8e757cc..d05c04c 100644 --- a/capn.c +++ b/capn.c @@ -8,6 +8,7 @@ #define STRUCT_PTR 0 #define LIST_PTR 1 #define FAR_PTR 2 +#define INTERFACE_PTR 3 #define DOUBLE_PTR 6 #define VOID_LIST 0 @@ -322,16 +323,26 @@ static capn_ptr read_ptr(struct capn_segment *s, char *d) { d += (I32(U32(val)) >> 2) * 8 + 8; - if ((val&3) > LIST_PTR || d < s->data) { + if (d < s->data) { goto err; } - if ((val&3) == STRUCT_PTR) { + switch (val & 3) { + case STRUCT_PTR: + ret.type = val ? CAPN_STRUCT : CAPN_NULL; + goto struct_common; + + case INTERFACE_PTR: + ret.type = CAPN_INTERFACE; + goto struct_common; + + struct_common: ret.datasz = U32(U16(val >> 32)) * 8; ret.ptrsz = U32(U16(val >> 48)) * 8; - ret.type = (ret.datasz || ret.ptrsz) ? CAPN_STRUCT : CAPN_NULL; e = d + ret.datasz + ret.ptrsz; - } else { + break; + + case LIST_PTR: ret.type = CAPN_LIST; ret.len = val >> 35; @@ -377,13 +388,14 @@ static capn_ptr read_ptr(struct capn_segment *s, char *d) { ret.datasz = U32(U16(val >> 32)) * 8; ret.ptrsz = U32(U16(val >> 48)) * 8; ret.len = U32(val) >> 2; - ret.has_composite_tag = 1; + ret.type = CAPN_COMPOSITE_LIST; if ((ret.datasz + ret.ptrsz) * ret.len != e - d) { goto err; } break; } + break; } if (e - s->data > s->len) @@ -399,12 +411,11 @@ err: capn_ptr capn_getp(capn_ptr p, int off) { switch (p.type) { + case CAPN_COMPOSITE_LIST: case CAPN_LIST: /* Return an inner pointer */ if (off < p.len) { - capn_ptr ret = {CAPN_NULL}; - ret.type = CAPN_STRUCT; - ret.is_list_member = 1; + capn_ptr ret = {CAPN_LIST_MEMBER}; ret.data = p.data + off * (p.datasz + p.ptrsz); ret.seg = p.seg; ret.datasz = p.datasz; @@ -414,6 +425,8 @@ capn_ptr capn_getp(capn_ptr p, int off) { goto err; } + case CAPN_INTERFACE: + case CAPN_LIST_MEMBER: case CAPN_STRUCT: off *= 8; if (off >= p.ptrsz) { @@ -438,27 +451,53 @@ err: return p; } -static uint64_t ptr_value(capn_ptr p, int off) { +static int data_size(struct capn_ptr p) { + switch (p.type) { + case CAPN_BIT_LIST: + return p.datasz; + case CAPN_PTR_LIST: + return p.len*8; + case CAPN_INTERFACE: + case CAPN_STRUCT: + return p.datasz + p.ptrsz; + case CAPN_COMPOSITE_LIST: + return p.len * (p.datasz + p.ptrsz) + 8; + case CAPN_LIST: + return p.len * (p.datasz + p.ptrsz); + default: + return 0; + } +} + +static void write_ptr_tag(char *d, capn_ptr p, int off) { uint64_t val = U64(U32(I32(off/8) << 2)); switch (p.type) { + case CAPN_INTERFACE: + val |= INTERFACE_PTR | (U64(p.datasz/8) << 32) | (U64(p.ptrsz/8) << 48); + break; + case CAPN_STRUCT: val |= STRUCT_PTR | (U64(p.datasz/8) << 32) | (U64(p.ptrsz/8) << 48); break; + case CAPN_COMPOSITE_LIST: + val |= LIST_PTR | (U64(COMPOSITE_LIST) << 32) | (U64(p.len * (p.datasz + p.ptrsz)/8) << 35); + break; + case CAPN_LIST: - if (p.has_composite_tag) { - val |= LIST_PTR | (U64(COMPOSITE_LIST) << 32) | (U64(p.len * (p.datasz + p.ptrsz)/8) << 35); - } else if (p.datasz == 8) { - val |= LIST_PTR | (U64(BYTE_8_LIST) << 32) | (U64(p.len) << 35); + val |= LIST_PTR | (U64(p.len) << 35); + + if (p.datasz == 8) { + val |= (U64(BYTE_8_LIST) << 32); } else if (p.datasz == 4) { - val |= LIST_PTR | (U64(BYTE_4_LIST) << 32) | (U64(p.len) << 35); + val |= (U64(BYTE_4_LIST) << 32); } else if (p.datasz == 2) { - val |= LIST_PTR | (U64(BYTE_2_LIST) << 32) | (U64(p.len) << 35); + val |= (U64(BYTE_2_LIST) << 32); } else if (p.datasz == 1) { - val |= LIST_PTR | (U64(BYTE_1_LIST) << 32) | (U64(p.len) << 35); + val |= (U64(BYTE_1_LIST) << 32); } else { - val |= LIST_PTR | (U64(VOID_LIST) << 32) | (U64(p.len) << 35); + val |= (U64(VOID_LIST) << 32); } break; @@ -475,7 +514,7 @@ static uint64_t ptr_value(capn_ptr p, int off) { break; } - return capn_flip64(val); + *(uint64_t*) d = capn_flip64(val); } static void write_far_ptr(char *d, struct capn_segment *s, char *tgt) { @@ -486,25 +525,17 @@ static void write_double_far(char *d, struct capn_segment *s, char *tgt) { *(uint64_t*) d = capn_flip64(DOUBLE_PTR | U64(tgt - s->data) | (U64(s->id) << 32)); } -static void write_ptr_tag(char *d, capn_ptr p, int off) { - *(uint64_t*) d = ptr_value(p, off); -} - #define NEED_TO_COPY 1 static int write_ptr(struct capn_segment *s, char *d, capn_ptr p) { /* note p.seg can be NULL if its a ptr to static data */ - char *pdata = p.data; + char *pdata = p.data - (p.type == CAPN_COMPOSITE_LIST ? 8 : 0); - if (p.has_composite_tag) { - pdata -= 8; - } - - if (p.type == CAPN_NULL) { - *(uint64_t*) d = 0; + if (data_size(p) == 0) { + write_ptr_tag(d, p, 0); return 0; - } else if (!p.seg || p.seg->capn != s->capn || p.is_list_member) { + } else if (!p.seg || p.seg->capn != s->capn || p.type == CAPN_LIST_MEMBER) { return NEED_TO_COPY; } else if (p.seg == s) { @@ -559,30 +590,19 @@ struct copy { char *fbegin, *fend; }; -static int data_size(const struct capn_ptr *p) { - switch (p->type) { - case CAPN_BIT_LIST: - return p->datasz; - case CAPN_PTR_LIST: - return p->len*8; - case CAPN_STRUCT: - return p->datasz + p->ptrsz; - case CAPN_LIST: - return p->len * (p->datasz + p->ptrsz); - default: - return 0; - } -} - static capn_ptr new_clone(struct capn_segment *s, capn_ptr p) { switch (p.type) { + case CAPN_INTERFACE: + return capn_new_interface(s, p.datasz, p.ptrsz/8); case CAPN_STRUCT: + case CAPN_LIST_MEMBER: return capn_new_struct(s, p.datasz, p.ptrsz/8); case CAPN_PTR_LIST: return capn_new_ptr_list(s, p.len); case CAPN_BIT_LIST: return capn_new_list1(s, p.len).p; case CAPN_LIST: + case CAPN_COMPOSITE_LIST: return capn_new_list(s, p.len, p.datasz, p.ptrsz/8); default: return p; @@ -594,22 +614,15 @@ static int is_ptr_equal(const struct capn_ptr *a, const struct capn_ptr *b) { && a->type == b->type && a->len == b->len && a->datasz == b->datasz - && a->ptrsz == b->ptrsz - && a->has_composite_tag == b->has_composite_tag; + && a->ptrsz == b->ptrsz; } static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, struct capn_ptr *f, int *dep) { struct capn *c = seg->capn; struct copy *cp = NULL; struct capn_tree **xcp; - char *fbegin = f->data; - char *fend = fbegin + data_size(f); - - if (f->has_composite_tag) { - fbegin -= 8; - } else if (f->is_list_member) { - fend = fbegin; - } + char *fbegin = f->data - (f->type == CAPN_COMPOSITE_LIST ? 8 : 0); + char *fend = fbegin + data_size(*f); /* We always copy list members as it would otherwise be an * overlapped pointer (the data is owned by the enclosing list). @@ -678,6 +691,7 @@ static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, st * be valid */ switch (t->type) { case CAPN_STRUCT: + case CAPN_INTERFACE: if (t->datasz) { memcpy(t->data, f->data, t->datasz); t->data += t->datasz; @@ -695,6 +709,7 @@ static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, st return 0; case CAPN_LIST: + case CAPN_COMPOSITE_LIST: if (!t->len) { /* empty list - nothing to copy */ } else if (t->ptrsz && t->datasz) { @@ -748,7 +763,8 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) { switch (p.type) { case CAPN_LIST: - if (off >= p.len || tgt.type != CAPN_STRUCT) + case CAPN_COMPOSITE_LIST: + if (off >= p.len || (tgt.type != CAPN_STRUCT && tgt.type != CAPN_LIST_MEMBER)) return -1; to[0] = p; @@ -764,6 +780,8 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) { goto copy_ptr; case CAPN_STRUCT: + case CAPN_INTERFACE: + case CAPN_LIST_MEMBER: off *= 8; if (off >= p.ptrsz) return -1; @@ -805,8 +823,7 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) { continue; } - switch (tc->type) { - case CAPN_LIST: + if (tc->type == CAPN_COMPOSITE_LIST) { *fn = capn_getp(*fc, 0); *tn = capn_getp(*tc, 0); @@ -815,10 +832,8 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) { fc->data += fc->datasz + fc->ptrsz; tc->data += tc->datasz + tc->ptrsz; tc->len--; - break; - case CAPN_PTR_LIST: - default: + } else { /* CAPN_PTR_LIST */ *fn = read_ptr(fc->seg, fc->data); if (fn->type && copy_ptr(tc->seg, tc->data, tn, fn, &dep)) @@ -827,7 +842,6 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) { fc->data += 8; tc->data += 8; tc->len--; - break; } } @@ -914,6 +928,9 @@ int capn_setv1(capn_list1 l, int off, const uint8_t *data, int sz) { static void new_object(capn_ptr *p, int bytes) { struct capn_segment *s = p->seg; + if (!bytes) + return; + /* all allocations are 8 byte aligned */ bytes = (bytes + 7) & ~7; @@ -954,9 +971,17 @@ capn_ptr capn_root(struct capn *c) { } capn_ptr capn_new_struct(struct capn_segment *seg, int datasz, int ptrs) { - capn_ptr p = {CAPN_NULL}; + capn_ptr p = {CAPN_STRUCT}; + p.seg = seg; + p.datasz = (datasz + 7) & ~7; + p.ptrsz = ptrs * 8; + new_object(&p, p.datasz + p.ptrsz); + return p; +} + +capn_ptr capn_new_interface(struct capn_segment *seg, int datasz, int ptrs) { + capn_ptr p = {CAPN_INTERFACE}; p.seg = seg; - p.type = CAPN_STRUCT; p.datasz = (datasz + 7) & ~7; p.ptrsz = ptrs * 8; new_object(&p, p.datasz + p.ptrsz); @@ -964,15 +989,16 @@ capn_ptr capn_new_struct(struct capn_segment *seg, int datasz, int ptrs) { } capn_ptr capn_new_list(struct capn_segment *seg, int sz, int datasz, int ptrs) { - capn_ptr p = {CAPN_NULL}; + capn_ptr p = {CAPN_LIST}; p.seg = seg; - p.type = CAPN_LIST; p.len = sz; - if (ptrs || datasz > 8) { + if (!sz) { + /* empty lists may as well be a len=0 void list */ + } else if (ptrs || datasz > 8) { + p.type = CAPN_COMPOSITE_LIST; p.datasz = (datasz + 7) & ~7; p.ptrsz = ptrs*8; - p.has_composite_tag = 1; new_object(&p, p.len * (p.datasz + p.ptrsz) + 8); if (p.data) { uint64_t hdr = STRUCT_PTR | (U64(p.len) << 2) | (U64(p.datasz/8) << 32) | (U64(ptrs) << 48); @@ -994,9 +1020,8 @@ 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 l = {{CAPN_NULL}}; + capn_list1 l = {{CAPN_BIT_LIST}}; l.p.seg = seg; - l.p.type = CAPN_BIT_LIST; l.p.datasz = (sz+7)/8; l.p.len = sz; new_object(&l.p, l.p.datasz); @@ -1004,9 +1029,8 @@ capn_list1 capn_new_list1(struct capn_segment *seg, int sz) { } capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz) { - capn_ptr p = {CAPN_NULL}; + capn_ptr p = {CAPN_PTR_LIST}; p.seg = seg; - p.type = CAPN_PTR_LIST; p.len = sz; p.ptrsz = 0; p.datasz = 0; @@ -1015,9 +1039,8 @@ capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz) { } capn_ptr capn_new_string(struct capn_segment *seg, const char *str, int sz) { - capn_ptr p = {CAPN_NULL}; + capn_ptr p = {CAPN_LIST}; p.seg = seg; - p.type = CAPN_LIST; p.len = ((sz >= 0) ? sz : strlen(str)) + 1; p.datasz = 1; new_object(&p, p.len); diff --git a/capn.h b/capn.h index d9e5597..a94d2a6 100644 --- a/capn.h +++ b/capn.h @@ -87,14 +87,15 @@ enum CAPN_TYPE { CAPN_STRUCT = 1, CAPN_LIST = 2, CAPN_PTR_LIST = 3, - CAPN_BIT_LIST = 4 + CAPN_BIT_LIST = 4, + CAPN_INTERFACE = 5, + CAPN_LIST_MEMBER = 6, + CAPN_COMPOSITE_LIST = 7 }; struct capn_ptr { - unsigned int type : 3; - unsigned int is_list_member : 1; + unsigned int type : 4; unsigned int has_ptr_tag : 1; - unsigned int has_composite_tag : 1; unsigned int datasz : 19; unsigned int ptrsz : 19; int len; @@ -176,6 +177,7 @@ int capn_setv64(capn_list64 p, int off, const uint64_t *data, int sz); * On an error a CAPN_NULL pointer is returned */ 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_list(struct capn_segment *seg, int sz, int datasz, int ptrs); capn_list1 capn_new_list1(struct capn_segment *seg, int sz); capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz); diff --git a/compiler/capnpc-c.c b/compiler/capnpc-c.c index d6e1fe1..f65b27a 100644 --- a/compiler/capnpc-c.c +++ b/compiler/capnpc-c.c @@ -288,9 +288,8 @@ static void decode_value(struct value* v, Type_ptr type, Value_ptr value, const if (strcmp(v->t.name, "capn_ptr")) str_addf(&SRC, "{"); - str_addf(&SRC, "%d,%d,%d,%d,%d,%d,%d,(char*)&capn_buf[%d],(struct capn_segment*)&capn_seg", - p.type, p.is_list_member, - p.has_ptr_tag, p.has_composite_tag, + str_addf(&SRC, "%d,%d,%d,%d,%d,(char*)&capn_buf[%d],(struct capn_segment*)&capn_seg", + p.type, p.has_ptr_tag, p.datasz, p.ptrsz, p.len, (int) (p.data-p.seg->data-8));