@@ -123,10 +123,18 @@ _hs_text_decode_latin1(uint16_t *dest, const uint8_t const *src,
123123 * state0 != UTF8_ACCEPT, UTF8_REJECT
124124 *
125125 */
126−uint8_t const *
127−_hs_text_decode_utf8_state(uint16_t *dest, size_t *destoff,
128− const uint8_t const *src, const uint8_t const *srcend,
129− uint32_t *codepoint0, uint32_t *state0)
126+
127+#if defined(__GNUC__) || defined(__clang__)
128+static inline uint8_t const *
129+_hs_text_decode_utf8_int(uint16_t *dest, size_t *destoff,
130+ const uint8_t const *src, const uint8_t const *srcend,
131+ uint32_t *codepoint0, uint32_t *state0)
132+ __attribute((always_inline));
133+#endif
134+static inline uint8_t const *
135+_hs_text_decode_utf8_int(uint16_t *dest, size_t *destoff,
136+ const uint8_t const *src, const uint8_t const *srcend,
137+ uint32_t *codepoint0, uint32_t *state0)
130138{
131139 uint16_t *d = dest + *destoff;
132140 const uint8_t const *s = src;
@@ -178,10 +186,6 @@ _hs_text_decode_utf8_state(uint16_t *dest, size_t *destoff,
178186 }
179187 }
180188
181− /* Invalid encoding, back up to the errant character */
182− if (state == UTF8_REJECT)
183− s -= 1;
184−
185189 *destoff = d - dest;
186190 *codepoint0 = codepoint;
187191 *state0 = state;
@@ -189,6 +193,19 @@ _hs_text_decode_utf8_state(uint16_t *dest, size_t *destoff,
189193 return s;
190194}
191195
196+uint8_t const *
197+_hs_text_decode_utf8_state(uint16_t *dest, size_t *destoff,
198+ const uint8_t const *src,
199+ const uint8_t const *srcend,
200+ uint32_t *codepoint0, uint32_t *state0)
201+{
202+ uint8_t const *ret = _hs_text_decode_utf8_int(dest, destoff, src, srcend,
203+ codepoint0, state0);
204+ if (*state0 == UTF8_REJECT)
205+ ret -=1;
206+ return ret;
207+}
208+
192209/*
193210 * Helper to decode buffer and discard final decoder state
194211 */
@@ -198,10 +215,10 @@ _hs_text_decode_utf8(uint16_t *dest, size_t *destoff,
198215{
199216 uint32_t codepoint;
200217 uint32_t state = UTF8_ACCEPT;
201− uint8_t const *ret = _hs_text_decode_utf8_state(dest, destoff, src, srcend,
202− &codepoint, &state);
203− /* Back up if we have an incomplete encoding */
204− if (state != UTF8_ACCEPT && state != UTF8_REJECT)
218+ uint8_t const *ret = _hs_text_decode_utf8_int(dest, destoff, src, srcend,
219+ &codepoint, &state);
220+ /* Back up if we have an incomplete or invalid encoding */
221+ if (state != UTF8_ACCEPT)
205222 ret -= 1;
206223 return ret;
207224}