From b2735330f95d8bf8b2e7ee10a218447a3b5f358b Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Thu, 22 May 2025 16:46:29 -0400 Subject: [PATCH] Add PRESERVE_NONE to continuations --- src/parser3.h | 68 +++++++++++++++++++++++---------------------- src/preserve_none.h | 11 ++++++++ 2 files changed, 46 insertions(+), 33 deletions(-) create mode 100644 src/preserve_none.h diff --git a/src/parser3.h b/src/parser3.h index 664d162..aa06ab4 100644 --- a/src/parser3.h +++ b/src/parser3.h @@ -19,12 +19,13 @@ #endif #include "musttail.h" +#include "preserve_none.h" #include "tables.h" #include "weaseljson.h" namespace parser3 { -typedef WeaselJsonStatus (*Continuation)(struct Parser3 *); +typedef PRESERVE_NONE WeaselJsonStatus (*Continuation)(struct Parser3 *); // These appear in the stack of the pushdown // automata @@ -119,7 +120,7 @@ struct Parser3 { return *(stackPtr - 1); } - static WeaselJsonStatus keepGoing(Parser3 *self); + static PRESERVE_NONE WeaselJsonStatus keepGoing(Parser3 *self); constexpr static int kMaxStackSize = 1024; @@ -142,7 +143,7 @@ struct Parser3 { uint32_t minCodepoint; }; -inline WeaselJsonStatus n_whitespace(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_whitespace(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -157,7 +158,7 @@ inline WeaselJsonStatus n_whitespace(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline WeaselJsonStatus n_value(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self) { assert(self->len() != 0); while (tables.whitespace[uint8_t(*self->buf)]) { ++self->buf; @@ -280,7 +281,7 @@ inline WeaselJsonStatus n_value(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline WeaselJsonStatus n_object2(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_object2(Parser3 *self) { assert(self->len() != 0); while (tables.whitespace[uint8_t(*self->buf)]) { ++self->buf; @@ -308,7 +309,7 @@ inline WeaselJsonStatus n_object2(Parser3 *self) { } } -inline WeaselJsonStatus n_object3(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_object3(Parser3 *self) { assert(self->len() != 0); while (tables.whitespace[uint8_t(*self->buf)]) { ++self->buf; @@ -334,7 +335,7 @@ inline WeaselJsonStatus n_object3(Parser3 *self) { } } -inline WeaselJsonStatus n_array2(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_array2(Parser3 *self) { assert(self->len() != 0); while (tables.whitespace[uint8_t(*self->buf)]) { ++self->buf; @@ -357,7 +358,7 @@ inline WeaselJsonStatus n_array2(Parser3 *self) { } } -inline WeaselJsonStatus n_array3(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_array3(Parser3 *self) { assert(self->len() != 0); while (tables.whitespace[uint8_t(*self->buf)]) { ++self->buf; @@ -383,7 +384,7 @@ inline WeaselJsonStatus n_array3(Parser3 *self) { } } -inline WeaselJsonStatus n_string(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_string(Parser3 *self) { assert(self->len() != 0); while (tables.whitespace[uint8_t(*self->buf)]) { ++self->buf; @@ -404,7 +405,7 @@ inline WeaselJsonStatus n_string(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline WeaselJsonStatus n_string2(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self) { const auto before = self->buf; // Advance self->buf to the first "non-normal" character @@ -531,7 +532,7 @@ inline WeaselJsonStatus n_string2(Parser3 *self) { } } -inline WeaselJsonStatus n_string_following_escape(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_string_following_escape(Parser3 *self) { switch (*self->buf) { case '"': case '\\': @@ -560,7 +561,7 @@ inline WeaselJsonStatus n_string_following_escape(Parser3 *self) { } } -inline WeaselJsonStatus t_utf8_continuation_byte(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus t_utf8_continuation_byte(Parser3 *self) { if (tables.stringByteMeaning[uint8_t(*self->buf)] != Tables::CONTINUATION_BYTE) [[unlikely]] { return WeaselJson_REJECT; @@ -572,7 +573,8 @@ inline WeaselJsonStatus t_utf8_continuation_byte(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline WeaselJsonStatus t_utf8_last_continuation_byte(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus +t_utf8_last_continuation_byte(Parser3 *self) { if (tables.stringByteMeaning[uint8_t(*self->buf)] != Tables::CONTINUATION_BYTE) [[unlikely]] { return WeaselJson_REJECT; @@ -591,7 +593,7 @@ inline WeaselJsonStatus t_utf8_last_continuation_byte(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline WeaselJsonStatus t_digit(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus t_digit(Parser3 *self) { if ('0' <= *self->buf && *self->buf <= '9') { ++self->buf; self->pop(); @@ -601,7 +603,7 @@ inline WeaselJsonStatus t_digit(Parser3 *self) { } } -inline WeaselJsonStatus t_onenine(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus t_onenine(Parser3 *self) { if ('1' <= *self->buf && *self->buf <= '9') { ++self->buf; self->pop(); @@ -611,7 +613,7 @@ inline WeaselJsonStatus t_onenine(Parser3 *self) { } } -inline WeaselJsonStatus t_hex(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus t_hex(Parser3 *self) { self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -627,7 +629,7 @@ inline WeaselJsonStatus t_hex(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline WeaselJsonStatus t_hex2(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus t_hex2(Parser3 *self) { self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -694,7 +696,7 @@ inline WeaselJsonStatus t_hex2(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline WeaselJsonStatus t_hex3(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus t_hex3(Parser3 *self) { self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -745,7 +747,7 @@ inline WeaselJsonStatus t_hex3(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline WeaselJsonStatus n_integer(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_integer(Parser3 *self) { self->callbacks->on_begin_number(self->data); self->dataBegin = self->buf; switch (*self->buf) { @@ -780,7 +782,7 @@ inline WeaselJsonStatus n_integer(Parser3 *self) { } } -inline WeaselJsonStatus n_integer2(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_integer2(Parser3 *self) { switch (*self->buf) { case '0': ++self->buf; @@ -806,7 +808,7 @@ inline WeaselJsonStatus n_integer2(Parser3 *self) { } } -inline WeaselJsonStatus n_digits(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_digits(Parser3 *self) { switch (*self->buf) { case '0': case '1': @@ -829,7 +831,7 @@ inline WeaselJsonStatus n_digits(Parser3 *self) { } } -inline WeaselJsonStatus n_digits2(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_digits2(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -853,7 +855,7 @@ inline WeaselJsonStatus n_digits2(Parser3 *self) { } } -inline WeaselJsonStatus n_fraction(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_fraction(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -873,7 +875,7 @@ inline WeaselJsonStatus n_fraction(Parser3 *self) { } // Responsible for ensuring that on_end_number gets called -inline WeaselJsonStatus n_exponent(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_exponent(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -895,7 +897,7 @@ inline WeaselJsonStatus n_exponent(Parser3 *self) { } } -inline WeaselJsonStatus n_sign(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_sign(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -912,7 +914,7 @@ inline WeaselJsonStatus n_sign(Parser3 *self) { } } -inline WeaselJsonStatus n_true(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_true(Parser3 *self) { if (*self->buf == 'e') { ++self->buf; self->pop(); @@ -923,7 +925,7 @@ inline WeaselJsonStatus n_true(Parser3 *self) { } } -inline WeaselJsonStatus n_false(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_false(Parser3 *self) { if (*self->buf == 'e') { ++self->buf; self->pop(); @@ -934,7 +936,7 @@ inline WeaselJsonStatus n_false(Parser3 *self) { } } -inline WeaselJsonStatus n_null(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus n_null(Parser3 *self) { if (*self->buf == 'l') { ++self->buf; self->pop(); @@ -946,7 +948,7 @@ inline WeaselJsonStatus n_null(Parser3 *self) { } template -inline WeaselJsonStatus singleChar(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus singleChar(Parser3 *self) { if constexpr (kSkipWhitespace) { assert(self->len() != 0); while (tables.whitespace[uint8_t(*self->buf)]) { @@ -965,14 +967,14 @@ inline WeaselJsonStatus singleChar(Parser3 *self) { } } -inline WeaselJsonStatus t_eof(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus t_eof(Parser3 *self) { if (self->len() > 0) [[unlikely]] { return WeaselJson_REJECT; } return self->complete ? WeaselJson_OK : WeaselJson_AGAIN; } -inline WeaselJsonStatus t_end_number(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus t_end_number(Parser3 *self) { self->pop(); self->flushNumber(); self->callbacks->on_end_number(self->data); @@ -983,7 +985,7 @@ constexpr inline struct ContinuationTable { constexpr ContinuationTable() { // Defaults for (int i = 0; i < N_SYMBOL_COUNT; ++i) { - continuations[i] = +[](struct Parser3 *) { + continuations[i] = +[](struct Parser3 *) PRESERVE_NONE { printf("unimplemented\n"); return WeaselJson_REJECT; }; @@ -1074,7 +1076,7 @@ constexpr inline struct ContinuationTable { bool acceptsEmptyString[N_SYMBOL_COUNT]{}; } symbolTables; -inline WeaselJsonStatus Parser3::keepGoing(Parser3 *self) { +inline PRESERVE_NONE WeaselJsonStatus Parser3::keepGoing(Parser3 *self) { // self->debugPrint(); if (self->len() == 0) { if (!self->complete) { diff --git a/src/preserve_none.h b/src/preserve_none.h new file mode 100644 index 0000000..e10a500 --- /dev/null +++ b/src/preserve_none.h @@ -0,0 +1,11 @@ +#pragma once + +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif + +#if __has_attribute(preserve_none) +#define PRESERVE_NONE __attribute__((preserve_none)) +#else +#define PRESERVE_NONE +#endif