From 2f3daa55d193ff0d9f06340f766f82f06639dc99 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 6 Sep 2014 14:33:43 +0300 Subject: [PATCH] Optimize memory footprint of the bidi level stack. --- src/bidi.c | 18 +++++++++++++++--- src/dispextern.h | 9 ++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/bidi.c b/src/bidi.c index cb86b20b38e..6fe937671da 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -429,12 +429,12 @@ bidi_push_embedding_level (struct bidi_it *bidi_it, bidi_it->stack_idx++; eassert (bidi_it->stack_idx < BIDI_MAXDEPTH+2+1); st = &bidi_it->level_stack[bidi_it->stack_idx]; + eassert (level <= (1 << 7)); st->level = level; st->override = override; st->isolate_status = isolate_status; if (isolate_status) { - st->prev = bidi_it->prev; st->last_strong = bidi_it->last_strong; st->prev_for_neutral = bidi_it->prev_for_neutral; st->next_for_neutral = bidi_it->next_for_neutral; @@ -449,6 +449,8 @@ bidi_push_embedding_level (struct bidi_it *bidi_it, static int bidi_pop_embedding_level (struct bidi_it *bidi_it) { + int level; + /* UAX#9 says to ignore invalid PDFs (X7, last bullet) and PDIs (X6a, 2nd bullet). */ if (bidi_it->stack_idx > 0) @@ -460,7 +462,15 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it) st = bidi_it->level_stack[bidi_it->stack_idx]; if (isolate_status) { - bidi_it->prev = st.prev; + /* PREV is used in W1 for resolving WEAK_NSM. By the time + we get to an NSM, we must have gotten past at least one + character: the PDI that ends the isolate from which we + are popping here. So PREV will have been filled up by + the time we first use it. We initialize it here to + UNKNOWN_BT to be able to catch any blunders in this + logic. */ + bidi_it->prev.orig_type = bidi_it->prev.type_after_w1 + = bidi_it->prev.type = UNKNOWN_BT; bidi_it->last_strong = st.last_strong; bidi_it->prev_for_neutral = st.prev_for_neutral; bidi_it->next_for_neutral = st.next_for_neutral; @@ -469,7 +479,9 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it) } bidi_it->stack_idx--; } - return bidi_it->level_stack[bidi_it->stack_idx].level; + level = bidi_it->level_stack[bidi_it->stack_idx].level; + eassert (0 <= level && level <= BIDI_MAXDEPTH + 1); + return level; } /* Record in SAVED_INFO the information about the current character. */ diff --git a/src/dispextern.h b/src/dispextern.h index 3723d341a51..e0701f34a41 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1912,15 +1912,14 @@ struct bidi_saved_info { levels, override status, isolate status, and isolating sequence runs. */ struct bidi_stack { - char level; - bool isolate_status; - bidi_dir_t override; - struct bidi_saved_info prev; struct bidi_saved_info last_strong; struct bidi_saved_info next_for_neutral; struct bidi_saved_info prev_for_neutral; struct bidi_saved_info next_for_ws; - bidi_dir_t sos; + unsigned level : 7; + bool_bf isolate_status : 1; + unsigned override : 2; + unsigned sos : 2; }; /* Data type for storing information about a string being iterated on. */ -- 2.39.5