diff options
Diffstat (limited to 'upb/pb')
-rw-r--r-- | upb/pb/compile_decoder.c | 184 | ||||
-rw-r--r-- | upb/pb/compile_decoder_x64.c | 3 | ||||
-rw-r--r-- | upb/pb/compile_decoder_x64.dasc | 19 | ||||
-rw-r--r-- | upb/pb/compile_decoder_x64.h | 287 | ||||
-rw-r--r-- | upb/pb/decoder.c | 35 | ||||
-rw-r--r-- | upb/pb/decoder.h | 290 | ||||
-rw-r--r-- | upb/pb/decoder.int.h | 66 | ||||
-rw-r--r-- | upb/pb/encoder.c | 51 | ||||
-rw-r--r-- | upb/pb/encoder.h | 76 | ||||
-rw-r--r-- | upb/pb/glue.c | 54 | ||||
-rw-r--r-- | upb/pb/glue.h | 72 | ||||
-rw-r--r-- | upb/pb/textprinter.c | 41 | ||||
-rw-r--r-- | upb/pb/textprinter.h | 78 |
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 |