[repacker] add 'virtual links' to the serializer.
These aren't associated with an offset field, but instead exist solely to add an ordering constraint to the object graph.
This commit is contained in:
parent
59d8f6c817
commit
7615b94ecf
|
@ -828,8 +828,9 @@ struct graph_t
|
|||
if (visited[link.objidx]) continue;
|
||||
|
||||
const auto& child = vertices_[link.objidx].obj;
|
||||
unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
|
||||
int64_t child_weight = (child.tail - child.head) +
|
||||
((int64_t) 1 << (link.width * 8)) * (vertices_[link.objidx].space + 1);
|
||||
((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
|
||||
int64_t child_distance = next_distance + child_weight;
|
||||
|
||||
if (child_distance < vertices_[link.objidx].distance)
|
||||
|
@ -874,6 +875,10 @@ struct graph_t
|
|||
bool is_valid_offset (int64_t offset,
|
||||
const hb_serialize_context_t::object_t::link_t& link) const
|
||||
{
|
||||
if (unlikely (!link.width))
|
||||
// Virtual links can't overflow.
|
||||
return link.is_signed || offset >= 0;
|
||||
|
||||
if (link.is_signed)
|
||||
{
|
||||
if (link.width == 4)
|
||||
|
@ -966,6 +971,9 @@ struct graph_t
|
|||
{
|
||||
switch (link.width)
|
||||
{
|
||||
case 0:
|
||||
// Virtual links aren't serialized.
|
||||
return;
|
||||
case 4:
|
||||
if (link.is_signed)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,12 @@ enum hb_serialize_error_t {
|
|||
};
|
||||
HB_MARK_AS_FLAG_T (hb_serialize_error_t);
|
||||
|
||||
// This is a 0 byte wide offset, used to add virtual links to the serializer object graph.
|
||||
// It does not correspond to a real offset and exists soley to enforce an ordering constraint
|
||||
// in the graph's packed order.
|
||||
struct VirtualOffset {
|
||||
};
|
||||
|
||||
struct hb_serialize_context_t
|
||||
{
|
||||
typedef unsigned objidx_t;
|
||||
|
@ -376,11 +382,22 @@ struct hb_serialize_context_t
|
|||
err (HB_SERIALIZE_ERROR_OTHER);
|
||||
|
||||
link.width = sizeof (T);
|
||||
link.objidx = objidx;
|
||||
if (unlikely (!sizeof (T)))
|
||||
{
|
||||
// This link is not associated with an actual offset and exists merely to enforce
|
||||
// an ordering constraint.
|
||||
link.is_signed = 0;
|
||||
link.whence = 0;
|
||||
link.position = 0;
|
||||
link.bias = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
link.is_signed = std::is_signed<hb_unwrap_type (T)>::value;
|
||||
link.whence = (unsigned) whence;
|
||||
link.position = (const char *) &ofs - current->head;
|
||||
link.bias = bias;
|
||||
link.objidx = objidx;
|
||||
}
|
||||
|
||||
unsigned to_bias (const void *base) const
|
||||
|
@ -402,6 +419,8 @@ struct hb_serialize_context_t
|
|||
for (const object_t* parent : ++hb_iter (packed))
|
||||
for (const object_t::link_t &link : parent->links)
|
||||
{
|
||||
if (unlikely (!link.width)) continue; // Don't need to resolve virtual offsets
|
||||
|
||||
const object_t* child = packed[link.objidx];
|
||||
if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; }
|
||||
unsigned offset = 0;
|
||||
|
|
Loading…
Reference in New Issue