add "add_link()" with bias arg

issue #2227
This commit is contained in:
blueshade7 2020-03-05 15:40:44 -08:00 committed by Ebrahim Byagowi
parent bdf372b24c
commit 4c3af7d406
2 changed files with 22 additions and 17 deletions

View File

@ -415,7 +415,7 @@ struct Dict : UnsizedByteStr
{
T &ofs = *(T *) (c->head + OpCode_Size (int_op));
if (unlikely (!serialize_int_op<T> (c, op, 0, int_op))) return false;
c->add_link (ofs, link, nullptr, whence);
c->add_link (ofs, link, whence);
return true;
}

View File

@ -278,8 +278,8 @@ struct hb_serialize_context_t
template <typename T>
void add_link (T &ofs, objidx_t objidx,
const void *base = nullptr,
whence_t whence = Head)
whence_t whence,
unsigned bias = 0)
{
static_assert (sizeof (T) == 2 || sizeof (T) == 4, "");
@ -293,23 +293,18 @@ struct hb_serialize_context_t
link.is_wide = sizeof (T) == 4;
link.is_signed = hb_is_signed (hb_unwrap_type (T));
link.whence = (unsigned)whence;
link.whence = (unsigned) whence;
link.position = (const char *) &ofs - current->head;
if (whence == Head)
{
if (base == nullptr)
link.bias = 0;
else
{
assert (current->head <= (const char *)base);
link.bias = (const char *) base - current->head;
}
}
else
link.bias = 0;
link.bias = bias;
link.objidx = objidx;
}
template <typename T>
void add_link (T &ofs, objidx_t objidx,
const void *base = nullptr,
whence_t whence = Head)
{ add_link (ofs, objidx, whence, to_bias (base)); }
void resolve_links ()
{
if (unlikely (in_error ())) return;
@ -324,12 +319,14 @@ struct hb_serialize_context_t
if (unlikely (!child)) { err_other_error(); return; }
unsigned offset;
switch ((whence_t)link.whence) {
case Head: offset = (child->head - parent->head) - link.bias; break;
case Head: offset = child->head - parent->head; break;
case Tail: offset = child->head - parent->tail; break;
case Absolute: offset = (head - start) + (child->head - tail); break;
default: assert (0);
}
assert (offset >= link.bias);
offset -= link.bias;
if (link.is_signed)
{
if (link.is_wide)
@ -492,6 +489,14 @@ struct hb_serialize_context_t
check_assign (off, offset);
}
unsigned to_bias (const void *base) const
{
if (!base) return 0;
assert (current);
assert (current->head <= (const char *) base);
return (const char *) base - current->head;
}
public: /* TODO Make private. */
char *start, *head, *tail, *end;
unsigned int debug_depth;