summaryrefslogtreecommitdiff
path: root/src/upb_decoder_x86.dasc
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2011-05-20 11:26:27 -0700
committerJoshua Haberman <joshua@reverberate.org>2011-05-20 11:26:27 -0700
commit0941664215ed7fa4a8d53b6387d50c56df6757d0 (patch)
tree9125c22f6892015e05fa709426a6cc8b082972ad /src/upb_decoder_x86.dasc
parent74102e836d285bcfcb4c22cbe72a3a36828d30cb (diff)
Add startseq/endseq handlers.
Startseq/endseq handlers are called at the beginning and end of a sequence of repeated values. Protobuf does not really have direct support for this (repeated primitive fields do not delimit "begin" and "end" of the sequence) but we can infer them from the bytestream. The benefit of supporting them explicitly is that they get their own stack frame and closure, so we can avoid having to find the array's address over and over and deciding if we need to initialize it. This will also pave the way for better support of JSON, which does have explicit "startseq/endseq" markers: [].
Diffstat (limited to 'src/upb_decoder_x86.dasc')
-rw-r--r--src/upb_decoder_x86.dasc24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/upb_decoder_x86.dasc b/src/upb_decoder_x86.dasc
index b7195c2..1780c98 100644
--- a/src/upb_decoder_x86.dasc
+++ b/src/upb_decoder_x86.dasc
@@ -285,6 +285,18 @@ static void upb_decoder_jit_field(upb_decoder *d, uint32_t tag, uint32_t next_ta
| cmp edx, (tag & 0x7)
| jne ->exit_jit // In the future: could be an unknown field or packed.
|=>f->jit_pclabel_notypecheck:
+ if (f->repeated) {
+ if (f->startseq != upb_startfield_nop) {
+ | mov ARG1_64, CLOSURE
+ | loadfval f
+ | callp f->startseq
+ } else {
+ | mov rdx, CLOSURE
+ }
+ | mov esi, FRAME->end_offset
+ | pushframe f, rdx, esi, true
+ }
+
|1: // Label for repeating this field.
// Decode the value into arg 3 for the callback.
@@ -382,7 +394,7 @@ static void upb_decoder_jit_field(upb_decoder *d, uint32_t tag, uint32_t next_ta
// Call callbacks.
if (upb_issubmsgtype(f->type)) {
// Call startsubmsg handler (if any).
- if (f->startsubmsg != upb_startsubmsg_nop) {
+ if (f->startsubmsg != upb_startfield_nop) {
// upb_sflow_t startsubmsg(void *closure, upb_value fval)
| mov r12d, ARG3_32
| callp f->startsubmsg
@@ -396,7 +408,7 @@ static void upb_decoder_jit_field(upb_decoder *d, uint32_t tag, uint32_t next_ta
| add esi, r12d // = (d->ptr - d->buf) + delim_len
} else {
assert(f->type == UPB_TYPE(GROUP));
- | mov esi, -1U
+ | mov esi, UPB_NONDELIMITED
}
| pushframe f, rdx, esi, false
@@ -411,7 +423,7 @@ static void upb_decoder_jit_field(upb_decoder *d, uint32_t tag, uint32_t next_ta
| popframe
// Call endsubmsg handler (if any).
- if (f->endsubmsg != upb_endsubmsg_nop) {
+ if (f->endsubmsg != upb_endfield_nop) {
// upb_flow_t endsubmsg(void *closure, upb_value fval);
| mov ARG1_64, CLOSURE
| loadfval f
@@ -428,6 +440,12 @@ static void upb_decoder_jit_field(upb_decoder *d, uint32_t tag, uint32_t next_ta
if (f->repeated) {
| checktag tag
| je <1
+ | popframe
+ if (f->endseq != upb_endfield_nop) {
+ | mov ARG1_64, CLOSURE
+ | loadfval f
+ | callp f->endseq
+ }
}
if (next_tag != 0) {
| checktag next_tag
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback