[serialize] Start fleshing out object stack

This commit is contained in:
Behdad Esfahbod 2019-03-30 17:26:35 -07:00
parent 63c3565189
commit bed150bd2e
2 changed files with 72 additions and 28 deletions

View File

@ -39,6 +39,30 @@
struct hb_serialize_context_t struct hb_serialize_context_t
{ {
typedef unsigned objidx_t;
struct object_t
{
void fini () { links.fini (); }
struct link_t
{
bool wide: 1;
unsigned offset : 31;
objidx_t objidx;
};
hb_bytes_t bytes;
hb_vector_t<link_t> links;
};
struct snapshot_t
{
char *head, *tail;
};
snapshot_t snapshot () { snapshot_t s = {head, tail} ; return s; }
hb_serialize_context_t (void *start_, unsigned int size) hb_serialize_context_t (void *start_, unsigned int size)
{ {
this->start = (char *) start_; this->start = (char *) start_;
@ -56,7 +80,8 @@ struct hb_serialize_context_t
this->tail = this->end; this->tail = this->end;
this->debug_depth = 0; this->debug_depth = 0;
this->packed.resize (1); this->packed.resize (0);
this->packed.push ()->bytes.arrayZ = this->end;
this->current.resize (0); this->current.resize (0);
} }
@ -81,18 +106,53 @@ struct hb_serialize_context_t
this->start, this->end, this->start, this->end,
(unsigned long) (this->end - this->start)); (unsigned long) (this->end - this->start));
return start_embed<Type> (); assert (!current.length);
return push<Type> ();
} }
void end_serialize () objidx_t end_serialize ()
{ {
DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1, DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
"end [%p..%p] serialized %d bytes; %s", "end [%p..%p] serialized %u bytes; %s",
this->start, this->end, this->start, this->end,
(int) (this->head - this->start), (unsigned) (this->head - this->start),
this->successful ? "successful" : "UNSUCCESSFUL"); this->successful ? "successful" : "UNSUCCESSFUL");
assert (current.length == 1);
return pop_pack ();
} }
unsigned int length () const { return this->head - this->start; } template <typename Type>
Type *push ()
{
current.push (snapshot ());
return start_embed<Type> ();
}
void pop_discard ()
{
revert (current.pop ());
}
objidx_t pop_pack ()
{
return 0;
}
void revert (snapshot_t snap)
{
assert (snap.head <= head);
assert (tail <= snap.tail);
head = snap.head;
tail = snap.tail;
discard_stale_objects ();
}
void discard_stale_objects ()
{
while (packed.length > 1 &&
packed.tail ().bytes.arrayZ < tail)
packed.pop ();
assert (packed.tail ().bytes.arrayZ == tail);
}
unsigned int length () const { return this->head - current.tail ().head; }
void align (unsigned int alignment) void align (unsigned int alignment)
{ {
@ -199,28 +259,9 @@ struct hb_serialize_context_t
private: private:
/* Stack of packed objects. Object 0 is always nil object. */ /* Stack of packed objects. Object 0 is always nil object. */
struct object_t
{
void fini () { links.fini (); }
struct link_t
{
bool wide: 1;
unsigned offset : 31;
unsigned objidx;
};
hb_bytes_t bytes;
hb_vector_t<link_t> links;
};
hb_vector_t<object_t> packed; hb_vector_t<object_t> packed;
/* Stack of currently under construction object locations. */ /* Stack of currently under construction object locations. */
struct snapshot_t
{
char *head, *tail;
};
snapshot_t snapshot () { snapshot_t s = {head, tail} ; return s; }
hb_vector_t<snapshot_t> current; hb_vector_t<snapshot_t> current;
}; };

View File

@ -87,6 +87,9 @@ struct hb_vector_t
return arrayZ()[i]; return arrayZ()[i];
} }
Type& tail () { return (*this)[length - 1]; }
const Type& tail () const { return (*this)[length - 1]; }
explicit operator bool () const { return length; } explicit operator bool () const { return length; }
/* Sink interface. */ /* Sink interface. */
@ -188,10 +191,10 @@ struct hb_vector_t
return true; return true;
} }
void pop () Type pop ()
{ {
if (!length) return; if (!length) return Null(Type);
length--; return arrayZ()[--length];
} }
void remove (unsigned int i) void remove (unsigned int i)