diff options
Diffstat (limited to 'upb/pb')
-rw-r--r-- | upb/pb/decoder.c | 55 | ||||
-rw-r--r-- | upb/pb/decoder.h | 4 | ||||
-rw-r--r-- | upb/pb/decoder_x64.dasc | 201 | ||||
-rw-r--r-- | upb/pb/glue.c | 4 | ||||
-rw-r--r-- | upb/pb/textprinter.c | 51 |
5 files changed, 198 insertions, 117 deletions
diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c index 2bfc717..18bb430 100644 --- a/upb/pb/decoder.c +++ b/upb/pb/decoder.c @@ -95,6 +95,10 @@ typedef struct { // Maps (upb_handlers* or upb_fielddef*) -> int32 pclabel_base upb_inttable pclabels; + // For marking labels that should go into the generated code. + // Maps pclabel -> owned char* label. + upb_inttable asmlabels; + // This is not the same as len(pclabels) because the table only contains base // offsets for each def, but each def can have many pclabels. uint32_t pclabel_count; @@ -131,7 +135,7 @@ static const upb_decoder_typeinfo upb_decoder_types[] = { static upb_selector_t getselector(const upb_fielddef *f, upb_handlertype_t type) { upb_selector_t selector; - bool ok = upb_getselector(f, type, &selector); + bool ok = upb_handlers_getselector(f, type, &selector); UPB_ASSERT_VAR(ok, ok); return selector; } @@ -165,11 +169,11 @@ void freeplan(void *_p) { free(p); } -static decoderplan *getdecoderplan(const upb_handlers *h) { +static const decoderplan *getdecoderplan(const upb_handlers *h) { if (upb_handlers_frametype(h) != upb_pbdecoder_getframetype()) return NULL; upb_selector_t sel; - if (!upb_getselector(UPB_BYTESTREAM_BYTES, UPB_HANDLER_STRING, &sel)) + if (!upb_handlers_getselector(UPB_BYTESTREAM_BYTES, UPB_HANDLER_STRING, &sel)) return NULL; return upb_handlers_gethandlerdata(h, sel); } @@ -180,7 +184,7 @@ bool upb_pbdecoder_isdecoder(const upb_handlers *h) { bool upb_pbdecoder_hasjitcode(const upb_handlers *h) { #ifdef UPB_USE_JIT_X64 - decoderplan *p = getdecoderplan(h); + const decoderplan *p = getdecoderplan(h); if (!p) return false; return p->jit_code != NULL; #else @@ -190,7 +194,7 @@ bool upb_pbdecoder_hasjitcode(const upb_handlers *h) { } const upb_handlers *upb_pbdecoder_getdesthandlers(const upb_handlers *h) { - decoderplan *p = getdecoderplan(h); + const decoderplan *p = getdecoderplan(h); if (!p) return NULL; return p->dest_handlers; } @@ -290,7 +294,6 @@ static void suspendjmp(upb_pbdecoder *d) { } static void advancetobuf(upb_pbdecoder *d, const char *buf, size_t len) { - assert(len >= 0); assert(d->ptr == d->end); d->bufstart_ofs += (d->ptr - d->buf); switchtobuf(d, buf, buf + len); @@ -583,7 +586,7 @@ static const upb_fielddef *decode_tag(upb_pbdecoder *d) { uint32_t tag = decode_v32(d); uint8_t wire_type = tag & 0x7; uint32_t fieldnum = tag >> 3; const upb_fielddef *f = NULL; - const upb_handlers *h = upb_sinkframe_handlers(upb_sink_top(d->sink)); + const upb_handlers *h = d->sink->top->h; // TODO(haberman): rm f = upb_msgdef_itof(upb_handlers_msgdef(h), fieldnum); bool packed = false; @@ -646,17 +649,19 @@ static const upb_fielddef *decode_tag(upb_pbdecoder *d) { } } -void *start(const upb_sinkframe *fr, size_t size_hint) { +void *start(void *closure, const void *handler_data, size_t size_hint) { + UPB_UNUSED(handler_data); UPB_UNUSED(size_hint); - upb_pbdecoder *d = upb_sinkframe_userdata(fr); + upb_pbdecoder *d = closure; assert(d); assert(d->sink); upb_sink_startmsg(d->sink); return d; } -bool end(const upb_sinkframe *fr) { - upb_pbdecoder *d = upb_sinkframe_userdata(fr); +bool end(void *closure, const void *handler_data) { + UPB_UNUSED(handler_data); + upb_pbdecoder *d = closure; if (d->residual_end > d->residual) { // We have preserved bytes. @@ -668,7 +673,6 @@ bool end(const upb_sinkframe *fr) { if (d->top == d->stack + 1 && d->top->is_sequence && !d->top->is_packed) { - assert(upb_sinkframe_depth(upb_sink_top(d->sink)) == 1); pop_seq(d); } if (d->top != d->stack) { @@ -680,47 +684,47 @@ bool end(const upb_sinkframe *fr) { return true; } -size_t decode(const upb_sinkframe *fr, const char *buf, size_t size) { - upb_pbdecoder *d = upb_sinkframe_userdata(fr); - decoderplan *plan = upb_sinkframe_handlerdata(fr); +size_t decode(void *closure, const void *hd, const char *buf, size_t size) { + upb_pbdecoder *d = closure; + const decoderplan *plan = hd; UPB_UNUSED(plan); - assert(upb_sinkframe_handlers(upb_sink_top(d->sink)) == plan->dest_handlers); + assert(d->sink->top->h == plan->dest_handlers); if (size == 0) return 0; // Assume we'll consume the whole buffer unless this is overwritten. d->ret = size; + d->buf_param = buf; + d->size_param = size; if (_setjmp(d->exitjmp)) { // Hit end-of-buffer or error. return d->ret; } - d->buf_param = buf; - d->size_param = size; if (d->residual_end > d->residual) { // We have residual bytes from the last buffer. - d->userbuf_remaining = size; + d->userbuf_remaining = d->size_param; } else { d->userbuf_remaining = 0; - advancetobuf(d, buf, size); + advancetobuf(d, buf, d->size_param); if (d->top != d->stack && upb_fielddef_isstring(d->top->f) && !d->top->is_sequence) { // Last buffer ended in the middle of a string; deliver more of it. size_t len = d->top->end_ofs - offset(d); - if (size >= len) { + if (d->size_param >= len) { upb_sink_putstring(d->sink, getselector(d->top->f, UPB_HANDLER_STRING), d->ptr, len); advance(d, len); pop_string(d); } else { upb_sink_putstring(d->sink, getselector(d->top->f, UPB_HANDLER_STRING), - d->ptr, size); - advance(d, size); + d->ptr, d->size_param); + advance(d, d->size_param); d->residual_end = d->residual; advancetobuf(d, d->residual, 0); - return size; + return d->size_param; } } } @@ -762,7 +766,8 @@ size_t decode(const upb_sinkframe *fr, const char *buf, size_t size) { } } -void init(void *_d) { +void init(void *_d, upb_pipeline *p) { + UPB_UNUSED(p); upb_pbdecoder *d = _d; d->limit = &d->stack[UPB_MAX_NESTING]; d->sink = NULL; diff --git a/upb/pb/decoder.h b/upb/pb/decoder.h index 4307434..c1b6cb3 100644 --- a/upb/pb/decoder.h +++ b/upb/pb/decoder.h @@ -70,10 +70,6 @@ const upb_handlers *upb_pbdecoder_getdesthandlers(const upb_handlers *h); namespace upb { -template<> inline const FrameType* GetFrameType<upb::pb::Decoder>() { - return upb_pbdecoder_getframetype(); -} - namespace pb { inline bool ResetDecoderSink(Decoder* r, Sink* sink) { return upb_pbdecoder_resetsink(r, sink); diff --git a/upb/pb/decoder_x64.dasc b/upb/pb/decoder_x64.dasc index 7d4c537..154fee3 100644 --- a/upb/pb/decoder_x64.dasc +++ b/upb/pb/decoder_x64.dasc @@ -12,9 +12,11 @@ |// function) we must respect alignment rules. All x86-64 systems require |// 16-byte stack alignment. +#define _GNU_SOURCE #include <stdio.h> #include <sys/mman.h> #include "dynasm/dasm_x86.h" +#include "upb/shim/shim.h" #ifndef MAP_ANONYMOUS # define MAP_ANONYMOUS MAP_ANON @@ -61,7 +63,7 @@ static uint32_t upb_getpclabel(decoderplan *plan, const void *obj, int n) { return upb_value_getuint32(v) + n; } -static upb_jitmsginfo *upb_getmsginfo(decoderplan *plan, +static upb_jitmsginfo *upb_getmsginfo(const decoderplan *plan, const upb_handlers *h) { upb_value v; bool found = upb_inttable_lookupptr(&plan->msginfo, h, &v); @@ -161,6 +163,7 @@ static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; } |.define ARG2_64, rsi |.define ARG3_32, edx |.define ARG3_64, rdx +|.define ARG4_32, ecx |.define ARG4_64, rcx |.define XMMARG1, xmm0 @@ -193,13 +196,11 @@ static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; } ||{ || uintptr_t data = (uintptr_t)gethandlerdata(h, f, type); || if (data > 0xffffffff) { -| mov64 rax, data -| mov SINKFRAME->u.handler_data, rax -|| } else if (data > 0x7fffffff) { -| mov eax, data -| mov SINKFRAME->u.handler_data, rax +| mov64 ARG2_64, data +|| } else if (data) { +| mov ARG2_32, data || } else { -| mov qword SINKFRAME->u.handler_data, data +| xor ARG2_32, ARG2_32 || } || } |.endmacro @@ -269,6 +270,8 @@ static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; } |// table on the raw (length-masked) varint to save 3-4 cycles of latency. |// Currently only support tables where all entries are in the array part. |.macro dyndispatch_, h +|| asmlabel(plan, "_UPB_MCODE_DISPATCH_%s.%d", +|| upb_msgdef_fullname(upb_handlers_msgdef(h)), rand()); |=>upb_getpclabel(plan, h, DYNDISPATCH): | decode_loaded_varint, 0 | mov ecx, esi @@ -310,22 +313,21 @@ static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; } | |.macro pushsinkframe, handlers, field, endtype | mov rax, DECODER->sink -| mov dword SINKFRAME->u.selector, getselector(field, endtype) +| mov dword SINKFRAME->selector, getselector(field, endtype) | lea rcx, [SINKFRAME + sizeof(upb_sinkframe)] // rcx for short addressing | cmp rcx, SINK:rax->limit | jae ->exit_jit // Frame stack overflow. | mov64 r9, (uintptr_t)handlers | mov SINKFRAME:rcx->h, r9 | mov SINKFRAME:rcx->closure, CLOSURE -| mov SINK:rax->top_, rcx -| mov SINKFRAME:rcx->sink_, rax +| mov SINK:rax->top, rcx | mov SINKFRAME, rcx |.endmacro | |.macro popsinkframe | sub SINKFRAME, sizeof(upb_sinkframe) | mov rax, DECODER->sink -| mov SINK:rax->top_, SINKFRAME +| mov SINK:rax->top, SINKFRAME | mov CLOSURE, SINKFRAME->closure |.endmacro | @@ -415,12 +417,28 @@ static uintptr_t gethandlerdata(const upb_handlers *h, const upb_fielddef *f, return (uintptr_t)upb_handlers_gethandlerdata(h, getselector(f, type)); } +static void asmlabel(decoderplan *plan, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + char *str = NULL; + size_t size = 0; + upb_vrprintf(&str, &size, 0, fmt, ap); + va_end(ap); + uint32_t label = plan->pclabel_count++; + dasm_growpc(plan, plan->pclabel_count); + |=>label: + upb_inttable_insert(&plan->asmlabels, label, upb_value_ptr(str)); +} + // Decodes the next val into ARG2, advances PTR. static void upb_decoderplan_jit_decodefield(decoderplan *plan, size_t tag_size, const upb_handlers *h, const upb_fielddef *f) { // Decode the value into arg 3 for the callback. + asmlabel(plan, "UPB_MCODE_DECODE_FIELD_%s.%s", + upb_msgdef_fullname(upb_handlers_msgdef(h)), + upb_fielddef_name(f)); switch (upb_fielddef_descriptortype(f)) { case UPB_DESCRIPTOR_TYPE_DOUBLE: | movsd XMMARG1, qword [PTR + tag_size] @@ -496,39 +514,36 @@ static void upb_decoderplan_jit_decodefield(decoderplan *plan, upb_func *handler = gethandler(h, f, UPB_HANDLER_STARTSTR); if (handler) { + // void* startstr(void *c, const void *hd, size_t hint) | mov DECODER->tmp_len, ARG2_32 - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE + | mov ARG3_64, ARG2_64 | load_handler_data h, f, UPB_HANDLER_STARTSTR | callp handler | check_ptr_ret - | mov CLOSURE, rax - | mov ARG3_32, DECODER->tmp_len + | mov ARG1_64, rax // sub-closure + | mov ARG4_32, DECODER->tmp_len } else { - | mov ARG3_64, ARG2_64 + | mov ARG1_64, CLOSURE + | mov ARG4_64, ARG2_64 } handler = gethandler(h, f, UPB_HANDLER_STRING); if (handler) { - // TODO: push a real frame so we can resume into the string. - // (but maybe do this only if the string breaks). - | pushsinkframe h, f, UPB_HANDLER_ENDSTR - - // size_t str(const upb_sinkframe *frame, const char *buf, size_t len) - | mov ARG1_64, SINKFRAME + // size_t str(void *c, const void *hd, const char *buf, size_t len) | load_handler_data h, f, UPB_HANDLER_STRING - | mov ARG2_64, PTR + | mov ARG3_64, PTR | callp handler // TODO: properly handle returns other than "n" (the whole string). | add PTR, rax - | popsinkframe } else { - | add PTR, ARG3_64 + | add PTR, ARG4_64 } handler = gethandler(h, f, UPB_HANDLER_ENDSTR); if (handler) { // bool endstr(const upb_sinkframe *frame); - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE | load_handler_data h, f, UPB_HANDLER_ENDSTR | callp handler | check_bool_ret @@ -553,13 +568,16 @@ static void upb_decoderplan_jit_callcb(decoderplan *plan, const upb_fielddef *f) { // Call callbacks. Specializing the append accessors didn't yield a speed // increase in benchmarks. + asmlabel(plan, "UPB_MCODE_CALLCB_%s.%s", + upb_msgdef_fullname(upb_handlers_msgdef(h)), + upb_fielddef_name(f)); if (upb_fielddef_issubmsg(f)) { // Call startsubmsg handler (if any). upb_func *startsubmsg = gethandler(h, f, UPB_HANDLER_STARTSUBMSG); if (startsubmsg) { // upb_sflow_t startsubmsg(const upb_sinkframe *frame) | mov DECODER->tmp_len, ARG2_32 - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE | load_handler_data h, f, UPB_HANDLER_STARTSUBMSG | callp startsubmsg | check_ptr_ret @@ -594,37 +612,46 @@ static void upb_decoderplan_jit_callcb(decoderplan *plan, upb_func *endsubmsg = gethandler(h, f, UPB_HANDLER_ENDSUBMSG); if (endsubmsg) { // upb_flow_t endsubmsg(void *closure, upb_value fval); - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE | load_handler_data h, f, UPB_HANDLER_ENDSUBMSG | callp endsubmsg | check_bool_ret } } else if (!upb_fielddef_isstring(f)) { upb_handlertype_t handlertype = upb_handlers_getprimitivehandlertype(f); + upb_selector_t sel = getselector(f, handlertype); upb_func *handler = gethandler(h, f, handlertype); - const upb_stdmsg_fval *fv = (void*)gethandlerdata(h, f, handlertype); - // Test for callbacks we can specialize. - // Can't switch() on function pointers. - if (handler == (void*)&upb_stdmsg_setint64 || - handler == (void*)&upb_stdmsg_setuint64) { - | mov [CLOSURE + fv->offset], ARG2_64 - | sethas CLOSURE, fv->hasbit - } else if (handler == (void*)&upb_stdmsg_setdouble) { - | movsd qword [CLOSURE + fv->offset], XMMARG1 - | sethas CLOSURE, fv->hasbit - } else if (handler == (void*)&upb_stdmsg_setint32 || - handler == (void*)&upb_stdmsg_setuint32) { - | mov [CLOSURE + fv->offset], ARG2_32 - | sethas CLOSURE, fv->hasbit - } else if (handler == (void*)&upb_stdmsg_setfloat) { - | movss dword [CLOSURE + fv->offset], XMMARG1 - | sethas CLOSURE, fv->hasbit - } else if (handler == (void*)&upb_stdmsg_setbool) { - | mov [CLOSURE + fv->offset], ARG2_8 - | sethas CLOSURE, fv->hasbit + const upb_shim_data *data = upb_shim_getdata(h, sel); + if (data) { + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT64: + case UPB_TYPE_UINT64: + | mov [CLOSURE + data->offset], ARG2_64 + break; + case UPB_TYPE_INT32: + case UPB_TYPE_UINT32: + case UPB_TYPE_ENUM: + | mov [CLOSURE + data->offset], ARG2_32 + break; + case UPB_TYPE_DOUBLE: + | movsd qword [CLOSURE + data->offset], XMMARG1 + break; + case UPB_TYPE_FLOAT: + | movss dword [CLOSURE + data->offset], XMMARG1 + break; + case UPB_TYPE_BOOL: + | mov [CLOSURE + data->offset], ARG2_8 + break; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + case UPB_TYPE_MESSAGE: + assert(false); break; + } + | sethas CLOSURE, data->hasbit } else if (handler) { // bool value(const upb_sinkframe* frame, ctype val) - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE + | mov ARG3_64, ARG2_64 | load_handler_data h, f, handlertype | callp handler | check_bool_ret @@ -647,7 +674,7 @@ static void upb_decoderplan_jit_endseq(decoderplan *plan, | popframe upb_func *endseq = gethandler(h, f, UPB_HANDLER_ENDSEQ); if (endseq) { - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE | load_handler_data h, f, UPB_HANDLER_ENDSEQ | callp endseq } @@ -658,6 +685,9 @@ static void upb_decoderplan_jit_field(decoderplan *plan, const upb_handlers *h, const upb_fielddef *f, const upb_fielddef *next_f) { + asmlabel(plan, "UPB_MCODE_FIELD_%s.%s", + upb_msgdef_fullname(upb_handlers_msgdef(h)), + upb_fielddef_name(f)); uint64_t tag = upb_get_encoded_tag(f); uint64_t next_tag = next_f ? upb_get_encoded_tag(next_f) : 0; int tag_size = upb_value_size(tag); @@ -672,7 +702,7 @@ static void upb_decoderplan_jit_field(decoderplan *plan, if (upb_fielddef_isseq(f)) { upb_func *startseq = gethandler(h, f, UPB_HANDLER_STARTSEQ); if (startseq) { - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE | load_handler_data h, f, UPB_HANDLER_STARTSEQ | callp startseq | check_ptr_ret @@ -726,6 +756,8 @@ static int upb_compare_uint32(const void *a, const void *b) { static void upb_decoderplan_jit_msg(decoderplan *plan, const upb_handlers *h) { + asmlabel(plan, "UPB_MCODE_DECODEMSG_%s", + upb_msgdef_fullname(upb_handlers_msgdef(h))); |=>upb_getpclabel(plan, h, AFTER_STARTMSG): | push rbp | mov rbp, rsp @@ -739,7 +771,7 @@ static void upb_decoderplan_jit_msg(decoderplan *plan, upb_startmsg_handler *startmsg = upb_handlers_getstartmsg(h); if (startmsg) { // upb_flow_t startmsg(void *closure); - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE | callp startmsg | check_bool_ret } @@ -792,7 +824,7 @@ static void upb_decoderplan_jit_msg(decoderplan *plan, upb_endmsg_handler *endmsg = upb_handlers_getendmsg(h); if (endmsg) { // void endmsg(void *closure, upb_status *status) { - | mov ARG1_64, SINKFRAME + | mov ARG1_64, CLOSURE | mov ARG2_64, DECODER->sink | mov ARG2_64, SINK:ARG2_64->pipeline_ | add ARG2_64, offsetof(upb_pipeline, status_) @@ -815,6 +847,7 @@ static void upb_decoderplan_jit(decoderplan *plan) { // calculate the structure offsets ourself instead of symbolically // (ie. [r15 + 0xcd] instead of DECODER->ptr). So we tolerate a bit of // unnecessary duplication/redundancy. + asmlabel(plan, "upb_jit_trampoline"); | push rbp | mov rbp, rsp | push r15 @@ -828,13 +861,14 @@ static void upb_decoderplan_jit(decoderplan *plan) { | mov DECODER->saved_rbp, rbp | mov FRAME, DECODER:ARG1_64->top | mov rax, DECODER:ARG1_64->sink - | mov SINKFRAME, SINK:rax->top_ + | mov SINKFRAME, SINK:rax->top | mov CLOSURE, SINKFRAME->closure | mov PTR, DECODER->ptr // TODO: push return addresses for re-entry (will be necessary for multiple // buffer support). | call ARG2_64 + asmlabel(plan, "exitjit"); |->exit_jit: | mov rbp, DECODER->saved_rbp | lea rsp, [rbp - 48] @@ -903,6 +937,8 @@ static void upb_decoderplan_makejit(decoderplan *plan) { upb_inttable_init(&plan->pclabels, UPB_CTYPE_UINT32); upb_decoderplan_jit_assignpclabels(plan, plan->dest_handlers); + upb_inttable_init(&plan->asmlabels, UPB_CTYPE_PTR); + void **globals = malloc(UPB_JIT_GLOBAL__MAX * sizeof(*globals)); dasm_init(plan, 1); dasm_setupglobal(plan, globals, UPB_JIT_GLOBAL__MAX); @@ -947,18 +983,57 @@ static void upb_decoderplan_makejit(decoderplan *plan) { upb_inttable_uninit(&plan->pclabels); - dasm_free(plan); - free(globals); - mprotect(plan->jit_code, plan->jit_size, PROT_EXEC | PROT_READ); #ifndef NDEBUG - // View with: objdump -M intel -D -b binary -mi386 -Mx86-64 /tmp/machine-code - // Or: ndisasm -b 64 /tmp/machine-code - FILE *f = fopen("/tmp/machine-code", "wb"); - fwrite(plan->jit_code, plan->jit_size, 1, f); - fclose(f); + // Dump to a .o file in /tmp, for easy inspection. + + // Convert all asm labels from pclabel offsets to machine code offsets. + upb_inttable mclabels; + upb_inttable_init(&mclabels, UPB_CTYPE_PTR); + upb_inttable_begin(&i, &plan->asmlabels); + for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { + upb_inttable_insert( + &mclabels, + dasm_getpclabel(plan, upb_inttable_iter_key(&i)), + upb_inttable_iter_value(&i)); + } + + FILE *f = fopen("/tmp/upb-jit-code.s", "w"); + if (f) { + fputs(" .text", f); + size_t linelen = 0; + for (size_t i = 0; i < plan->jit_size; i++) { + upb_value v; + if (upb_inttable_lookup(&mclabels, i, &v)) { + const char *label = upb_value_getptr(v); + fprintf(f, "\n\n_%s:\n", label); + fprintf(f, " .globl _%s", label); + linelen = 1000; + } + if (linelen >= 77) { + linelen = fprintf(f, "\n .byte %u", plan->jit_code[i]); + } else { + linelen += fprintf(f, ",%u", plan->jit_code[i]); + } + } + fputs("\n", f); + fclose(f); + } else { + fprintf(stderr, "Couldn't open /tmp/upb-jit-code.s for writing/\n"); + } + + upb_inttable_uninit(&mclabels); #endif + + upb_inttable_begin(&i, &plan->asmlabels); + for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { + free(upb_value_getptr(upb_inttable_iter_value(&i))); + } + upb_inttable_uninit(&plan->asmlabels); + + dasm_free(plan); + free(globals); } static void upb_decoderplan_freejit(decoderplan *plan) { @@ -975,10 +1050,10 @@ static void upb_decoderplan_freejit(decoderplan *plan) { // TODO: unregister } -static void upb_decoder_enterjit(upb_pbdecoder *d, decoderplan *plan) { +static void upb_decoder_enterjit(upb_pbdecoder *d, const decoderplan *plan) { if (plan->jit_code && d->top == d->stack && - d->sink->top_ == d->sink->stack && + d->sink->top == d->sink->stack && d->ptr && d->ptr < d->jit_end) { #ifndef NDEBUG register uint64_t rbx asm ("rbx") = 11; diff --git a/upb/pb/glue.c b/upb/pb/glue.c index bcde039..2c621f4 100644 --- a/upb/pb/glue.c +++ b/upb/pb/glue.c @@ -30,7 +30,7 @@ upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n, // Create sinks. upb_sink *reader_sink = upb_pipeline_newsink(&pipeline, reader_h); upb_sink *decoder_sink = upb_pipeline_newsink(&pipeline, decoder_h); - upb_pbdecoder *d = upb_sinkframe_userdata(upb_sink_base(decoder_sink)); + upb_pbdecoder *d = upb_sink_getobj(decoder_sink); upb_pbdecoder_resetsink(d, reader_sink); // Push input data. @@ -42,7 +42,7 @@ upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n, return NULL; } - upb_descreader *r = upb_sinkframe_userdata(upb_sink_base(reader_sink)); + upb_descreader *r = upb_sink_getobj(reader_sink); upb_def **defs = upb_descreader_getdefs(r, owner, n); upb_def **defscopy = malloc(sizeof(upb_def*) * (*n)); memcpy(defscopy, defs, sizeof(upb_def*) * (*n)); diff --git a/upb/pb/textprinter.c b/upb/pb/textprinter.c index 91c1e2d..08eda15 100644 --- a/upb/pb/textprinter.c +++ b/upb/pb/textprinter.c @@ -38,8 +38,7 @@ static int endfield(upb_textprinter *p) { return 0; } -static int putescaped(upb_textprinter *p, const char *buf, size_t len, - bool preserve_utf8) { +static int putescaped(const char* buf, size_t len, bool preserve_utf8) { // Based on CEscapeInternal() from Google's protobuf release. char dstbuf[4096], *dst = dstbuf, *dstend = dstbuf + sizeof(dstbuf); const char *end = buf + len; @@ -84,9 +83,9 @@ static int putescaped(upb_textprinter *p, const char *buf, size_t len, } #define TYPE(name, ctype, fmt) \ - static bool put ## name(const upb_sinkframe *frame, ctype val) { \ - upb_textprinter *p = upb_sinkframe_userdata(frame); \ - const upb_fielddef *f = upb_sinkframe_handlerdata(frame); \ + static bool put ## name(void *closure, const void *handler_data, ctype val) {\ + upb_textprinter *p = closure; \ + const upb_fielddef *f = handler_data; \ CHECK(indent(p)); \ puts(upb_fielddef_name(f)); \ puts(": "); \ @@ -97,9 +96,9 @@ static int putescaped(upb_textprinter *p, const char *buf, size_t len, return false; \ } -static bool putbool(const upb_sinkframe *frame, bool val) { - upb_textprinter *p = upb_sinkframe_userdata(frame); - const upb_fielddef *f = upb_sinkframe_handlerdata(frame); +static bool putbool(void *closure, const void *handler_data, bool val) { + upb_textprinter *p = closure; + const upb_fielddef *f = handler_data; CHECK(indent(p)); puts(upb_fielddef_name(f)); puts(": "); @@ -121,44 +120,49 @@ TYPE(float, float, "%." STRINGIFY_MACROVAL(FLT_DIG) "g") TYPE(double, double, "%." STRINGIFY_MACROVAL(DBL_DIG) "g") // Output a symbolic value from the enum if found, else just print as int32. -static bool putenum(const upb_sinkframe *frame, int32_t val) { - const upb_fielddef *f = upb_sinkframe_handlerdata(frame); +static bool putenum(void *closure, const void *handler_data, int32_t val) { + const upb_fielddef *f = handler_data; const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f)); const char *label = upb_enumdef_iton(enum_def, val); if (label) { puts(label); } else { - CHECK(putint32(frame, val)); + CHECK(putint32(closure, handler_data, val)); } return true; err: return false; } -static void *startstr(const upb_sinkframe *frame, size_t size_hint) { +static void *startstr(void *closure, const void *handler_data, + size_t size_hint) { + UPB_UNUSED(handler_data); UPB_UNUSED(size_hint); - upb_textprinter *p = upb_sinkframe_userdata(frame); + upb_textprinter *p = closure; putchar('"'); return p; } -static bool endstr(const upb_sinkframe *frame) { +static bool endstr(void *closure, const void *handler_data) { + UPB_UNUSED(closure); + UPB_UNUSED(handler_data); putchar('"'); return true; } -static size_t putstr(const upb_sinkframe *frame, const char *buf, size_t len) { - upb_textprinter *p = upb_sinkframe_userdata(frame); - const upb_fielddef *f = upb_sinkframe_handlerdata(frame); - CHECK(putescaped(p, buf, len, upb_fielddef_type(f) == UPB_TYPE_STRING)); +static size_t putstr(void *closure, const void *hd, const char *buf, + size_t len) { + UPB_UNUSED(closure); + const upb_fielddef *f = hd; + CHECK(putescaped(buf, len, upb_fielddef_type(f) == UPB_TYPE_STRING)); return len; err: return 0; } -static void *startsubmsg(const upb_sinkframe *frame) { - upb_textprinter *p = upb_sinkframe_userdata(frame); - const upb_fielddef *f = upb_sinkframe_handlerdata(frame); +static void *startsubmsg(void *closure, const void *handler_data) { + upb_textprinter *p = closure; + const upb_fielddef *f = handler_data; CHECK(indent(p)); printf("%s {", upb_fielddef_name(f)); if (!p->single_line) @@ -169,8 +173,9 @@ err: return UPB_BREAK; } -static bool endsubmsg(const upb_sinkframe *frame) { - upb_textprinter *p = upb_sinkframe_userdata(frame); +static bool endsubmsg(void *closure, const void *handler_data) { + UPB_UNUSED(handler_data); + upb_textprinter *p = closure; p->indent_depth--; CHECK(indent(p)); putchar('}'); |