diff --git a/src/musttail.h b/src/musttail.h index 667e6d1..c33a912 100644 --- a/src/musttail.h +++ b/src/musttail.h @@ -6,6 +6,7 @@ #if __has_attribute(musttail) #define MUSTTAIL __attribute__((musttail)) +#define HAS_MUSTTAIL #else #define MUSTTAIL #endif diff --git a/src/parser3.h b/src/parser3.h index 6a233eb..d28b2a2 100644 --- a/src/parser3.h +++ b/src/parser3.h @@ -146,6 +146,10 @@ struct Parser3 { NumDfa numDfa; Utf8Dfa strDfa; bool inKey = false; + +#ifndef HAS_MUSTTAIL + char *stashBufForTrampoline; +#endif }; inline PRESERVE_NONE WeaselJsonStatus skipWhitespace(char *&buf, char *bufEnd) { @@ -1029,13 +1033,29 @@ constexpr inline struct ContinuationTable { inline WeaselJsonStatus Parser3::parse(char *buf, int len) { this->dataBegin = this->writeBuf = buf; + +#ifdef HAS_MUSTTAIL return symbolTables.continuations[top()](this, buf, buf + len); +#else + this->stashBufForTrampoline = buf; + WeaselJsonStatus result; + while ((result = symbolTables.continuations[top()]( + this, stashBufForTrampoline, buf + len)) == WeaselJsonStatus(-1)) + ; + return result; +#endif } inline PRESERVE_NONE WeaselJsonStatus Parser3::keepGoing(Parser3 *self, char *buf, char *bufEnd) { +#ifdef HAS_MUSTTAIL MUSTTAIL return symbolTables.continuations[self->top()](self, buf, bufEnd); +#else + self->stashBufForTrampoline = buf; + (void)bufEnd; + return WeaselJsonStatus(-1); +#endif } } // namespace parser3