summaryrefslogtreecommitdiff
path: root/upb/pb
diff options
context:
space:
mode:
Diffstat (limited to 'upb/pb')
-rw-r--r--upb/pb/compile_decoder.c184
-rw-r--r--upb/pb/compile_decoder_x64.c3
-rw-r--r--upb/pb/compile_decoder_x64.dasc19
-rw-r--r--upb/pb/compile_decoder_x64.h287
-rw-r--r--upb/pb/decoder.c35
-rw-r--r--upb/pb/decoder.h290
-rw-r--r--upb/pb/decoder.int.h66
-rw-r--r--upb/pb/encoder.c51
-rw-r--r--upb/pb/encoder.h76
-rw-r--r--upb/pb/glue.c54
-rw-r--r--upb/pb/glue.h72
-rw-r--r--upb/pb/textprinter.c41
-rw-r--r--upb/pb/textprinter.h78
13 files changed, 487 insertions, 769 deletions
diff --git a/upb/pb/compile_decoder.c b/upb/pb/compile_decoder.c
index d147edf..ca497ed 100644
--- a/upb/pb/compile_decoder.c
+++ b/upb/pb/compile_decoder.c
@@ -23,80 +23,23 @@
#define MAXLABEL 5
#define EMPTYLABEL -1
-/* mgroup *********************************************************************/
-
-static void freegroup(upb_refcounted *r) {
- mgroup *g = (mgroup*)r;
- upb_inttable_uninit(&g->methods);
-#ifdef UPB_USE_JIT_X64
- upb_pbdecoder_freejit(g);
-#endif
- upb_gfree(g->bytecode);
- upb_gfree(g);
-}
-
-static void visitgroup(const upb_refcounted *r, upb_refcounted_visit *visit,
- void *closure) {
- const mgroup *g = (const mgroup*)r;
- upb_inttable_iter i;
- upb_inttable_begin(&i, &g->methods);
- for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
- upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i));
- visit(r, upb_pbdecodermethod_upcast(method), closure);
- }
-}
-
-mgroup *newgroup(const void *owner) {
- mgroup *g = upb_gmalloc(sizeof(*g));
- static const struct upb_refcounted_vtbl vtbl = {visitgroup, freegroup};
- upb_refcounted_init(mgroup_upcast_mutable(g), &vtbl, owner);
- upb_inttable_init(&g->methods, UPB_CTYPE_PTR);
- g->bytecode = NULL;
- g->bytecode_end = NULL;
- return g;
-}
-
-
/* upb_pbdecodermethod ********************************************************/
-static void freemethod(upb_refcounted *r) {
- upb_pbdecodermethod *method = (upb_pbdecodermethod*)r;
-
- if (method->dest_handlers_) {
- upb_handlers_unref(method->dest_handlers_, method);
- }
-
+static void freemethod(upb_pbdecodermethod *method) {
upb_inttable_uninit(&method->dispatch);
upb_gfree(method);
}
-static void visitmethod(const upb_refcounted *r, upb_refcounted_visit *visit,
- void *closure) {
- const upb_pbdecodermethod *m = (const upb_pbdecodermethod*)r;
- visit(r, m->group, closure);
-}
-
static upb_pbdecodermethod *newmethod(const upb_handlers *dest_handlers,
mgroup *group) {
- static const struct upb_refcounted_vtbl vtbl = {visitmethod, freemethod};
upb_pbdecodermethod *ret = upb_gmalloc(sizeof(*ret));
- upb_refcounted_init(upb_pbdecodermethod_upcast_mutable(ret), &vtbl, &ret);
upb_byteshandler_init(&ret->input_handler_);
- /* The method references the group and vice-versa, in a circular reference. */
- upb_ref2(ret, group);
- upb_ref2(group, ret);
- upb_inttable_insertptr(&group->methods, dest_handlers, upb_value_ptr(ret));
- upb_pbdecodermethod_unref(ret, &ret);
-
- ret->group = mgroup_upcast_mutable(group);
+ ret->group = group;
ret->dest_handlers_ = dest_handlers;
ret->is_native_ = false; /* If we JIT, it will update this later. */
upb_inttable_init(&ret->dispatch, UPB_CTYPE_UINT64);
- if (ret->dest_handlers_) {
- upb_handlers_ref(ret->dest_handlers_, ret);
- }
return ret;
}
@@ -114,16 +57,31 @@ bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m) {
return m->is_native_;
}
-const upb_pbdecodermethod *upb_pbdecodermethod_new(
- const upb_pbdecodermethodopts *opts, const void *owner) {
- const upb_pbdecodermethod *ret;
- upb_pbcodecache cache;
- upb_pbcodecache_init(&cache);
- ret = upb_pbcodecache_getdecodermethod(&cache, opts);
- upb_pbdecodermethod_ref(ret, owner);
- upb_pbcodecache_uninit(&cache);
- return ret;
+/* mgroup *********************************************************************/
+
+static void freegroup(mgroup *g) {
+ upb_inttable_iter i;
+
+ upb_inttable_begin(&i, &g->methods);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ freemethod(upb_value_getptr(upb_inttable_iter_value(&i)));
+ }
+
+ upb_inttable_uninit(&g->methods);
+#ifdef UPB_USE_JIT_X64
+ upb_pbdecoder_freejit(g);
+#endif
+ upb_gfree(g->bytecode);
+ upb_gfree(g);
+}
+
+mgroup *newgroup() {
+ mgroup *g = upb_gmalloc(sizeof(*g));
+ upb_inttable_init(&g->methods, UPB_CTYPE_PTR);
+ g->bytecode = NULL;
+ g->bytecode_end = NULL;
+ return g;
}
@@ -558,7 +516,7 @@ static upb_pbdecodermethod *find_submethod(const compiler *c,
static void putsel(compiler *c, opcode op, upb_selector_t sel,
const upb_handlers *h) {
- if (upb_handlers_gethandler(h, sel)) {
+ if (upb_handlers_gethandler(h, sel, NULL)) {
putop(c, op, sel);
}
}
@@ -574,9 +532,9 @@ static bool haslazyhandlers(const upb_handlers *h, const upb_fielddef *f) {
if (!upb_fielddef_lazy(f))
return false;
- return upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STARTSTR)) ||
- upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STRING)) ||
- upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_ENDSTR));
+ return upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STARTSTR), NULL) ||
+ upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STRING), NULL) ||
+ upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_ENDSTR), NULL);
}
@@ -814,10 +772,13 @@ static void find_methods(compiler *c, const upb_handlers *h) {
upb_value v;
upb_msg_field_iter i;
const upb_msgdef *md;
+ upb_pbdecodermethod *method;
if (upb_inttable_lookupptr(&c->group->methods, h, &v))
return;
- newmethod(h, c->group);
+
+ method = newmethod(h, c->group);
+ upb_inttable_insertptr(&c->group->methods, h, upb_value_ptr(method));
/* Find submethods. */
md = upb_handlers_msgdef(h);
@@ -893,15 +854,13 @@ static void sethandlers(mgroup *g, bool allowjit) {
/* TODO(haberman): allow this to be constructed for an arbitrary set of dest
* handlers and other mgroups (but verify we have a transitive closure). */
-const mgroup *mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy,
- const void *owner) {
+const mgroup *mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy) {
mgroup *g;
compiler *c;
UPB_UNUSED(allowjit);
- UPB_ASSERT(upb_handlers_isfrozen(dest));
- g = newgroup(owner);
+ g = newgroup();
c = newcompiler(g, lazy);
find_methods(c, dest);
@@ -939,56 +898,63 @@ const mgroup *mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy,
/* upb_pbcodecache ************************************************************/
-void upb_pbcodecache_init(upb_pbcodecache *c) {
- upb_inttable_init(&c->groups, UPB_CTYPE_CONSTPTR);
- c->allow_jit_ = true;
+upb_pbcodecache *upb_pbcodecache_new(upb_handlercache *dest) {
+ upb_pbcodecache *c = upb_gmalloc(sizeof(*c));
+
+ if (!c) return NULL;
+
+ c->dest = dest;
+ c->allow_jit = true;
+ c->lazy = false;
+
+ c->arena = upb_arena_new();
+ if (!upb_inttable_init(&c->groups, UPB_CTYPE_CONSTPTR)) return NULL;
+
+ return c;
}
-void upb_pbcodecache_uninit(upb_pbcodecache *c) {
- upb_inttable_iter i;
- upb_inttable_begin(&i, &c->groups);
- for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
- const mgroup *group = upb_value_getconstptr(upb_inttable_iter_value(&i));
- mgroup_unref(group, c);
+void upb_pbcodecache_free(upb_pbcodecache *c) {
+ size_t i;
+
+ for (i = 0; i < upb_inttable_count(&c->groups); i++) {
+ upb_value v;
+ bool ok = upb_inttable_lookup(&c->groups, i, &v);
+ UPB_ASSERT(ok);
+ freegroup((void*)upb_value_getconstptr(v));
}
+
upb_inttable_uninit(&c->groups);
+ upb_gfree(c);
}
bool upb_pbcodecache_allowjit(const upb_pbcodecache *c) {
- return c->allow_jit_;
+ return c->allow_jit;
}
-bool upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow) {
- if (upb_inttable_count(&c->groups) > 0)
- return false;
- c->allow_jit_ = allow;
- return true;
+void upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow) {
+ UPB_ASSERT(upb_inttable_count(&c->groups) == 0);
+ c->allow_jit = allow;
}
-const upb_pbdecodermethod *upb_pbcodecache_getdecodermethod(
- upb_pbcodecache *c, const upb_pbdecodermethodopts *opts) {
+void upb_pbdecodermethodopts_setlazy(upb_pbcodecache *c, bool lazy) {
+ UPB_ASSERT(upb_inttable_count(&c->groups) == 0);
+ c->lazy = lazy;
+}
+
+const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c,
+ const upb_msgdef *md) {
upb_value v;
bool ok;
+ const upb_handlers *h;
+ const mgroup *g;
/* Right now we build a new DecoderMethod every time.
* TODO(haberman): properly cache methods by their true key. */
- const mgroup *g = mgroup_new(opts->handlers, c->allow_jit_, opts->lazy, c);
+ h = upb_handlercache_get(c->dest, md);
+ g = mgroup_new(h, c->allow_jit, c->lazy);
upb_inttable_push(&c->groups, upb_value_constptr(g));
- ok = upb_inttable_lookupptr(&g->methods, opts->handlers, &v);
+ ok = upb_inttable_lookupptr(&g->methods, h, &v);
UPB_ASSERT(ok);
return upb_value_getptr(v);
}
-
-
-/* upb_pbdecodermethodopts ****************************************************/
-
-void upb_pbdecodermethodopts_init(upb_pbdecodermethodopts *opts,
- const upb_handlers *h) {
- opts->handlers = h;
- opts->lazy = false;
-}
-
-void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy) {
- opts->lazy = lazy;
-}
diff --git a/upb/pb/compile_decoder_x64.c b/upb/pb/compile_decoder_x64.c
index fd541a4..7c716e8 100644
--- a/upb/pb/compile_decoder_x64.c
+++ b/upb/pb/compile_decoder_x64.c
@@ -233,7 +233,8 @@ static int getjmptarget(jitcompiler *jc, const void *key) {
*
* Creates/allocates a pclabel for this target if one does not exist already. */
static int jmptarget(jitcompiler *jc, const void *key) {
- // Optimizer sometimes can't figure out that initializing this is unnecessary.
+ /* Optimizer sometimes can't figure out that initializing this is unnecessary.
+ */
int pclabel = 0;
if (!try_getjmptarget(jc, key, &pclabel)) {
pclabel = alloc_pclabel(jc);
diff --git a/upb/pb/compile_decoder_x64.dasc b/upb/pb/compile_decoder_x64.dasc
index 7fcd006..7dc1987 100644
--- a/upb/pb/compile_decoder_x64.dasc
+++ b/upb/pb/compile_decoder_x64.dasc
@@ -92,7 +92,7 @@
|.endmacro
|
|.macro load_handler_data, h, arg
-| ld64 upb_handlers_gethandlerdata(h, arg)
+| ld64 gethandlerdata(h, arg)
|.endmacro
|
|.macro chkeob, bytes, target
@@ -140,7 +140,7 @@
#define DECODE_EOF -3
static upb_func *gethandler(const upb_handlers *h, upb_selector_t sel) {
- return h ? upb_handlers_gethandler(h, sel) : NULL;
+ return h ? upb_handlers_gethandler(h, sel, NULL) : NULL;
}
/* Defines an "assembly label" for the current code generation offset.
@@ -179,14 +179,19 @@ static void asmlabel(jitcompiler *jc, const char *fmt, ...) {
/* Should only be called when the associated handler is known to exist. */
static bool alwaysok(const upb_handlers *h, upb_selector_t sel) {
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr attr = UPB_HANDLERATTR_INIT;
bool ok = upb_handlers_getattr(h, sel, &attr);
- bool ret;
UPB_ASSERT(ok);
- ret = upb_handlerattr_alwaysok(&attr);
- upb_handlerattr_uninit(&attr);
- return ret;
+ return attr.alwaysok;
+}
+
+static const void *gethandlerdata(const upb_handlers *h, upb_selector_t sel) {
+ upb_handlerattr attr = UPB_HANDLERATTR_INIT;
+ bool ok = upb_handlers_getattr(h, sel, &attr);
+
+ UPB_ASSERT(ok);
+ return attr.handler_data;
}
/* Emit static assembly routines; code that does not vary based on the message
diff --git a/upb/pb/compile_decoder_x64.h b/upb/pb/compile_decoder_x64.h
index 2c07063..4a4dffc 100644
--- a/upb/pb/compile_decoder_x64.h
+++ b/upb/pb/compile_decoder_x64.h
@@ -278,7 +278,7 @@ static const char *const upb_jit_globalnames[] = {
/*|.endmacro */
/*| */
/*|.macro load_handler_data, h, arg */
-/*| ld64 upb_handlers_gethandlerdata(h, arg) */
+/*| ld64 gethandlerdata(h, arg) */
/*|.endmacro */
/*| */
/*|.macro chkeob, bytes, target */
@@ -326,7 +326,7 @@ static const char *const upb_jit_globalnames[] = {
#define DECODE_EOF -3
static upb_func *gethandler(const upb_handlers *h, upb_selector_t sel) {
- return h ? upb_handlers_gethandler(h, sel) : NULL;
+ return h ? upb_handlers_gethandler(h, sel, NULL) : NULL;
}
/* Defines an "assembly label" for the current code generation offset.
@@ -367,14 +367,19 @@ static void asmlabel(jitcompiler *jc, const char *fmt, ...) {
/* Should only be called when the associated handler is known to exist. */
static bool alwaysok(const upb_handlers *h, upb_selector_t sel) {
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr attr = UPB_HANDLERATTR_INIT;
bool ok = upb_handlers_getattr(h, sel, &attr);
- bool ret;
UPB_ASSERT(ok);
- ret = upb_handlerattr_alwaysok(&attr);
- upb_handlerattr_uninit(&attr);
- return ret;
+ return attr.alwaysok;
+}
+
+static const void *gethandlerdata(const upb_handlers *h, upb_selector_t sel) {
+ upb_handlerattr attr = UPB_HANDLERATTR_INIT;
+ bool ok = upb_handlers_getattr(h, sel, &attr);
+
+ UPB_ASSERT(ok);
+ return attr.handler_data;
}
/* Emit static assembly routines; code that does not vary based on the message
@@ -424,7 +429,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*|1: */
/*| pop rbx */
dasm_put(Dst, 2, (unsigned int)((uintptr_t)upb_pbdecoder_resume), (unsigned int)(((uintptr_t)upb_pbdecoder_resume)>>32), 0xfffffffffffffff0UL, Dt2(->saved_rsp), Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt1(->sink.closure), Dt1(->end_ofs), Dt2(->bufstart_ofs), Dt2(->buf), Dt2(->call_len), Dt2(->size_param), Dt2(->call_len));
-# 238 "upb/pb/compile_decoder_x64.dasc"
+# 243 "upb/pb/compile_decoder_x64.dasc"
/*| pop r12 */
/*| pop r13 */
/*| pop r14 */
@@ -445,7 +450,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| // the JIT resumes, and more buffer space will be available. */
/*| // Args: eax=the value that decode() should return. */
dasm_put(Dst, 115, Dt2(->callstack), (unsigned int)((uintptr_t)memcpy), (unsigned int)(((uintptr_t)memcpy)>>32), 0xfffffffffffffff0UL);
-# 257 "upb/pb/compile_decoder_x64.dasc"
+# 262 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "exitjit");
/*|->exitjit: */
/*| // Save the stack into DECODER->callstack. */
@@ -473,7 +478,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| // (from the caller's perspective) not to return until the decoder is */
/*| // resumed. */
dasm_put(Dst, 161, Dt2(->callstack), Dt2(->saved_rsp), Dt2(->call_len), (unsigned int)((uintptr_t)memcpy), (unsigned int)(((uintptr_t)memcpy)>>32), 0xfffffffffffffff0UL, Dt2(->saved_rsp));
-# 283 "upb/pb/compile_decoder_x64.dasc"
+# 288 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "suspend");
/*|->suspend: */
/*| cmp DECODER->ptr, PTR */
@@ -486,7 +491,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| jmp ->exitjit */
/*| */
dasm_put(Dst, 222, Dt2(->ptr), Dt2(->checkpoint), Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt2(->delim_end), Dt2(->buf), Dt2(->bufstart_ofs), Dt1(->end_ofs), Dt1(->sink.closure), (unsigned int)((uintptr_t)upb_pbdecoder_suspend), (unsigned int)(((uintptr_t)upb_pbdecoder_suspend)>>32), 0xfffffffffffffff0UL);
-# 294 "upb/pb/compile_decoder_x64.dasc"
+# 299 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "pushlendelim");
/*|->pushlendelim: */
/*|1: */
@@ -499,7 +504,7 @@ static void emit_static_asm(jitcompiler *jc) {
} else {
dasm_put(Dst, 321);
}
-# 300 "upb/pb/compile_decoder_x64.dasc"
+# 305 "upb/pb/compile_decoder_x64.dasc"
/*| mov rcx, DELIMEND */
/*| sub rcx, PTR */
/*| sub rcx, rdx */
@@ -520,7 +525,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| ja >2 */
/*| mov DATAEND, DELIMEND // If DELIMEND >= PTR && DELIMEND < DATAEND */
dasm_put(Dst, 337, Dt1(->end_ofs), Dt2(->limit), sizeof(upb_pbdecoder_frame), Dt1(->groupnum), Dt2(->end));
-# 319 "upb/pb/compile_decoder_x64.dasc"
+# 324 "upb/pb/compile_decoder_x64.dasc"
/*|2: */
/*| ret */
/*|3: */
@@ -540,7 +545,7 @@ static void emit_static_asm(jitcompiler *jc) {
dasm_put(Dst, 454);
}
}
-# 327 "upb/pb/compile_decoder_x64.dasc"
+# 332 "upb/pb/compile_decoder_x64.dasc"
/*| callp upb_pbdecoder_seterr */
/*| call ->suspend */
/*| jmp <1 */
@@ -561,7 +566,7 @@ static void emit_static_asm(jitcompiler *jc) {
dasm_put(Dst, 454);
}
}
-# 336 "upb/pb/compile_decoder_x64.dasc"
+# 341 "upb/pb/compile_decoder_x64.dasc"
/*| callp upb_pbdecoder_seterr */
/*| call ->suspend */
/*| jmp <1 */
@@ -592,7 +597,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*|.endmacro */
/*| */
dasm_put(Dst, 497, (unsigned int)((uintptr_t)upb_pbdecoder_seterr), (unsigned int)(((uintptr_t)upb_pbdecoder_seterr)>>32), 0xfffffffffffffff0UL);
-# 365 "upb/pb/compile_decoder_x64.dasc"
+# 370 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "parse_unknown");
/*| // Args: edx=fieldnum, cl=wire type */
/*|->parse_unknown: */
@@ -607,7 +612,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| cmp eax, DECODE_ENDGROUP */
/*| jne >1 */
dasm_put(Dst, 526, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt2(->delim_end), Dt2(->buf), Dt2(->bufstart_ofs), Dt1(->end_ofs), Dt1(->sink.closure), (unsigned int)((uintptr_t)upb_pbdecoder_skipunknown), (unsigned int)(((uintptr_t)upb_pbdecoder_skipunknown)>>32), 0xfffffffffffffff0UL, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt1(->sink.closure), Dt1(->end_ofs), Dt2(->bufstart_ofs), Dt2(->buf), DECODE_ENDGROUP);
-# 378 "upb/pb/compile_decoder_x64.dasc"
+# 383 "upb/pb/compile_decoder_x64.dasc"
/*| ret // Return eax=DECODE_ENDGROUP, not zero */
/*|1: */
/*| cmp eax, DECODE_OK */
@@ -627,26 +632,26 @@ static void emit_static_asm(jitcompiler *jc) {
/*| // completes. We also set DECODER->ptr to this value which is a signal to */
/*| // ->suspend that DECODER->checkpoint is up to date. */
dasm_put(Dst, 623, DECODE_OK);
-# 396 "upb/pb/compile_decoder_x64.dasc"
+# 401 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "skip_decode_f32_fallback");
/*|->skipf32_fallback: */
/*|->decodef32_fallback: */
/*| getvalue_slow upb_pbdecoder_decode_f32, 4 */
dasm_put(Dst, 647, Dt2(->checkpoint), Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt2(->delim_end), Dt2(->buf), Dt2(->bufstart_ofs), Dt1(->end_ofs), Dt1(->sink.closure), (unsigned int)((uintptr_t)upb_pbdecoder_decode_f32), (unsigned int)(((uintptr_t)upb_pbdecoder_decode_f32)>>32), 0xfffffffffffffff0UL, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt1(->sink.closure), Dt1(->end_ofs));
-# 400 "upb/pb/compile_decoder_x64.dasc"
+# 405 "upb/pb/compile_decoder_x64.dasc"
/*| */
dasm_put(Dst, 751, Dt2(->bufstart_ofs), Dt2(->buf), Dt2(->ptr));
-# 401 "upb/pb/compile_decoder_x64.dasc"
+# 406 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "skip_decode_f64_fallback");
/*|->skipf64_fallback: */
/*|->decodef64_fallback: */
/*| getvalue_slow upb_pbdecoder_decode_f64, 8 */
dasm_put(Dst, 799, Dt2(->checkpoint), Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt2(->delim_end), Dt2(->buf), Dt2(->bufstart_ofs), Dt1(->end_ofs), Dt1(->sink.closure), (unsigned int)((uintptr_t)upb_pbdecoder_decode_f64), (unsigned int)(((uintptr_t)upb_pbdecoder_decode_f64)>>32), 0xfffffffffffffff0UL, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt1(->sink.closure), Dt1(->end_ofs));
-# 405 "upb/pb/compile_decoder_x64.dasc"
+# 410 "upb/pb/compile_decoder_x64.dasc"
/*| */
/*| // Called for varint >= 1 byte. */
dasm_put(Dst, 903, Dt2(->bufstart_ofs), Dt2(->buf), Dt2(->ptr));
-# 407 "upb/pb/compile_decoder_x64.dasc"
+# 412 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "skip_decode_v32_fallback");
/*|->skipv32_fallback: */
/*|->skipv64_fallback: */
@@ -657,7 +662,7 @@ static void emit_static_asm(jitcompiler *jc) {
} else {
dasm_put(Dst, 964);
}
-# 411 "upb/pb/compile_decoder_x64.dasc"
+# 416 "upb/pb/compile_decoder_x64.dasc"
/*| // With at least 16 bytes left, we can do a branch-less SSE version. */
/*| movdqu xmm0, [PTR] */
/*| pmovmskb eax, xmm0 // bits 0-15 are continuation bits, 16-31 are 0. */
@@ -687,7 +692,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| */
/*| // Returns tag in edx */
dasm_put(Dst, 980, 10);
-# 439 "upb/pb/compile_decoder_x64.dasc"
+# 444 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "decode_unknown_tag_fallback");
/*|->decode_unknown_tag_fallback: */
/*| sub rsp, 16 */
@@ -705,7 +710,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| callp upb_pbdecoder_decode_varint_slow */
/*| load_regs */
dasm_put(Dst, 1053, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt2(->delim_end), Dt2(->buf), Dt2(->bufstart_ofs), Dt1(->end_ofs), Dt1(->sink.closure), (unsigned int)((uintptr_t)upb_pbdecoder_decode_varint_slow), (unsigned int)(((uintptr_t)upb_pbdecoder_decode_varint_slow)>>32), 0xfffffffffffffff0UL, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt1(->sink.closure));
-# 455 "upb/pb/compile_decoder_x64.dasc"
+# 460 "upb/pb/compile_decoder_x64.dasc"
/*| cmp eax, 0 */
/*| jge >3 */
/*| mov edx, [rsp] // Success; return parsed data. */
@@ -717,7 +722,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| */
/*| // Called for varint >= 1 byte. */
dasm_put(Dst, 1156, Dt1(->end_ofs), Dt2(->bufstart_ofs), Dt2(->buf));
-# 465 "upb/pb/compile_decoder_x64.dasc"
+# 470 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "decode_v32_v64_fallback");
/*|->decodev32_fallback: */
/*|->decodev64_fallback: */
@@ -728,7 +733,7 @@ static void emit_static_asm(jitcompiler *jc) {
} else {
dasm_put(Dst, 1207);
}
-# 469 "upb/pb/compile_decoder_x64.dasc"
+# 474 "upb/pb/compile_decoder_x64.dasc"
/*| // OPT: do something faster than just calling the C version. */
/*| mov rdi, PTR */
/*| callp upb_vdecode_fast */
@@ -740,17 +745,17 @@ static void emit_static_asm(jitcompiler *jc) {
/*| ret */
/*| */
dasm_put(Dst, 1223, (unsigned int)((uintptr_t)upb_vdecode_fast), (unsigned int)(((uintptr_t)upb_vdecode_fast)>>32), 0xfffffffffffffff0UL, Dt2(->ptr));
-# 479 "upb/pb/compile_decoder_x64.dasc"
+# 484 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "decode_varint_slow");
/*|->decode_varint_slow: */
/*| // Slow path: end of buffer or error (varint length >= 10). */
/*| getvalue_slow upb_pbdecoder_decode_varint_slow, 1 */
dasm_put(Dst, 1268, Dt2(->checkpoint), Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt2(->delim_end), Dt2(->buf), Dt2(->bufstart_ofs), Dt1(->end_ofs), Dt1(->sink.closure), (unsigned int)((uintptr_t)upb_pbdecoder_decode_varint_slow), (unsigned int)(((uintptr_t)upb_pbdecoder_decode_varint_slow)>>32), 0xfffffffffffffff0UL, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt1(->sink.closure), Dt1(->end_ofs), Dt2(->bufstart_ofs));
-# 483 "upb/pb/compile_decoder_x64.dasc"
+# 488 "upb/pb/compile_decoder_x64.dasc"
/*| */
/*| // Args: rsi=expected tag, return=rax (DECODE_{OK,MISMATCH}) */
dasm_put(Dst, 1374, Dt2(->buf), Dt2(->ptr));
-# 485 "upb/pb/compile_decoder_x64.dasc"
+# 490 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "checktag_fallback");
/*|->checktag_fallback: */
/*| sub rsp, 8 */
@@ -762,7 +767,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| callp upb_pbdecoder_checktag_slow */
/*| load_regs */
dasm_put(Dst, 1418, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt2(->delim_end), Dt2(->buf), Dt2(->bufstart_ofs), Dt1(->end_ofs), Dt1(->sink.closure), Dt2(->checkpoint), (unsigned int)((uintptr_t)upb_pbdecoder_checktag_slow), (unsigned int)(((uintptr_t)upb_pbdecoder_checktag_slow)>>32), 0xfffffffffffffff0UL, Dt2(->top), Dt2(->ptr), Dt2(->data_end), Dt1(->sink.closure), Dt1(->end_ofs), Dt2(->bufstart_ofs));
-# 495 "upb/pb/compile_decoder_x64.dasc"
+# 500 "upb/pb/compile_decoder_x64.dasc"
/*| cmp eax, 0 */
/*| jge >2 */
/*| add rsp, 8 */
@@ -780,7 +785,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| // Preserves: rcx, rdx */
/*| // OPT: Could write this in assembly if it's a hotspot. */
dasm_put(Dst, 1517, Dt2(->buf), DECODE_EOF);
-# 511 "upb/pb/compile_decoder_x64.dasc"
+# 516 "upb/pb/compile_decoder_x64.dasc"
asmlabel(jc, "hashlookup");
/*|->hashlookup: */
/*| push rcx */
@@ -802,7 +807,7 @@ static void emit_static_asm(jitcompiler *jc) {
/*| not rax */
/*| ret */
dasm_put(Dst, 1559, (unsigned int)((uintptr_t)upb_inttable_lookup), (unsigned int)(((uintptr_t)upb_inttable_lookup)>>32), 0xfffffffffffffff0UL);
-# 531 "upb/pb/compile_decoder_x64.dasc"
+# 536 "upb/pb/compile_decoder_x64.dasc"
}
static void jitprimitive(jitcompiler *jc, opcode op,
@@ -828,63 +833,63 @@ static void jitprimitive(jitcompiler *jc, opcode op,
} else {
dasm_put(Dst, 1636, fastbytes);
}
-# 550 "upb/pb/compile_decoder_x64.dasc"
+# 555 "upb/pb/compile_decoder_x64.dasc"
/*|2: */
dasm_put(Dst, 1652);
-# 551 "upb/pb/compile_decoder_x64.dasc"
+# 556 "upb/pb/compile_decoder_x64.dasc"
switch (vtype) {
case V32:
/*| call ->decodev32_fallback */
dasm_put(Dst, 1655);
-# 554 "upb/pb/compile_decoder_x64.dasc"
+# 559 "upb/pb/compile_decoder_x64.dasc"
break;
case V64:
/*| call ->decodev64_fallback */
dasm_put(Dst, 1659);
-# 557 "upb/pb/compile_decoder_x64.dasc"
+# 562 "upb/pb/compile_decoder_x64.dasc"
break;
case F32:
/*| call ->decodef32_fallback */
dasm_put(Dst, 1663);
-# 560 "upb/pb/compile_decoder_x64.dasc"
+# 565 "upb/pb/compile_decoder_x64.dasc"
break;
case F64:
/*| call ->decodef64_fallback */
dasm_put(Dst, 1667);
-# 563 "upb/pb/compile_decoder_x64.dasc"
+# 568 "upb/pb/compile_decoder_x64.dasc"
break;
case X: break;
}
/*| jmp >4 */
dasm_put(Dst, 1671);
-# 567 "upb/pb/compile_decoder_x64.dasc"
+# 572 "upb/pb/compile_decoder_x64.dasc"
/* Fast path decode; for when check_bytes bytes are available. */
/*|3: */
dasm_put(Dst, 1676);
-# 570 "upb/pb/compile_decoder_x64.dasc"
+# 575 "upb/pb/compile_decoder_x64.dasc"
switch (op) {
case OP_PARSE_SFIXED32:
case OP_PARSE_FIXED32:
/*| mov edx, dword [PTR] */
dasm_put(Dst, 1679);
-# 574 "upb/pb/compile_decoder_x64.dasc"
+# 579 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_PARSE_SFIXED64:
case OP_PARSE_FIXED64:
/*| mov rdx, qword [PTR] */
dasm_put(Dst, 1682);
-# 578 "upb/pb/compile_decoder_x64.dasc"
+# 583 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_PARSE_FLOAT:
/*| movss xmm0, dword [PTR] */
dasm_put(Dst, 1686);
-# 581 "upb/pb/compile_decoder_x64.dasc"
+# 586 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_PARSE_DOUBLE:
/*| movsd xmm0, qword [PTR] */
dasm_put(Dst, 1692);
-# 584 "upb/pb/compile_decoder_x64.dasc"
+# 589 "upb/pb/compile_decoder_x64.dasc"
break;
default:
/* Inline one byte of varint decoding. */
@@ -892,7 +897,7 @@ static void jitprimitive(jitcompiler *jc, opcode op,
/*| test dl, dl */
/*| js <2 // Fallback to slow path for >1 byte varint. */
dasm_put(Dst, 1698);
-# 590 "upb/pb/compile_decoder_x64.dasc"
+# 595 "upb/pb/compile_decoder_x64.dasc"
break;
}
@@ -900,7 +905,7 @@ static void jitprimitive(jitcompiler *jc, opcode op,
/* (only needed for a few types). */
/*|4: */
dasm_put(Dst, 1708);
-# 596 "upb/pb/compile_decoder_x64.dasc"
+# 601 "upb/pb/compile_decoder_x64.dasc"
switch (op) {
case OP_PARSE_SINT32:
/* 32-bit zig-zag decode. */
@@ -910,7 +915,7 @@ static void jitprimitive(jitcompiler *jc, opcode op,
/*| neg eax */
/*| xor edx, eax */
dasm_put(Dst, 1711);
-# 604 "upb/pb/compile_decoder_x64.dasc"
+# 609 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_PARSE_SINT64:
/* 64-bit zig-zag decode. */
@@ -920,13 +925,13 @@ static void jitprimitive(jitcompiler *jc, opcode op,
/*| neg rax */
/*| xor rdx, rax */
dasm_put(Dst, 1725);
-# 612 "upb/pb/compile_decoder_x64.dasc"
+# 617 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_PARSE_BOOL:
/*| test rdx, rdx */
/*| setne dl */
dasm_put(Dst, 1744);
-# 616 "upb/pb/compile_decoder_x64.dasc"
+# 621 "upb/pb/compile_decoder_x64.dasc"
break;
default: break;
}
@@ -938,29 +943,29 @@ static void jitprimitive(jitcompiler *jc, opcode op,
case UPB_TYPE_UINT64:
/*| mov [CLOSURE + offset], rdx */
dasm_put(Dst, 1751, offset);
-# 626 "upb/pb/compile_decoder_x64.dasc"
+# 631 "upb/pb/compile_decoder_x64.dasc"
break;
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_ENUM:
/*| mov [CLOSURE + offset], edx */
dasm_put(Dst, 1756, offset);
-# 631 "upb/pb/compile_decoder_x64.dasc"
+# 636 "upb/pb/compile_decoder_x64.dasc"
break;
case UPB_TYPE_DOUBLE:
/*| movsd qword [CLOSURE + offset], XMMARG1 */
dasm_put(Dst, 1761, offset);
-# 634 "upb/pb/compile_decoder_x64.dasc"
+# 639 "upb/pb/compile_decoder_x64.dasc"
break;
case UPB_TYPE_FLOAT:
/*| movss dword [CLOSURE + offset], XMMARG1 */
dasm_put(Dst, 1769, offset);
-# 637 "upb/pb/compile_decoder_x64.dasc"
+# 642 "upb/pb/compile_decoder_x64.dasc"
break;
case UPB_TYPE_BOOL:
/*| mov [CLOSURE + offset], dl */
dasm_put(Dst, 1777, offset);
-# 640 "upb/pb/compile_decoder_x64.dasc"
+# 645 "upb/pb/compile_decoder_x64.dasc"
break;
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES:
@@ -971,13 +976,13 @@ static void jitprimitive(jitcompiler *jc, opcode op,
if (hasbit >= 0) {
dasm_put(Dst, 1782, ((uint32_t)hasbit / 8), (1 << ((uint32_t)hasbit % 8)));
}
-# 647 "upb/pb/compile_decoder_x64.dasc"
+# 652 "upb/pb/compile_decoder_x64.dasc"
} else if (handler) {
/*| mov ARG1_64, CLOSURE */
/*| load_handler_data h, sel */
dasm_put(Dst, 1788);
{
- uintptr_t v = (uintptr_t)upb_handlers_gethandlerdata(h, sel);
+ uintptr_t v = (uintptr_t)gethandlerdata(h, sel);
if (v > 0xffffffff) {
dasm_put(Dst, 446, (unsigned int)(v), (unsigned int)((v)>>32));
} else if (v) {
@@ -986,10 +991,10 @@ static void jitprimitive(jitcompiler *jc, opcode op,
dasm_put(Dst, 454);
}
}
-# 650 "upb/pb/compile_decoder_x64.dasc"
+# 655 "upb/pb/compile_decoder_x64.dasc"
/*| callp handler */
dasm_put(Dst, 1793, (unsigned int)((uintptr_t)handler), (unsigned int)(((uintptr_t)handler)>>32), 0xfffffffffffffff0UL);
-# 651 "upb/pb/compile_decoder_x64.dasc"
+# 656 "upb/pb/compile_decoder_x64.dasc"
if (!alwaysok(h, sel)) {
/*| test al, al */
/*| jnz >5 */
@@ -997,7 +1002,7 @@ static void jitprimitive(jitcompiler *jc, opcode op,
/*| jmp <1 */
/*|5: */
dasm_put(Dst, 1815);
-# 657 "upb/pb/compile_decoder_x64.dasc"
+# 662 "upb/pb/compile_decoder_x64.dasc"
}
}
@@ -1005,7 +1010,7 @@ static void jitprimitive(jitcompiler *jc, opcode op,
* data until the callback has returned success. */
/*| add PTR, fastbytes */
dasm_put(Dst, 1831, fastbytes);
-# 663 "upb/pb/compile_decoder_x64.dasc"
+# 668 "upb/pb/compile_decoder_x64.dasc"
} else {
/* No handler registered for this value, just skip it. */
/*| chkneob fastbytes, >3 */
@@ -1014,30 +1019,30 @@ static void jitprimitive(jitcompiler *jc, opcode op,
} else {
dasm_put(Dst, 1636, fastbytes);
}
-# 666 "upb/pb/compile_decoder_x64.dasc"
+# 671 "upb/pb/compile_decoder_x64.dasc"
/*|2: */
dasm_put(Dst, 1652);
-# 667 "upb/pb/compile_decoder_x64.dasc"
+# 672 "upb/pb/compile_decoder_x64.dasc"
switch (vtype) {
case V32:
/*| call ->skipv32_fallback */
dasm_put(Dst, 1836);
-# 670 "upb/pb/compile_decoder_x64.dasc"
+# 675 "upb/pb/compile_decoder_x64.dasc"
break;
case V64:
/*| call ->skipv64_fallback */
dasm_put(Dst, 1840);
-# 673 "upb/pb/compile_decoder_x64.dasc"
+# 678 "upb/pb/compile_decoder_x64.dasc"
break;
case F32:
/*| call ->skipf32_fallback */
dasm_put(Dst, 1844);
-# 676 "upb/pb/compile_decoder_x64.dasc"
+# 681 "upb/pb/compile_decoder_x64.dasc"
break;
case F64:
/*| call ->skipf64_fallback */
dasm_put(Dst, 1848);
-# 679 "upb/pb/compile_decoder_x64.dasc"
+# 684 "upb/pb/compile_decoder_x64.dasc"
break;
case X: break;
}
@@ -1045,16 +1050,16 @@ static void jitprimitive(jitcompiler *jc, opcode op,
/* Fast-path skip. */
/*|3: */
dasm_put(Dst, 1676);
-# 685 "upb/pb/compile_decoder_x64.dasc"
+# 690 "upb/pb/compile_decoder_x64.dasc"
if (vtype == V32 || vtype == V64) {
/*| test byte [PTR], 0x80 */
/*| jnz <2 */
dasm_put(Dst, 1852);
-# 688 "upb/pb/compile_decoder_x64.dasc"
+# 693 "upb/pb/compile_decoder_x64.dasc"
}
/*| add PTR, fastbytes */
dasm_put(Dst, 1831, fastbytes);
-# 690 "upb/pb/compile_decoder_x64.dasc"
+# 695 "upb/pb/compile_decoder_x64.dasc"
}
}
@@ -1075,7 +1080,7 @@ static void jitdispatch(jitcompiler *jc,
/*|=>define_jmptarget(jc, &method->dispatch): */
/*|1: */
dasm_put(Dst, 1861, define_jmptarget(jc, &method->dispatch));
-# 709 "upb/pb/compile_decoder_x64.dasc"
+# 714 "upb/pb/compile_decoder_x64.dasc"
/* Decode the field tag. */
/*| mov aword DECODER->checkpoint, PTR */
/*| chkeob 2, >6 */
@@ -1085,7 +1090,7 @@ static void jitdispatch(jitcompiler *jc,
} else {
dasm_put(Dst, 1873);
}
-# 712 "upb/pb/compile_decoder_x64.dasc"
+# 717 "upb/pb/compile_decoder_x64.dasc"
/*| movzx edx, byte [PTR] */
/*| test dl, dl */
/*| jns >7 // Jump if first byte has no continuation bit. */
@@ -1110,48 +1115,48 @@ static void jitdispatch(jitcompiler *jc,
/*| shr edx, 3 */
/*| and cl, 7 */
dasm_put(Dst, 1889, 1);
-# 735 "upb/pb/compile_decoder_x64.dasc"
+# 740 "upb/pb/compile_decoder_x64.dasc"
/* See comment attached to upb_pbdecodermethod.dispatch for layout of the
* dispatch table. */
/*|2: */
/*| cmp edx, dispatch->array_size */
dasm_put(Dst, 1954, dispatch->array_size);
-# 740 "upb/pb/compile_decoder_x64.dasc"
+# 745 "upb/pb/compile_decoder_x64.dasc"
if (has_hash_entries) {
/*| jae >7 */
dasm_put(Dst, 1961);
-# 742 "upb/pb/compile_decoder_x64.dasc"
+# 747 "upb/pb/compile_decoder_x64.dasc"
} else {
/*| jae >5 */
dasm_put(Dst, 1966);
-# 744 "upb/pb/compile_decoder_x64.dasc"
+# 749 "upb/pb/compile_decoder_x64.dasc"
}
/*| // OPT: Compact the lookup arr into 32-bit entries. */
if ((uintptr_t)dispatch->array > 0x7fffffff) {
/*| mov64 rax, (uintptr_t)dispatch->array */
/*| mov rax, qword [rax + rdx * 8] */
dasm_put(Dst, 1971, (unsigned int)((uintptr_t)dispatch->array), (unsigned int)(((uintptr_t)dispatch->array)>>32));
-# 749 "upb/pb/compile_decoder_x64.dasc"
+# 754 "upb/pb/compile_decoder_x64.dasc"
} else {
/*| mov rax, qword [rdx * 8 + dispatch->array] */
dasm_put(Dst, 1980, dispatch->array);
-# 751 "upb/pb/compile_decoder_x64.dasc"
+# 756 "upb/pb/compile_decoder_x64.dasc"
}
/*|3: */
/*| // We take advantage of the fact that non-present entries are stored */
/*| // as -1, which will result in wire types that will never match. */
/*| cmp al, cl */
dasm_put(Dst, 1986);
-# 756 "upb/pb/compile_decoder_x64.dasc"
+# 761 "upb/pb/compile_decoder_x64.dasc"
if (has_multi_wiretype) {
/*| jne >6 */
dasm_put(Dst, 1991);
-# 758 "upb/pb/compile_decoder_x64.dasc"
+# 763 "upb/pb/compile_decoder_x64.dasc"
} else {
/*| jne >5 */
dasm_put(Dst, 1996);
-# 760 "upb/pb/compile_decoder_x64.dasc"
+# 765 "upb/pb/compile_decoder_x64.dasc"
}
/*| shr rax, 16 */
/*| */
@@ -1182,7 +1187,7 @@ static void jitdispatch(jitcompiler *jc,
/*| lea rax, [>9] // ENDGROUP; Load address of OP_ENDMSG. */
/*| ret */
dasm_put(Dst, 2001, define_jmptarget(jc, dispatch->array), (unsigned int)((uintptr_t)method->dest_handlers_), (unsigned int)(((uintptr_t)method->dest_handlers_)>>32), Dt1(->sink.handlers));
-# 789 "upb/pb/compile_decoder_x64.dasc"
+# 794 "upb/pb/compile_decoder_x64.dasc"
if (has_multi_wiretype) {
/*|6: */
@@ -1193,7 +1198,7 @@ static void jitdispatch(jitcompiler *jc,
/*| add rdx, UPB_MAX_FIELDNUMBER */
/*| // This key will never be in the array part, so do a hash lookup. */
dasm_put(Dst, 2043, UPB_MAX_FIELDNUMBER);
-# 798 "upb/pb/compile_decoder_x64.dasc"
+# 803 "upb/pb/compile_decoder_x64.dasc"
UPB_ASSERT(has_hash_entries);
/*| ld64 dispatch */
{
@@ -1206,10 +1211,10 @@ static void jitdispatch(jitcompiler *jc,
dasm_put(Dst, 454);
}
}
-# 800 "upb/pb/compile_decoder_x64.dasc"
+# 805 "upb/pb/compile_decoder_x64.dasc"
/*| jmp ->hashlookup // Tail call. */
dasm_put(Dst, 2056);
-# 801 "upb/pb/compile_decoder_x64.dasc"
+# 806 "upb/pb/compile_decoder_x64.dasc"
}
if (has_hash_entries) {
@@ -1227,11 +1232,11 @@ static void jitdispatch(jitcompiler *jc,
dasm_put(Dst, 454);
}
}
-# 807 "upb/pb/compile_decoder_x64.dasc"
+# 812 "upb/pb/compile_decoder_x64.dasc"
/*| call ->hashlookup */
/*| jmp <3 */
dasm_put(Dst, 2064);
-# 809 "upb/pb/compile_decoder_x64.dasc"
+# 814 "upb/pb/compile_decoder_x64.dasc"
}
}
@@ -1258,7 +1263,7 @@ static void jittag(jitcompiler *jc, uint64_t tag, int n, int ofs,
} else {
dasm_put(Dst, 2080, n);
}
-# 830 "upb/pb/compile_decoder_x64.dasc"
+# 835 "upb/pb/compile_decoder_x64.dasc"
/*| // OPT: this is way too much fallback code to put here. */
/*| // Reduce and/or move to a separate section to make better icache usage. */
@@ -1273,7 +1278,7 @@ static void jittag(jitcompiler *jc, uint64_t tag, int n, int ofs,
dasm_put(Dst, 454);
}
}
-# 834 "upb/pb/compile_decoder_x64.dasc"
+# 839 "upb/pb/compile_decoder_x64.dasc"
/*| call ->checktag_fallback */
/*| cmp eax, DECODE_MISMATCH */
/*| je >3 */
@@ -1281,21 +1286,21 @@ static void jittag(jitcompiler *jc, uint64_t tag, int n, int ofs,
/*| je =>jmptarget(jc, delimend) */
/*| jmp >5 */
dasm_put(Dst, 2096, DECODE_MISMATCH, DECODE_EOF, jmptarget(jc, delimend));
-# 840 "upb/pb/compile_decoder_x64.dasc"
+# 845 "upb/pb/compile_decoder_x64.dasc"
/*|1: */
dasm_put(Dst, 112);
-# 842 "upb/pb/compile_decoder_x64.dasc"
+# 847 "upb/pb/compile_decoder_x64.dasc"
switch (n) {
case 1:
/*| cmp byte [PTR], tag */
dasm_put(Dst, 2119, tag);
-# 845 "upb/pb/compile_decoder_x64.dasc"
+# 850 "upb/pb/compile_decoder_x64.dasc"
break;
case 2:
/*| cmp word [PTR], tag */
dasm_put(Dst, 2123, tag);
-# 848 "upb/pb/compile_decoder_x64.dasc"
+# 853 "upb/pb/compile_decoder_x64.dasc"
break;
case 3:
/*| // OPT: Slightly more efficient code, but depends on an extra byte. */
@@ -1307,41 +1312,41 @@ static void jittag(jitcompiler *jc, uint64_t tag, int n, int ofs,
/*| cmp byte [PTR + 2], (tag >> 16) */
/*|2: */
dasm_put(Dst, 2128, (tag & 0xffff), 2, (tag >> 16));
-# 858 "upb/pb/compile_decoder_x64.dasc"
+# 863 "upb/pb/compile_decoder_x64.dasc"
break;
case 4:
/*| cmp dword [PTR], tag */
dasm_put(Dst, 2143, tag);
-# 861 "upb/pb/compile_decoder_x64.dasc"
+# 866 "upb/pb/compile_decoder_x64.dasc"
break;
case 5:
/*| cmp dword [PTR], (tag & 0xffffffff) */
/*| jne >3 */
/*| cmp byte [PTR + 4], (tag >> 32) */
dasm_put(Dst, 2147, (tag & 0xffffffff), 4, (tag >> 32));
-# 866 "upb/pb/compile_decoder_x64.dasc"
+# 871 "upb/pb/compile_decoder_x64.dasc"
}
/*| je >4 */
/*|3: */
dasm_put(Dst, 2159);
-# 869 "upb/pb/compile_decoder_x64.dasc"
+# 874 "upb/pb/compile_decoder_x64.dasc"
if (ofs == 0) {
/*| call =>jmptarget(jc, &method->dispatch) */
/*| test rax, rax */
/*| jz =>jmptarget(jc, delimend) */
/*| jmp rax */
dasm_put(Dst, 2166, jmptarget(jc, &method->dispatch), jmptarget(jc, delimend));
-# 874 "upb/pb/compile_decoder_x64.dasc"
+# 879 "upb/pb/compile_decoder_x64.dasc"
} else {
/*| jmp =>jmptarget(jc, jc->pc + ofs) */
dasm_put(Dst, 2178, jmptarget(jc, jc->pc + ofs));
-# 876 "upb/pb/compile_decoder_x64.dasc"
+# 881 "upb/pb/compile_decoder_x64.dasc"
}
/*|4: */
/*| add PTR, n */
/*|5: */
dasm_put(Dst, 2182, n);
-# 880 "upb/pb/compile_decoder_x64.dasc"
+# 885 "upb/pb/compile_decoder_x64.dasc"
}
/* Compile the bytecode to x64. */
@@ -1364,7 +1369,7 @@ static void jitbytecode(jitcompiler *jc) {
* TODO: optimize this to only define pclabels that are actually used. */
/*|=>define_jmptarget(jc, jc->pc): */
dasm_put(Dst, 0, define_jmptarget(jc, jc->pc));
-# 901 "upb/pb/compile_decoder_x64.dasc"
+# 906 "upb/pb/compile_decoder_x64.dasc"
}
jc->pc++;
@@ -1379,7 +1384,7 @@ static void jitbytecode(jitcompiler *jc) {
/*| load_handler_data h, UPB_STARTMSG_SELECTOR */
dasm_put(Dst, 2191);
{
- uintptr_t v = (uintptr_t)upb_handlers_gethandlerdata(h, UPB_STARTMSG_SELECTOR);
+ uintptr_t v = (uintptr_t)gethandlerdata(h, UPB_STARTMSG_SELECTOR);
if (v > 0xffffffff) {
dasm_put(Dst, 446, (unsigned int)(v), (unsigned int)((v)>>32));
} else if (v) {
@@ -1388,10 +1393,10 @@ static void jitbytecode(jitcompiler *jc) {
dasm_put(Dst, 454);
}
}
-# 913 "upb/pb/compile_decoder_x64.dasc"
+# 918 "upb/pb/compile_decoder_x64.dasc"
/*| callp startmsg */
dasm_put(Dst, 1793, (unsigned int)((uintptr_t)startmsg), (unsigned int)(((uintptr_t)startmsg)>>32), 0xfffffffffffffff0UL);
-# 914 "upb/pb/compile_decoder_x64.dasc"
+# 919 "upb/pb/compile_decoder_x64.dasc"
if (!alwaysok(h, UPB_STARTMSG_SELECTOR)) {
/*| test al, al */
/*| jnz >2 */
@@ -1399,12 +1404,12 @@ static void jitbytecode(jitcompiler *jc) {
/*| jmp <1 */
/*|2: */
dasm_put(Dst, 2198);
-# 920 "upb/pb/compile_decoder_x64.dasc"
+# 925 "upb/pb/compile_decoder_x64.dasc"
}
} else {
/*| nop */
dasm_put(Dst, 2214);
-# 923 "upb/pb/compile_decoder_x64.dasc"
+# 928 "upb/pb/compile_decoder_x64.dasc"
}
break;
}
@@ -1412,14 +1417,14 @@ static void jitbytecode(jitcompiler *jc) {
upb_func *endmsg = gethandler(h, UPB_ENDMSG_SELECTOR);
/*|9: */
dasm_put(Dst, 2216);
-# 929 "upb/pb/compile_decoder_x64.dasc"
+# 934 "upb/pb/compile_decoder_x64.dasc"
if (endmsg) {
/* bool endmsg(void *closure, const void *hd, upb_status *status) */
/*| mov ARG1_64, CLOSURE */
/*| load_handler_data h, UPB_ENDMSG_SELECTOR */
dasm_put(Dst, 1788);
{
- uintptr_t v = (uintptr_t)upb_handlers_gethandlerdata(h, UPB_ENDMSG_SELECTOR);
+ uintptr_t v = (uintptr_t)gethandlerdata(h, UPB_ENDMSG_SELECTOR);
if (v > 0xffffffff) {
dasm_put(Dst, 446, (unsigned int)(v), (unsigned int)((v)>>32));
} else if (v) {
@@ -1428,11 +1433,11 @@ static void jitbytecode(jitcompiler *jc) {
dasm_put(Dst, 454);
}
}
-# 933 "upb/pb/compile_decoder_x64.dasc"
+# 938 "upb/pb/compile_decoder_x64.dasc"
/*| mov ARG3_64, DECODER->status */
/*| callp endmsg */
dasm_put(Dst, 2219, Dt2(->status), (unsigned int)((uintptr_t)endmsg), (unsigned int)(((uintptr_t)endmsg)>>32), 0xfffffffffffffff0UL);
-# 935 "upb/pb/compile_decoder_x64.dasc"
+# 940 "upb/pb/compile_decoder_x64.dasc"
}
break;
}
@@ -1465,7 +1470,7 @@ static void jitbytecode(jitcompiler *jc) {
/*|=>define_jmptarget(jc, method): */
/*| sub rsp, 8 */
dasm_put(Dst, 2245, define_jmptarget(jc, op_pc), define_jmptarget(jc, method));
-# 966 "upb/pb/compile_decoder_x64.dasc"
+# 971 "upb/pb/compile_decoder_x64.dasc"
break;
}
@@ -1497,7 +1502,7 @@ static void jitbytecode(jitcompiler *jc) {
/*| load_handler_data h, arg */
dasm_put(Dst, 2191);
{
- uintptr_t v = (uintptr_t)upb_handlers_gethandlerdata(h, arg);
+ uintptr_t v = (uintptr_t)gethandlerdata(h, arg);
if (v > 0xffffffff) {
dasm_put(Dst, 446, (unsigned int)(v), (unsigned int)((v)>>32));
} else if (v) {
@@ -1506,16 +1511,16 @@ static void jitbytecode(jitcompiler *jc) {
dasm_put(Dst, 454);
}
}
-# 995 "upb/pb/compile_decoder_x64.dasc"
+# 1000 "upb/pb/compile_decoder_x64.dasc"
if (op == OP_STARTSTR) {
/*| mov ARG3_64, DELIMEND */
/*| sub ARG3_64, PTR */
dasm_put(Dst, 2253);
-# 998 "upb/pb/compile_decoder_x64.dasc"
+# 1003 "upb/pb/compile_decoder_x64.dasc"
}
/*| callp start */
dasm_put(Dst, 1793, (unsigned int)((uintptr_t)start), (unsigned int)(((uintptr_t)start)>>32), 0xfffffffffffffff0UL);
-# 1000 "upb/pb/compile_decoder_x64.dasc"
+# 1005 "upb/pb/compile_decoder_x64.dasc"
if (!alwaysok(h, arg)) {
/*| test rax, rax */
/*| jnz >2 */
@@ -1523,16 +1528,16 @@ static void jitbytecode(jitcompiler *jc) {
/*| jmp <1 */
/*|2: */
dasm_put(Dst, 2261);
-# 1006 "upb/pb/compile_decoder_x64.dasc"
+# 1011 "upb/pb/compile_decoder_x64.dasc"
}
/*| mov CLOSURE, rax */
dasm_put(Dst, 2278);
-# 1008 "upb/pb/compile_decoder_x64.dasc"
+# 1013 "upb/pb/compile_decoder_x64.dasc"
} else {
/* TODO: nop is only required because of asmlabel(). */
/*| nop */
dasm_put(Dst, 2214);
-# 1011 "upb/pb/compile_decoder_x64.dasc"
+# 1016 "upb/pb/compile_decoder_x64.dasc"
}
break;
}
@@ -1549,7 +1554,7 @@ static void jitbytecode(jitcompiler *jc) {
/*| load_handler_data h, arg */
dasm_put(Dst, 2191);
{
- uintptr_t v = (uintptr_t)upb_handlers_gethandlerdata(h, arg);
+ uintptr_t v = (uintptr_t)gethandlerdata(h, arg);
if (v > 0xffffffff) {
dasm_put(Dst, 446, (unsigned int)(v), (unsigned int)((v)>>32));
} else if (v) {
@@ -1558,10 +1563,10 @@ static void jitbytecode(jitcompiler *jc) {
dasm_put(Dst, 454);
}
}
-# 1025 "upb/pb/compile_decoder_x64.dasc"
+# 1030 "upb/pb/compile_decoder_x64.dasc"
/*| callp end */
dasm_put(Dst, 1793, (unsigned int)((uintptr_t)end), (unsigned int)(((uintptr_t)end)>>32), 0xfffffffffffffff0UL);
-# 1026 "upb/pb/compile_decoder_x64.dasc"
+# 1031 "upb/pb/compile_decoder_x64.dasc"
if (!alwaysok(h, arg)) {
/*| test al, al */
/*| jnz >2 */
@@ -1569,13 +1574,13 @@ static void jitbytecode(jitcompiler *jc) {
/*| jmp <1 */
/*|2: */
dasm_put(Dst, 2198);
-# 1032 "upb/pb/compile_decoder_x64.dasc"
+# 1037 "upb/pb/compile_decoder_x64.dasc"
}
} else {
/* TODO: nop is only required because of asmlabel(). */
/*| nop */
dasm_put(Dst, 2214);
-# 1036 "upb/pb/compile_decoder_x64.dasc"
+# 1041 "upb/pb/compile_decoder_x64.dasc"
}
break;
}
@@ -1590,7 +1595,7 @@ static void jitbytecode(jitcompiler *jc) {
/*| jmp <1 */
/*|2: */
dasm_put(Dst, 2282);
-# 1049 "upb/pb/compile_decoder_x64.dasc"
+# 1054 "upb/pb/compile_decoder_x64.dasc"
if (str) {
/* size_t str(void *closure, const void *hd, const char *str,
* size_t n) */
@@ -1598,7 +1603,7 @@ static void jitbytecode(jitcompiler *jc) {
/*| load_handler_data h, arg */
dasm_put(Dst, 1788);
{
- uintptr_t v = (uintptr_t)upb_handlers_gethandlerdata(h, arg);
+ uintptr_t v = (uintptr_t)gethandlerdata(h, arg);
if (v > 0xffffffff) {
dasm_put(Dst, 446, (unsigned int)(v), (unsigned int)((v)>>32));
} else if (v) {
@@ -1607,7 +1612,7 @@ static void jitbytecode(jitcompiler *jc) {
dasm_put(Dst, 454);
}
}
-# 1054 "upb/pb/compile_decoder_x64.dasc"
+# 1059 "upb/pb/compile_decoder_x64.dasc"
/*| mov ARG3_64, PTR */
/*| mov ARG4_64, DATAEND */
/*| sub ARG4_64, PTR */
@@ -1615,25 +1620,25 @@ static void jitbytecode(jitcompiler *jc) {
/*| callp str */
/*| add PTR, rax */
dasm_put(Dst, 2309, Dt2(->handle), (unsigned int)((uintptr_t)str), (unsigned int)(((uintptr_t)str)>>32), 0xfffffffffffffff0UL);
-# 1060 "upb/pb/compile_decoder_x64.dasc"
+# 1065 "upb/pb/compile_decoder_x64.dasc"
if (!alwaysok(h, arg)) {
/*| cmp PTR, DATAEND */
/*| je >3 */
/*| call ->strret_fallback */
/*|3: */
dasm_put(Dst, 2347);
-# 1065 "upb/pb/compile_decoder_x64.dasc"
+# 1070 "upb/pb/compile_decoder_x64.dasc"
}
} else {
/*| mov PTR, DATAEND */
dasm_put(Dst, 2360);
-# 1068 "upb/pb/compile_decoder_x64.dasc"
+# 1073 "upb/pb/compile_decoder_x64.dasc"
}
/*| cmp PTR, DELIMEND */
/*| jne <1 */
/*|4: */
dasm_put(Dst, 2364);
-# 1072 "upb/pb/compile_decoder_x64.dasc"
+# 1077 "upb/pb/compile_decoder_x64.dasc"
break;
}
case OP_PUSHTAGDELIM:
@@ -1649,18 +1654,18 @@ static void jitbytecode(jitcompiler *jc) {
/*| add FRAME, sizeof(upb_pbdecoder_frame) */
/*| mov dword FRAME->groupnum, arg */
dasm_put(Dst, 2375, Dt1(->sink.closure), Dt1(->end_ofs), Dt2(->limit), sizeof(upb_pbdecoder_frame), Dt1(->groupnum), arg);
-# 1086 "upb/pb/compile_decoder_x64.dasc"
+# 1091 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_PUSHLENDELIM:
/*| call ->pushlendelim */
dasm_put(Dst, 2405);
-# 1089 "upb/pb/compile_decoder_x64.dasc"
+# 1094 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_POP:
/*| sub FRAME, sizeof(upb_pbdecoder_frame) */
/*| mov CLOSURE, FRAME->sink.closure */
dasm_put(Dst, 2409, sizeof(upb_pbdecoder_frame), Dt1(->sink.closure));
-# 1093 "upb/pb/compile_decoder_x64.dasc"
+# 1098 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_SETDELIM:
/* OPT: experiment with testing vs old offset to optimize away. */
@@ -1673,35 +1678,35 @@ static void jitbytecode(jitcompiler *jc) {
/*| mov DATAEND, DELIMEND */
/*|1: */
dasm_put(Dst, 2419, Dt2(->end), Dt1(->end_ofs), Dt2(->buf));
-# 1104 "upb/pb/compile_decoder_x64.dasc"
+# 1109 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_SETBIGGROUPNUM:
/*| mov dword FRAME->groupnum, *jc->pc++ */
dasm_put(Dst, 2399, Dt1(->groupnum), *jc->pc++);
-# 1107 "upb/pb/compile_decoder_x64.dasc"
+# 1112 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_CHECKDELIM:
/*| cmp DELIMEND, PTR */
/*| je =>jmptarget(jc, jc->pc + longofs) */
dasm_put(Dst, 2449, jmptarget(jc, jc->pc + longofs));
-# 1111 "upb/pb/compile_decoder_x64.dasc"
+# 1116 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_CALL:
/*| call =>jmptarget(jc, jc->pc + longofs) */
dasm_put(Dst, 2456, jmptarget(jc, jc->pc + longofs));
-# 1114 "upb/pb/compile_decoder_x64.dasc"
+# 1119 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_BRANCH:
/*| jmp =>jmptarget(jc, jc->pc + longofs); */
dasm_put(Dst, 2178, jmptarget(jc, jc->pc + longofs));
-# 1117 "upb/pb/compile_decoder_x64.dasc"
+# 1122 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_RET:
/*|9: */
/*| add rsp, 8 */
/*| ret */
dasm_put(Dst, 2459);
-# 1122 "upb/pb/compile_decoder_x64.dasc"
+# 1127 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_TAG1:
jittag(jc, (arg >> 8) & 0xff, 1, (int8_t)arg, method);
@@ -1718,7 +1723,7 @@ static void jitbytecode(jitcompiler *jc) {
case OP_DISPATCH:
/*| call =>jmptarget(jc, &method->dispatch) */
dasm_put(Dst, 2456, jmptarget(jc, &method->dispatch));
-# 1137 "upb/pb/compile_decoder_x64.dasc"
+# 1142 "upb/pb/compile_decoder_x64.dasc"
break;
case OP_HALT:
UPB_ASSERT(false);
@@ -1728,5 +1733,5 @@ static void jitbytecode(jitcompiler *jc) {
asmlabel(jc, "eof");
/*| nop */
dasm_put(Dst, 2214);
-# 1145 "upb/pb/compile_decoder_x64.dasc"
+# 1150 "upb/pb/compile_decoder_x64.dasc"
}
diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c
index 0cae05b..f1617db 100644
--- a/upb/pb/decoder.c
+++ b/upb/pb/decoder.c
@@ -99,9 +99,7 @@ static bool in_residual_buf(const upb_pbdecoder *d, const char *p);
* benchmarks. */
static void seterr(upb_pbdecoder *d, const char *msg) {
- upb_status status = UPB_STATUS_INIT;
- upb_status_seterrmsg(&status, msg);
- upb_env_reporterror(d->env, &status);
+ upb_status_seterrmsg(d->status, msg);
}
void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) {
@@ -992,40 +990,39 @@ void upb_pbdecoder_reset(upb_pbdecoder *d) {
d->residual_end = d->residual;
}
-upb_pbdecoder *upb_pbdecoder_create(upb_env *e, const upb_pbdecodermethod *m,
- upb_sink *sink) {
+upb_pbdecoder *upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m,
+ upb_sink sink, upb_status *status) {
const size_t default_max_nesting = 64;
#ifndef NDEBUG
- size_t size_before = upb_env_bytesallocated(e);
+ size_t size_before = upb_arena_bytesallocated(a);
#endif
- upb_pbdecoder *d = upb_env_malloc(e, sizeof(upb_pbdecoder));
+ upb_pbdecoder *d = upb_arena_malloc(a, sizeof(upb_pbdecoder));
if (!d) return NULL;
d->method_ = m;
- d->callstack = upb_env_malloc(e, callstacksize(d, default_max_nesting));
- d->stack = upb_env_malloc(e, stacksize(d, default_max_nesting));
+ d->callstack = upb_arena_malloc(a, callstacksize(d, default_max_nesting));
+ d->stack = upb_arena_malloc(a, stacksize(d, default_max_nesting));
if (!d->stack || !d->callstack) {
return NULL;
}
- d->env = e;
+ d->arena = a;
d->limit = d->stack + default_max_nesting - 1;
d->stack_size = default_max_nesting;
- d->status = NULL;
+ d->status = status;
upb_pbdecoder_reset(d);
upb_bytessink_reset(&d->input_, &m->input_handler_, d);
- UPB_ASSERT(sink);
if (d->method_->dest_handlers_) {
- if (sink->handlers != d->method_->dest_handlers_)
+ if (sink.handlers != d->method_->dest_handlers_)
return NULL;
}
- upb_sink_reset(&d->top->sink, sink->handlers, sink->closure);
+ d->top->sink = sink;
/* If this fails, increase the value in decoder.h. */
- UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(e) - size_before <=
+ UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(a) - size_before <=
UPB_PB_DECODER_SIZE);
return d;
}
@@ -1038,8 +1035,8 @@ const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d) {
return d->method_;
}
-upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d) {
- return &d->input_;
+upb_bytessink upb_pbdecoder_input(upb_pbdecoder *d) {
+ return d->input_;
}
size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d) {
@@ -1058,7 +1055,7 @@ bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
/* Need to reallocate stack and callstack to accommodate. */
size_t old_size = stacksize(d, d->stack_size);
size_t new_size = stacksize(d, max);
- void *p = upb_env_realloc(d->env, d->stack, old_size, new_size);
+ void *p = upb_arena_realloc(d->arena, d->stack, old_size, new_size);
if (!p) {
return false;
}
@@ -1066,7 +1063,7 @@ bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
old_size = callstacksize(d, d->stack_size);
new_size = callstacksize(d, max);
- p = upb_env_realloc(d->env, d->callstack, old_size, new_size);
+ p = upb_arena_realloc(d->arena, d->callstack, old_size, new_size);
if (!p) {
return false;
}
diff --git a/upb/pb/decoder.h b/upb/pb/decoder.h
index 7c1877a..5adfba8 100644
--- a/upb/pb/decoder.h
+++ b/upb/pb/decoder.h
@@ -21,20 +21,13 @@
namespace upb {
namespace pb {
class CodeCache;
-class Decoder;
-class DecoderMethod;
+class DecoderPtr;
+class DecoderMethodPtr;
class DecoderMethodOptions;
} /* namespace pb */
} /* namespace upb */
#endif
-UPB_DECLARE_TYPE(upb::pb::CodeCache, upb_pbcodecache)
-UPB_DECLARE_TYPE(upb::pb::Decoder, upb_pbdecoder)
-UPB_DECLARE_TYPE(upb::pb::DecoderMethodOptions, upb_pbdecodermethodopts)
-
-UPB_DECLARE_DERIVED_TYPE(upb::pb::DecoderMethod, upb::RefCounted,
- upb_pbdecodermethod, upb_refcounted)
-
/* The maximum number of bytes we are required to buffer internally between
* calls to the decoder. The value is 14: a 5 byte unknown tag plus ten-byte
* varint, less one because we are buffering an incomplete value.
@@ -42,83 +35,110 @@ UPB_DECLARE_DERIVED_TYPE(upb::pb::DecoderMethod, upb::RefCounted,
* Should only be used by unit tests. */
#define UPB_DECODER_MAX_RESIDUAL_BYTES 14
-#ifdef __cplusplus
+/* upb_pbdecodermethod ********************************************************/
-/* The parameters one uses to construct a DecoderMethod.
- * TODO(haberman): move allowjit here? Seems more convenient for users.
- * TODO(haberman): move this to be heap allocated for ABI stability. */
-class upb::pb::DecoderMethodOptions {
- public:
- /* Parameter represents the destination handlers that this method will push
- * to. */
- explicit DecoderMethodOptions(const Handlers* dest_handlers);
+struct upb_pbdecodermethod;
+typedef struct upb_pbdecodermethod upb_pbdecodermethod;
- /* Should the decoder push submessages to lazy handlers for fields that have
- * them? The caller should set this iff the lazy handlers expect data that is
- * in protobuf binary format and the caller wishes to lazy parse it. */
- void set_lazy(bool lazy);
-#else
-struct upb_pbdecodermethodopts {
+#ifdef __cplusplus
+extern "C" {
#endif
- const upb_handlers *handlers;
- bool lazy;
-};
+
+const upb_handlers *upb_pbdecodermethod_desthandlers(
+ const upb_pbdecodermethod *m);
+const upb_byteshandler *upb_pbdecodermethod_inputhandler(
+ const upb_pbdecodermethod *m);
+bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m);
#ifdef __cplusplus
+} /* extern "C" */
/* Represents the code to parse a protobuf according to a destination
* Handlers. */
-class upb::pb::DecoderMethod {
+class upb::pb::DecoderMethodPtr {
public:
- /* Include base methods from upb::ReferenceCounted. */
- UPB_REFCOUNTED_CPPMETHODS
+ DecoderMethodPtr() : ptr_(nullptr) {}
+ DecoderMethodPtr(const upb_pbdecodermethod* ptr) : ptr_(ptr) {}
+
+ const upb_pbdecodermethod* ptr() { return ptr_; }
/* The destination handlers that are statically bound to this method.
* This method is only capable of outputting to a sink that uses these
* handlers. */
- const Handlers* dest_handlers() const;
+ const Handlers *dest_handlers() const {
+ return upb_pbdecodermethod_desthandlers(ptr_);
+ }
/* The input handlers for this decoder method. */
- const BytesHandler* input_handler() const;
+ const BytesHandler* input_handler() const {
+ return upb_pbdecodermethod_inputhandler(ptr_);
+ }
/* Whether this method is native. */
- bool is_native() const;
-
- /* Convenience method for generating a DecoderMethod without explicitly
- * creating a CodeCache. */
- static reffed_ptr<const DecoderMethod> New(const DecoderMethodOptions& opts);
+ bool is_native() const {
+ return upb_pbdecodermethod_isnative(ptr_);
+ }
private:
- UPB_DISALLOW_POD_OPS(DecoderMethod, upb::pb::DecoderMethod)
+ const upb_pbdecodermethod* ptr_;
};
#endif
+/* upb_pbdecoder **************************************************************/
+
/* Preallocation hint: decoder won't allocate more bytes than this when first
* constructed. This hint may be an overestimate for some build configurations.
* But if the decoder library is upgraded without recompiling the application,
* it may be an underestimate. */
#define UPB_PB_DECODER_SIZE 4416
+struct upb_pbdecoder;
+typedef struct upb_pbdecoder upb_pbdecoder;
+
#ifdef __cplusplus
+extern "C" {
+#endif
+
+upb_pbdecoder *upb_pbdecoder_create(upb_arena *arena,
+ const upb_pbdecodermethod *method,
+ upb_sink output, upb_status *status);
+const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d);
+upb_bytessink upb_pbdecoder_input(upb_pbdecoder *d);
+uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d);
+size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d);
+bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max);
+void upb_pbdecoder_reset(upb_pbdecoder *d);
+
+#ifdef __cplusplus
+} /* extern "C" */
/* A Decoder receives binary protobuf data on its input sink and pushes the
* decoded data to its output sink. */
-class upb::pb::Decoder {
+class upb::pb::DecoderPtr {
public:
+ DecoderPtr(upb_pbdecoder* ptr) : ptr_(ptr) {}
+
+ upb_pbdecoder* ptr() { return ptr_; }
+
/* Constructs a decoder instance for the given method, which must outlive this
* decoder. Any errors during parsing will be set on the given status, which
* must also outlive this decoder.
*
* The sink must match the given method. */
- static Decoder* Create(Environment* env, const DecoderMethod* method,
- Sink* output);
+ static DecoderPtr Create(Arena *arena, DecoderMethodPtr method,
+ upb::Sink output, Status *status) {
+ return DecoderPtr(upb_pbdecoder_create(arena->ptr(), method.ptr(),
+ output.sink(), status->ptr()));
+ }
/* Returns the DecoderMethod this decoder is parsing from. */
- const DecoderMethod* method() const;
+ const DecoderMethodPtr method() const {
+ return DecoderMethodPtr(upb_pbdecoder_method(ptr_));
+ }
/* The sink on which this decoder receives input. */
- BytesSink* input();
+ BytesSink input() { return BytesSink(upb_pbdecoder_input(ptr())); }
/* Returns number of bytes successfully parsed.
*
@@ -127,7 +147,7 @@ class upb::pb::Decoder {
*
* This value may not be up-to-date when called from inside a parsing
* callback. */
- uint64_t BytesParsed() const;
+ uint64_t BytesParsed() { return upb_pbdecoder_bytesparsed(ptr()); }
/* Gets/sets the parsing nexting limit. If the total number of nested
* submessages and repeated fields hits this limit, parsing will fail. This
@@ -136,31 +156,52 @@ class upb::pb::Decoder {
*
* Setting the limit will fail if the parser is currently suspended at a depth
* greater than this, or if memory allocation of the stack fails. */
- size_t max_nesting() const;
- bool set_max_nesting(size_t max);
+ size_t max_nesting() { return upb_pbdecoder_maxnesting(ptr()); }
+ bool set_max_nesting(size_t max) { return upb_pbdecoder_maxnesting(ptr()); }
- void Reset();
+ void Reset() { upb_pbdecoder_reset(ptr()); }
static const size_t kSize = UPB_PB_DECODER_SIZE;
private:
- UPB_DISALLOW_POD_OPS(Decoder, upb::pb::Decoder)
+ upb_pbdecoder *ptr_;
};
#endif /* __cplusplus */
+/* upb_pbcodecache ************************************************************/
+
+struct upb_pbcodecache;
+typedef struct upb_pbcodecache upb_pbcodecache;
+
#ifdef __cplusplus
+extern "C" {
+#endif
+
+upb_pbcodecache *upb_pbcodecache_new(upb_handlercache *dest);
+void upb_pbcodecache_free(upb_pbcodecache *c);
+bool upb_pbcodecache_allowjit(const upb_pbcodecache *c);
+void upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow);
+void upb_pbcodecache_setlazy(upb_pbcodecache *c, bool lazy);
+const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c,
+ const upb_msgdef *md);
+
+#ifdef __cplusplus
+} /* extern "C" */
/* A class for caching protobuf processing code, whether bytecode for the
* interpreted decoder or machine code for the JIT.
*
- * This class is not thread-safe.
- *
- * TODO(haberman): move this to be heap allocated for ABI stability. */
+ * This class is not thread-safe. */
class upb::pb::CodeCache {
public:
- CodeCache();
- ~CodeCache();
+ CodeCache(upb::HandlerCache *dest)
+ : ptr_(upb_pbcodecache_new(dest->ptr()), upb_pbcodecache_free) {}
+ CodeCache(CodeCache&&) = default;
+ CodeCache& operator=(CodeCache&&) = default;
+
+ upb_pbcodecache* ptr() { return ptr_.get(); }
+ const upb_pbcodecache* ptr() const { return ptr_.get(); }
/* Whether the cache is allowed to generate machine code. Defaults to true.
* There is no real reason to turn it off except for testing or if you are
@@ -169,144 +210,27 @@ class upb::pb::CodeCache {
* Note that allow_jit = true does not *guarantee* that the code will be JIT
* compiled. If this platform is not supported or the JIT was not compiled
* in, the code may still be interpreted. */
- bool allow_jit() const;
+ bool allow_jit() const { return upb_pbcodecache_allowjit(ptr()); }
/* This may only be called when the object is first constructed, and prior to
- * any code generation, otherwise returns false and does nothing. */
- bool set_allow_jit(bool allow);
+ * any code generation. */
+ void set_allow_jit(bool allow) { upb_pbcodecache_setallowjit(ptr(), allow); }
- /* Returns a DecoderMethod that can push data to the given handlers.
- * If a suitable method already exists, it will be returned from the cache.
- *
- * Specifying the destination handlers here allows the DecoderMethod to be
- * statically bound to the destination handlers if possible, which can allow
- * more efficient decoding. However the returned method may or may not
- * actually be statically bound. But in all cases, the returned method can
- * push data to the given handlers. */
- const DecoderMethod *GetDecoderMethod(const DecoderMethodOptions& opts);
+ /* Should the decoder push submessages to lazy handlers for fields that have
+ * them? The caller should set this iff the lazy handlers expect data that is
+ * in protobuf binary format and the caller wishes to lazy parse it. */
+ void set_lazy(bool lazy) { upb_pbcodecache_setlazy(ptr(), lazy); }
- /* If/when someone needs to explicitly create a dynamically-bound
- * DecoderMethod*, we can add a method to get it here. */
+ /* Returns a DecoderMethod that can push data to the given handlers.
+ * If a suitable method already exists, it will be returned from the cache. */
+ const DecoderMethodPtr Get(MessageDefPtr md) {
+ return DecoderMethodPtr(upb_pbcodecache_get(ptr(), md.ptr()));
+ }
private:
- UPB_DISALLOW_COPY_AND_ASSIGN(CodeCache)
-#else
-struct upb_pbcodecache {
-#endif
- bool allow_jit_;
-
- /* Array of mgroups. */
- upb_inttable groups;
+ std::unique_ptr<upb_pbcodecache, decltype(&upb_pbcodecache_free)> ptr_;
};
-UPB_BEGIN_EXTERN_C
-
-upb_pbdecoder *upb_pbdecoder_create(upb_env *e,
- const upb_pbdecodermethod *method,
- upb_sink *output);
-const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d);
-upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d);
-uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d);
-size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d);
-bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max);
-void upb_pbdecoder_reset(upb_pbdecoder *d);
-
-void upb_pbdecodermethodopts_init(upb_pbdecodermethodopts *opts,
- const upb_handlers *h);
-void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy);
-
-
-/* Include refcounted methods like upb_pbdecodermethod_ref(). */
-UPB_REFCOUNTED_CMETHODS(upb_pbdecodermethod, upb_pbdecodermethod_upcast)
-
-const upb_handlers *upb_pbdecodermethod_desthandlers(
- const upb_pbdecodermethod *m);
-const upb_byteshandler *upb_pbdecodermethod_inputhandler(
- const upb_pbdecodermethod *m);
-bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m);
-const upb_pbdecodermethod *upb_pbdecodermethod_new(
- const upb_pbdecodermethodopts *opts, const void *owner);
-
-void upb_pbcodecache_init(upb_pbcodecache *c);
-void upb_pbcodecache_uninit(upb_pbcodecache *c);
-bool upb_pbcodecache_allowjit(const upb_pbcodecache *c);
-bool upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow);
-const upb_pbdecodermethod *upb_pbcodecache_getdecodermethod(
- upb_pbcodecache *c, const upb_pbdecodermethodopts *opts);
-
-UPB_END_EXTERN_C
-
-#ifdef __cplusplus
-
-namespace upb {
-
-namespace pb {
-
-/* static */
-inline Decoder* Decoder::Create(Environment* env, const DecoderMethod* m,
- Sink* sink) {
- return upb_pbdecoder_create(env, m, sink);
-}
-inline const DecoderMethod* Decoder::method() const {
- return upb_pbdecoder_method(this);
-}
-inline BytesSink* Decoder::input() {
- return upb_pbdecoder_input(this);
-}
-inline uint64_t Decoder::BytesParsed() const {
- return upb_pbdecoder_bytesparsed(this);
-}
-inline size_t Decoder::max_nesting() const {
- return upb_pbdecoder_maxnesting(this);
-}
-inline bool Decoder::set_max_nesting(size_t max) {
- return upb_pbdecoder_setmaxnesting(this, max);
-}
-inline void Decoder::Reset() { upb_pbdecoder_reset(this); }
-
-inline DecoderMethodOptions::DecoderMethodOptions(const Handlers* h) {
- upb_pbdecodermethodopts_init(this, h);
-}
-inline void DecoderMethodOptions::set_lazy(bool lazy) {
- upb_pbdecodermethodopts_setlazy(this, lazy);
-}
-
-inline const Handlers* DecoderMethod::dest_handlers() const {
- return upb_pbdecodermethod_desthandlers(this);
-}
-inline const BytesHandler* DecoderMethod::input_handler() const {
- return upb_pbdecodermethod_inputhandler(this);
-}
-inline bool DecoderMethod::is_native() const {
- return upb_pbdecodermethod_isnative(this);
-}
-/* static */
-inline reffed_ptr<const DecoderMethod> DecoderMethod::New(
- const DecoderMethodOptions &opts) {
- const upb_pbdecodermethod *m = upb_pbdecodermethod_new(&opts, &m);
- return reffed_ptr<const DecoderMethod>(m, &m);
-}
-
-inline CodeCache::CodeCache() {
- upb_pbcodecache_init(this);
-}
-inline CodeCache::~CodeCache() {
- upb_pbcodecache_uninit(this);
-}
-inline bool CodeCache::allow_jit() const {
- return upb_pbcodecache_allowjit(this);
-}
-inline bool CodeCache::set_allow_jit(bool allow) {
- return upb_pbcodecache_setallowjit(this, allow);
-}
-inline const DecoderMethod *CodeCache::GetDecoderMethod(
- const DecoderMethodOptions& opts) {
- return upb_pbcodecache_getdecodermethod(this, &opts);
-}
-
-} /* namespace pb */
-} /* namespace upb */
-
#endif /* __cplusplus */
#endif /* UPB_DECODER_H_ */
diff --git a/upb/pb/decoder.int.h b/upb/pb/decoder.int.h
index 4032570..47eb3ed 100644
--- a/upb/pb/decoder.int.h
+++ b/upb/pb/decoder.int.h
@@ -9,20 +9,8 @@
#include "upb/handlers.h"
#include "upb/pb/decoder.h"
#include "upb/sink.h"
-#include "upb/structdefs.int.h"
#include "upb/table.int.h"
-/* C++ names are not actually used since this type isn't exposed to users. */
-#ifdef __cplusplus
-namespace upb {
-namespace pb {
-class MessageGroup;
-} /* namespace pb */
-} /* namespace upb */
-#endif
-UPB_DECLARE_DERIVED_TYPE(upb::pb::MessageGroup, upb::RefCounted,
- mgroup, upb_refcounted)
-
/* Opcode definitions. The canonical meaning of each opcode is its
* implementation in the interpreter (the JIT is written to match this).
*
@@ -84,30 +72,25 @@ typedef enum {
UPB_INLINE opcode getop(uint32_t instr) { return instr & 0xff; }
+struct upb_pbcodecache {
+ upb_arena *arena;
+ upb_handlercache *dest;
+ bool allow_jit;
+ bool lazy;
+
+ /* Array of mgroups. */
+ upb_inttable groups;
+};
+
/* Method group; represents a set of decoder methods that had their code
- * emitted together, and must therefore be freed together. Immutable once
- * created. It is possible we may want to expose this to users at some point.
- *
- * Overall ownership of Decoder objects looks like this:
- *
- * +----------+
- * | | <---> DecoderMethod
- * | method |
- * CodeCache ---> | group | <---> DecoderMethod
- * | |
- * | (mgroup) | <---> DecoderMethod
- * +----------+
- */
-struct mgroup {
- upb_refcounted base;
-
- /* Maps upb_msgdef/upb_handlers -> upb_pbdecodermethod. We own refs on the
- * methods. */
+ * emitted together. Immutable once created. */
+typedef struct {
+ /* Maps upb_msgdef/upb_handlers -> upb_pbdecodermethod. Owned by us.
+ *
+ * Ideally this would be on pbcodecache (if we were actually caching code).
+ * Right now we don't actually cache anything, which is wasteful. */
upb_inttable methods;
- /* When we add the ability to link to previously existing mgroups, we'll
- * need an array of mgroups we reference here, and own refs on them. */
-
/* The bytecode for our methods, if any exists. Owned by us. */
uint32_t *bytecode;
uint32_t *bytecode_end;
@@ -120,7 +103,7 @@ struct mgroup {
char *debug_info;
void *dl;
#endif
-};
+} mgroup;
/* The maximum that any submessages can be nested. Matches proto2's limit.
* This specifies the size of the decoder's statically-sized array and therefore
@@ -160,8 +143,6 @@ typedef struct {
} upb_pbdecoder_frame;
struct upb_pbdecodermethod {
- upb_refcounted base;
-
/* While compiling, the base is relative in "ofs", after compiling it is
* absolute in "ptr". */
union {
@@ -169,14 +150,8 @@ struct upb_pbdecodermethod {
void *ptr; /* Pointer to bytecode or machine code for this method. */
} code_base;
- /* The decoder method group to which this method belongs. We own a ref.
- * Owning a ref on the entire group is more coarse-grained than is strictly
- * necessary; all we truly require is that methods we directly reference
- * outlive us, while the group could contain many other messages we don't
- * require. But the group represents the messages that were
- * allocated+compiled together, so it makes the most sense to free them
- * together also. */
- const upb_refcounted *group;
+ /* The decoder method group to which this method belongs. */
+ const mgroup *group;
/* Whether this method is native code or bytecode. */
bool is_native_;
@@ -194,7 +169,7 @@ struct upb_pbdecodermethod {
};
struct upb_pbdecoder {
- upb_env *env;
+ upb_arena *arena;
/* Our input sink. */
upb_bytessink input_;
@@ -277,7 +252,6 @@ const char *upb_pbdecoder_getopname(unsigned int op);
/* JIT codegen entry point. */
void upb_pbdecoder_jit(mgroup *group);
void upb_pbdecoder_freejit(mgroup *group);
-UPB_REFCOUNTED_CMETHODS(mgroup, mgroup_upcast)
/* A special label that means "do field dispatch for this message and branch to
* wherever that takes you." */
diff --git a/upb/pb/encoder.c b/upb/pb/encoder.c
index 839ede0..722cc5b 100644
--- a/upb/pb/encoder.c
+++ b/upb/pb/encoder.c
@@ -91,11 +91,11 @@ typedef struct {
} upb_pb_encoder_segment;
struct upb_pb_encoder {
- upb_env *env;
+ upb_arena *arena;
/* Our input and output. */
upb_sink input_;
- upb_bytessink *output_;
+ upb_bytessink output_;
/* The "subclosure" -- used as the inner closure as part of the bytessink
* protocol. */
@@ -127,7 +127,7 @@ struct upb_pb_encoder {
/* TODO(haberman): handle pushback */
static void putbuf(upb_pb_encoder *e, const char *buf, size_t len) {
- size_t n = upb_bytessink_putbuf(e->output_, e->subc, buf, len, NULL);
+ size_t n = upb_bytessink_putbuf(&e->output_, e->subc, buf, len, NULL);
UPB_ASSERT(n == len);
}
@@ -150,7 +150,7 @@ static bool reserve(upb_pb_encoder *e, size_t bytes) {
new_size *= 2;
}
- new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size);
+ new_buf = upb_arena_realloc(e->arena, e->buf, old_size, new_size);
if (new_buf == NULL) {
return false;
@@ -230,7 +230,7 @@ static bool start_delim(upb_pb_encoder *e) {
(e->seglimit - e->segbuf) * sizeof(upb_pb_encoder_segment);
size_t new_size = old_size * 2;
upb_pb_encoder_segment *new_buf =
- upb_env_realloc(e->env, e->segbuf, old_size, new_size);
+ upb_arena_realloc(e->arena, e->segbuf, old_size, new_size);
if (new_buf == NULL) {
return false;
@@ -304,8 +304,7 @@ static void new_tag(upb_handlers *h, const upb_fielddef *f, upb_wiretype_t wt,
tag_t *tag = upb_gmalloc(sizeof(tag_t));
tag->bytes = upb_vencode64((n << 3) | wt, tag->tag);
- upb_handlerattr_init(attr);
- upb_handlerattr_sethandlerdata(attr, tag);
+ attr->handler_data = tag;
upb_handlers_addcleanup(h, tag, upb_gfree);
}
@@ -354,7 +353,7 @@ static bool startmsg(void *c, const void *hd) {
upb_pb_encoder *e = c;
UPB_UNUSED(hd);
if (e->depth++ == 0) {
- upb_bytessink_start(e->output_, 0, &e->subc);
+ upb_bytessink_start(&e->output_, 0, &e->subc);
}
return true;
}
@@ -364,7 +363,7 @@ static bool endmsg(void *c, const void *hd, upb_status *status) {
UPB_UNUSED(hd);
UPB_UNUSED(status);
if (--e->depth == 0) {
- upb_bytessink_end(e->output_);
+ upb_bytessink_end(&e->output_);
}
return true;
}
@@ -451,7 +450,7 @@ static void newhandlers_callback(const void *closure, upb_handlers *h) {
const upb_fielddef *f = upb_msg_iter_field(&i);
bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) &&
upb_fielddef_packed(f);
- upb_handlerattr attr;
+ upb_handlerattr attr = UPB_HANDLERATTR_INIT;
upb_wiretype_t wt =
packed ? UPB_WIRE_TYPE_DELIMITED
: upb_pb_native_wire_types[upb_fielddef_descriptortype(f)];
@@ -500,20 +499,17 @@ static void newhandlers_callback(const void *closure, upb_handlers *h) {
break;
case UPB_DESCRIPTOR_TYPE_GROUP: {
/* Endgroup takes a different tag (wire_type = END_GROUP). */
- upb_handlerattr attr2;
+ upb_handlerattr attr2 = UPB_HANDLERATTR_INIT;
new_tag(h, f, UPB_WIRE_TYPE_END_GROUP, &attr2);
upb_handlers_setstartsubmsg(h, f, encode_startgroup, &attr);
upb_handlers_setendsubmsg(h, f, encode_endgroup, &attr2);
- upb_handlerattr_uninit(&attr2);
break;
}
}
#undef T
-
- upb_handlerattr_uninit(&attr);
}
}
@@ -526,27 +522,26 @@ void upb_pb_encoder_reset(upb_pb_encoder *e) {
/* public API *****************************************************************/
-const upb_handlers *upb_pb_encoder_newhandlers(const upb_msgdef *m,
- const void *owner) {
- return upb_handlers_newfrozen(m, owner, newhandlers_callback, NULL);
+upb_handlercache *upb_pb_encoder_newcache() {
+ return upb_handlercache_new(newhandlers_callback, NULL);
}
-upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h,
- upb_bytessink *output) {
+upb_pb_encoder *upb_pb_encoder_create(upb_arena *arena, const upb_handlers *h,
+ upb_bytessink output) {
const size_t initial_bufsize = 256;
const size_t initial_segbufsize = 16;
/* TODO(haberman): make this configurable. */
const size_t stack_size = 64;
#ifndef NDEBUG
- const size_t size_before = upb_env_bytesallocated(env);
+ const size_t size_before = upb_arena_bytesallocated(arena);
#endif
- upb_pb_encoder *e = upb_env_malloc(env, sizeof(upb_pb_encoder));
+ upb_pb_encoder *e = upb_arena_malloc(arena, sizeof(upb_pb_encoder));
if (!e) return NULL;
- e->buf = upb_env_malloc(env, initial_bufsize);
- e->segbuf = upb_env_malloc(env, initial_segbufsize * sizeof(*e->segbuf));
- e->stack = upb_env_malloc(env, stack_size * sizeof(*e->stack));
+ e->buf = upb_arena_malloc(arena, initial_bufsize);
+ e->segbuf = upb_arena_malloc(arena, initial_segbufsize * sizeof(*e->segbuf));
+ e->stack = upb_arena_malloc(arena, stack_size * sizeof(*e->stack));
if (!e->buf || !e->segbuf || !e->stack) {
return NULL;
@@ -559,15 +554,15 @@ upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h,
upb_pb_encoder_reset(e);
upb_sink_reset(&e->input_, h, e);
- e->env = env;
+ e->arena = arena;
e->output_ = output;
- e->subc = output->closure;
+ e->subc = output.closure;
e->ptr = e->buf;
/* If this fails, increase the value in encoder.h. */
- UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <=
+ UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <=
UPB_PB_ENCODER_SIZE);
return e;
}
-upb_sink *upb_pb_encoder_input(upb_pb_encoder *e) { return &e->input_; }
+upb_sink upb_pb_encoder_input(upb_pb_encoder *e) { return e->input_; }
diff --git a/upb/pb/encoder.h b/upb/pb/encoder.h
index 41b7e7b..780f60f 100644
--- a/upb/pb/encoder.h
+++ b/upb/pb/encoder.h
@@ -17,75 +17,65 @@
#ifdef __cplusplus
namespace upb {
namespace pb {
-class Encoder;
+class EncoderPtr;
} /* namespace pb */
} /* namespace upb */
#endif
-UPB_DECLARE_TYPE(upb::pb::Encoder, upb_pb_encoder)
-
#define UPB_PBENCODER_MAX_NESTING 100
-/* upb::pb::Encoder ***********************************************************/
+/* upb_pb_encoder *************************************************************/
/* Preallocation hint: decoder won't allocate more bytes than this when first
* constructed. This hint may be an overestimate for some build configurations.
* But if the decoder library is upgraded without recompiling the application,
* it may be an underestimate. */
-#define UPB_PB_ENCODER_SIZE 768
+#define UPB_PB_ENCODER_SIZE 784
+
+struct upb_pb_encoder;
+typedef struct upb_pb_encoder upb_pb_encoder;
#ifdef __cplusplus
+extern "C" {
+#endif
-class upb::pb::Encoder {
+upb_sink upb_pb_encoder_input(upb_pb_encoder *p);
+upb_pb_encoder* upb_pb_encoder_create(upb_arena* a, const upb_handlers* h,
+ upb_bytessink output);
+
+upb_handlercache *upb_pb_encoder_newcache();
+
+#ifdef __cplusplus
+} /* extern "C" { */
+
+class upb::pb::EncoderPtr {
public:
+ EncoderPtr(upb_pb_encoder* ptr) : ptr_(ptr) {}
+
+ upb_pb_encoder* ptr() { return ptr_; }
+
/* Creates a new encoder in the given environment. The Handlers must have
* come from NewHandlers() below. */
- static Encoder* Create(Environment* env, const Handlers* handlers,
- BytesSink* output);
+ static EncoderPtr Create(Arena* arena, const Handlers* handlers,
+ BytesSink output) {
+ return EncoderPtr(
+ upb_pb_encoder_create(arena->ptr(), handlers, output.sink()));
+ }
/* The input to the encoder. */
- Sink* input();
+ upb::Sink input() { return upb_pb_encoder_input(ptr()); }
/* Creates a new set of handlers for this MessageDef. */
- static reffed_ptr<const Handlers> NewHandlers(const MessageDef* msg);
+ static HandlerCache NewCache() {
+ return HandlerCache(upb_pb_encoder_newcache());
+ }
static const size_t kSize = UPB_PB_ENCODER_SIZE;
private:
- UPB_DISALLOW_POD_OPS(Encoder, upb::pb::Encoder)
+ upb_pb_encoder* ptr_;
};
-#endif
-
-UPB_BEGIN_EXTERN_C
-
-const upb_handlers *upb_pb_encoder_newhandlers(const upb_msgdef *m,
- const void *owner);
-upb_sink *upb_pb_encoder_input(upb_pb_encoder *p);
-upb_pb_encoder* upb_pb_encoder_create(upb_env* e, const upb_handlers* h,
- upb_bytessink* output);
-
-UPB_END_EXTERN_C
-
-#ifdef __cplusplus
-
-namespace upb {
-namespace pb {
-inline Encoder* Encoder::Create(Environment* env, const Handlers* handlers,
- BytesSink* output) {
- return upb_pb_encoder_create(env, handlers, output);
-}
-inline Sink* Encoder::input() {
- return upb_pb_encoder_input(this);
-}
-inline reffed_ptr<const Handlers> Encoder::NewHandlers(
- const upb::MessageDef *md) {
- const Handlers* h = upb_pb_encoder_newhandlers(md, &h);
- return reffed_ptr<const Handlers>(h, &h);
-}
-} /* namespace pb */
-} /* namespace upb */
-
-#endif
+#endif /* __cplusplus */
#endif /* UPB_ENCODER_H_ */
diff --git a/upb/pb/glue.c b/upb/pb/glue.c
deleted file mode 100644
index fb2b769..0000000
--- a/upb/pb/glue.c
+++ /dev/null
@@ -1,54 +0,0 @@
-
-#include "upb/pb/glue.h"
-
-#include "upb/descriptor/reader.h"
-#include "upb/pb/decoder.h"
-
-upb_filedef **upb_loaddescriptor(const char *buf, size_t n, const void *owner,
- upb_status *status) {
- /* Create handlers. */
- const upb_pbdecodermethod *decoder_m;
- const upb_handlers *reader_h = upb_descreader_newhandlers(&reader_h);
- upb_env env;
- upb_pbdecodermethodopts opts;
- upb_pbdecoder *decoder;
- upb_descreader *reader;
- bool ok;
- size_t i;
- upb_filedef **ret = NULL;
-
- upb_pbdecodermethodopts_init(&opts, reader_h);
- decoder_m = upb_pbdecodermethod_new(&opts, &decoder_m);
-
- upb_env_init(&env);
- upb_env_reporterrorsto(&env, status);
-
- reader = upb_descreader_create(&env, reader_h);
- decoder = upb_pbdecoder_create(&env, decoder_m, upb_descreader_input(reader));
-
- /* Push input data. */
- ok = upb_bufsrc_putbuf(buf, n, upb_pbdecoder_input(decoder));
-
- if (!ok) {
- goto cleanup;
- }
-
- ret = upb_gmalloc(sizeof (*ret) * (upb_descreader_filecount(reader) + 1));
-
- if (!ret) {
- goto cleanup;
- }
-
- for (i = 0; i < upb_descreader_filecount(reader); i++) {
- ret[i] = upb_descreader_file(reader, i);
- upb_filedef_ref(ret[i], owner);
- }
-
- ret[i] = NULL;
-
-cleanup:
- upb_env_uninit(&env);
- upb_handlers_unref(reader_h, &reader_h);
- upb_pbdecodermethod_unref(decoder_m, &decoder_m);
- return ret;
-}
diff --git a/upb/pb/glue.h b/upb/pb/glue.h
deleted file mode 100644
index 716fc0e..0000000
--- a/upb/pb/glue.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-** upb's core components like upb_decoder and upb_msg are carefully designed to
-** avoid depending on each other for maximum orthogonality. In other words,
-** you can use a upb_decoder to decode into *any* kind of structure; upb_msg is
-** just one such structure. A upb_msg can be serialized/deserialized into any
-** format, protobuf binary format is just one such format.
-**
-** However, for convenience we provide functions here for doing common
-** operations like deserializing protobuf binary format into a upb_msg. The
-** compromise is that this file drags in almost all of upb as a dependency,
-** which could be undesirable if you're trying to use a trimmed-down build of
-** upb.
-**
-** While these routines are convenient, they do not reuse any encoding/decoding
-** state. For example, if a decoder is JIT-based, it will be re-JITted every
-** time these functions are called. For this reason, if you are parsing lots
-** of data and efficiency is an issue, these may not be the best functions to
-** use (though they are useful for prototyping, before optimizing).
-*/
-
-#ifndef UPB_GLUE_H
-#define UPB_GLUE_H
-
-#include <stdbool.h>
-#include "upb/def.h"
-
-#ifdef __cplusplus
-#include <vector>
-
-extern "C" {
-#endif
-
-/* Loads a binary descriptor and returns a NULL-terminated array of unfrozen
- * filedefs. The caller owns the returned array, which must be freed with
- * upb_gfree(). */
-upb_filedef **upb_loaddescriptor(const char *buf, size_t n, const void *owner,
- upb_status *status);
-
-#ifdef __cplusplus
-} /* extern "C" */
-
-namespace upb {
-
-inline bool LoadDescriptor(const char* buf, size_t n, Status* status,
- std::vector<reffed_ptr<FileDef> >* files) {
- FileDef** parsed_files = upb_loaddescriptor(buf, n, &parsed_files, status);
-
- if (parsed_files) {
- FileDef** p = parsed_files;
- while (*p) {
- files->push_back(reffed_ptr<FileDef>(*p, &parsed_files));
- ++p;
- }
- free(parsed_files);
- return true;
- } else {
- return false;
- }
-}
-
-/* Templated so it can accept both string and std::string. */
-template <typename T>
-bool LoadDescriptor(const T& desc, Status* status,
- std::vector<reffed_ptr<FileDef> >* files) {
- return LoadDescriptor(desc.c_str(), desc.size(), status, files);
-}
-
-} /* namespace upb */
-
-#endif
-
-#endif /* UPB_GLUE_H */
diff --git a/upb/pb/textprinter.c b/upb/pb/textprinter.c
index abfc2eb..91d0d55 100644
--- a/upb/pb/textprinter.c
+++ b/upb/pb/textprinter.c
@@ -18,7 +18,7 @@
struct upb_textprinter {
upb_sink input_;
- upb_bytessink *output_;
+ upb_bytessink output_;
int indent_depth_;
bool single_line_;
void *subc;
@@ -35,13 +35,13 @@ static int indent(upb_textprinter *p) {
int i;
if (!p->single_line_)
for (i = 0; i < p->indent_depth_; i++)
- upb_bytessink_putbuf(p->output_, p->subc, " ", 2, NULL);
+ upb_bytessink_putbuf(&p->output_, p->subc, " ", 2, NULL);
return 0;
}
static int endfield(upb_textprinter *p) {
const char ch = (p->single_line_ ? ' ' : '\n');
- upb_bytessink_putbuf(p->output_, p->subc, &ch, 1, NULL);
+ upb_bytessink_putbuf(&p->output_, p->subc, &ch, 1, NULL);
return 0;
}
@@ -60,7 +60,7 @@ static int putescaped(upb_textprinter *p, const char *buf, size_t len,
bool is_hex_escape;
if (dstend - dst < 4) {
- upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
+ upb_bytessink_putbuf(&p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
dst = dstbuf;
}
@@ -88,7 +88,7 @@ static int putescaped(upb_textprinter *p, const char *buf, size_t len,
last_hex_escape = is_hex_escape;
}
/* Flush remaining data. */
- upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
+ upb_bytessink_putbuf(&p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
return 0;
}
@@ -114,7 +114,7 @@ bool putf(upb_textprinter *p, const char *fmt, ...) {
va_end(args);
UPB_ASSERT(written == len);
- ok = upb_bytessink_putbuf(p->output_, p->subc, str, len, NULL);
+ ok = upb_bytessink_putbuf(&p->output_, p->subc, str, len, NULL);
upb_gfree(str);
return ok;
}
@@ -126,7 +126,7 @@ static bool textprinter_startmsg(void *c, const void *hd) {
upb_textprinter *p = c;
UPB_UNUSED(hd);
if (p->indent_depth_ == 0) {
- upb_bytessink_start(p->output_, 0, &p->subc);
+ upb_bytessink_start(&p->output_, 0, &p->subc);
}
return true;
}
@@ -136,7 +136,7 @@ static bool textprinter_endmsg(void *c, const void *hd, upb_status *s) {
UPB_UNUSED(hd);
UPB_UNUSED(s);
if (p->indent_depth_ == 0) {
- upb_bytessink_end(p->output_);
+ upb_bytessink_end(&p->output_);
}
return true;
}
@@ -183,7 +183,7 @@ static bool textprinter_putenum(void *closure, const void *handler_data,
int32_t val) {
upb_textprinter *p = closure;
const upb_fielddef *f = handler_data;
- const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f));
+ const upb_enumdef *enum_def = upb_fielddef_enumsubdef(f);
const char *label = upb_enumdef_iton(enum_def, val);
if (label) {
indent(p);
@@ -241,7 +241,7 @@ static bool textprinter_endsubmsg(void *closure, const void *handler_data) {
UPB_UNUSED(handler_data);
p->indent_depth_--;
CHECK(indent(p));
- upb_bytessink_putbuf(p->output_, p->subc, "}", 1, NULL);
+ upb_bytessink_putbuf(&p->output_, p->subc, "}", 1, NULL);
CHECK(endfield(p));
return true;
err:
@@ -260,8 +260,8 @@ static void onmreg(const void *c, upb_handlers *h) {
!upb_msg_field_done(&i);
upb_msg_field_next(&i)) {
upb_fielddef *f = upb_msg_iter_field(&i);
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlerattr_sethandlerdata(&attr, f);
+ upb_handlerattr attr = UPB_HANDLERATTR_INIT;
+ attr.handler_data = f;
switch (upb_fielddef_type(f)) {
case UPB_TYPE_INT32:
upb_handlers_setint32(h, f, textprinter_putint32, &attr);
@@ -292,10 +292,10 @@ static void onmreg(const void *c, upb_handlers *h) {
break;
case UPB_TYPE_MESSAGE: {
const char *name =
- upb_fielddef_istagdelim(f)
+ upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_GROUP
? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f)))
: upb_fielddef_name(f);
- upb_handlerattr_sethandlerdata(&attr, name);
+ attr.handler_data = name;
upb_handlers_setstartsubmsg(h, f, textprinter_startsubmsg, &attr);
upb_handlers_setendsubmsg(h, f, textprinter_endsubmsg, &attr);
break;
@@ -315,9 +315,9 @@ static void textprinter_reset(upb_textprinter *p, bool single_line) {
/* Public API *****************************************************************/
-upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h,
- upb_bytessink *output) {
- upb_textprinter *p = upb_env_malloc(env, sizeof(upb_textprinter));
+upb_textprinter *upb_textprinter_create(upb_arena *arena, const upb_handlers *h,
+ upb_bytessink output) {
+ upb_textprinter *p = upb_arena_malloc(arena, sizeof(upb_textprinter));
if (!p) return NULL;
p->output_ = output;
@@ -327,12 +327,11 @@ upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h,
return p;
}
-const upb_handlers *upb_textprinter_newhandlers(const upb_msgdef *m,
- const void *owner) {
- return upb_handlers_newfrozen(m, owner, &onmreg, NULL);
+upb_handlercache *upb_textprinter_newcache() {
+ return upb_handlercache_new(&onmreg, NULL);
}
-upb_sink *upb_textprinter_input(upb_textprinter *p) { return &p->input_; }
+upb_sink upb_textprinter_input(upb_textprinter *p) { return p->input_; }
void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line) {
p->single_line_ = single_line;
diff --git a/upb/pb/textprinter.h b/upb/pb/textprinter.h
index 2f40ed8..e59e11d 100644
--- a/upb/pb/textprinter.h
+++ b/upb/pb/textprinter.h
@@ -17,63 +17,51 @@ class TextPrinter;
} /* namespace upb */
#endif
-UPB_DECLARE_TYPE(upb::pb::TextPrinter, upb_textprinter)
+/* upb_textprinter ************************************************************/
+
+struct upb_textprinter;
+typedef struct upb_textprinter upb_textprinter;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* C API. */
+upb_textprinter *upb_textprinter_create(upb_arena *arena, const upb_handlers *h,
+ upb_bytessink output);
+void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line);
+upb_sink upb_textprinter_input(upb_textprinter *p);
+upb_handlercache *upb_textprinter_newcache();
#ifdef __cplusplus
+} /* extern "C" */
-class upb::pb::TextPrinter {
+class upb::pb::TextPrinterPtr {
public:
+ TextPrinterPtr(upb_textprinter* ptr) : ptr_(ptr) {}
+
/* The given handlers must have come from NewHandlers(). It must outlive the
* TextPrinter. */
- static TextPrinter *Create(Environment *env, const upb::Handlers *handlers,
- BytesSink *output);
+ static TextPrinterPtr *Create(Arena *arena, const upb::Handlers *handlers,
+ BytesSink output) {
+ return TextPrinterPtr(upb_textprinter_create(arena, handlers, output));
+ }
- void SetSingleLineMode(bool single_line);
+ void SetSingleLineMode(bool single_line) {
+ upb_textprinter_setsingleline(ptr_, single_line);
+ }
- Sink* input();
+ Sink input() { return upb_textprinter_input(ptr_); }
/* If handler caching becomes a requirement we can add a code cache as in
* decoder.h */
- static reffed_ptr<const Handlers> NewHandlers(const MessageDef* md);
-};
-
-#endif
-
-UPB_BEGIN_EXTERN_C
+ static HandlerCache NewCache() {
+ return HandlerCache(upb_textprinter_newcache());
+ }
-/* C API. */
-upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h,
- upb_bytessink *output);
-void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line);
-upb_sink *upb_textprinter_input(upb_textprinter *p);
-
-const upb_handlers *upb_textprinter_newhandlers(const upb_msgdef *m,
- const void *owner);
-
-UPB_END_EXTERN_C
-
-#ifdef __cplusplus
-
-namespace upb {
-namespace pb {
-inline TextPrinter *TextPrinter::Create(Environment *env,
- const upb::Handlers *handlers,
- BytesSink *output) {
- return upb_textprinter_create(env, handlers, output);
-}
-inline void TextPrinter::SetSingleLineMode(bool single_line) {
- upb_textprinter_setsingleline(this, single_line);
-}
-inline Sink* TextPrinter::input() {
- return upb_textprinter_input(this);
-}
-inline reffed_ptr<const Handlers> TextPrinter::NewHandlers(
- const MessageDef *md) {
- const Handlers* h = upb_textprinter_newhandlers(md, &h);
- return reffed_ptr<const Handlers>(h, &h);
-}
-} /* namespace pb */
-} /* namespace upb */
+ private:
+ upb_textprinter* ptr_;
+};
#endif
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback