0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 07:23:53 +01:00

ircd::spirit: Consolidate entry to spirit through wrapper templates.

ircd::spirit: More aggressive inlining of interface templates; symbol visibility
This commit is contained in:
Jason Volk 2020-06-10 05:29:07 -07:00
parent 99504180c0
commit b59337eb78
6 changed files with 165 additions and 130 deletions

View file

@ -55,26 +55,8 @@ __attribute__((visibility("default")))
IRCD_EXCEPTION(ircd::error, error);
IRCD_EXCEPTION(error, generator_error);
IRCD_EXCEPTION(generator_error, buffer_overrun);
// parse.cc
extern thread_local char rule_buffer[64];
extern thread_local struct generator_state *generator_state;
}}
namespace ircd
__attribute__((visibility("default")))
{
template<class parent_error,
class it = const char *,
class... args>
bool parse(args&&...);
template<bool truncation = false,
class gen,
class... attr>
bool generate(mutable_buffer &out, gen&&, attr&&...);
}
namespace ircd {
namespace spirit
__attribute__((visibility("hidden")))
@ -180,6 +162,41 @@ namespace ircd::spirit::local
using qi::_3;
}
namespace ircd {
namespace spirit
__attribute__((visibility("default")))
{
// parse.cc
extern thread_local char rule_buffer[64];
extern thread_local struct generator_state *generator_state;
}}
namespace ircd {
namespace spirit
__attribute__((visibility("internal")))
{
template<class gen,
class... attr>
bool parse(const char *&start, const char *const &stop, gen&&, attr&&...);
template<class parent_error,
size_t error_show_max = 48,
class gen,
class... attr>
bool parse(const char *&start, const char *const &stop, gen&&, attr&&...);
template<bool truncation = false,
class gen,
class... attr>
bool generate(mutable_buffer &out, gen&&, attr&&...);
}}
namespace ircd
{
using spirit::generate;
using spirit::parse;
}
namespace ircd {
namespace spirit
__attribute__((visibility("default")))
@ -245,7 +262,8 @@ ircd::spirit::expectation_failure<parent>::expectation_failure(const qi::expecta
}
{}
struct ircd::spirit::generator_state
struct [[gnu::visibility("hidden")]]
ircd::spirit::generator_state
{
/// Destination buffer (used like window_buffer).
mutable_buffer &out;
@ -269,25 +287,23 @@ struct ircd::spirit::generator_state
template<bool truncation,
class gen,
class... attr>
inline bool
ircd::generate(mutable_buffer &out,
gen&& g,
attr&&... a)
[[using gnu: flatten, always_inline, gnu_inline, artificial]]
extern inline bool
ircd::spirit::generate(mutable_buffer &out,
gen&& g,
attr&&... a)
{
using namespace ircd::spirit;
namespace spirit = ircd::spirit;
const auto max(size(out));
const auto start(data(out));
struct spirit::generator_state state
struct generator_state state
{
out
};
const scope_restore _state
{
spirit::generator_state, &state
generator_state, &state
};
sink_type sink
@ -317,7 +333,7 @@ ircd::generate(mutable_buffer &out,
std::distance(start, begin(out))
};
throw spirit::buffer_overrun
throw buffer_overrun
{
"Insufficient buffer of %s; required at least %s",
pretty(pbuf[0], iec(max)),
@ -331,17 +347,37 @@ ircd::generate(mutable_buffer &out,
}
template<class parent_error,
class it,
class... args>
inline bool
ircd::parse(args&&... a)
size_t error_show_max,
class gen,
class... attr>
[[using gnu: flatten, always_inline, gnu_inline, artificial]]
extern inline bool
ircd::spirit::parse(const char *&start,
const char *const &stop,
gen&& g,
attr&&... a)
try
{
return spirit::qi::parse(std::forward<args>(a)...);
return qi::parse(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
}
catch(const spirit::qi::expectation_failure<it> &e)
catch(const qi::expectation_failure<const char *> &e)
{
throw spirit::expectation_failure<parent_error>(e);
throw expectation_failure<parent_error>
{
e, start, error_show_max
};
}
template<class gen,
class... attr>
[[using gnu: flatten, always_inline, gnu_inline, artificial]]
extern inline bool
ircd::spirit::parse(const char *&start,
const char *const &stop,
gen&& g,
attr&&... a)
{
return qi::parse(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
}
template<size_t idx,

View file

@ -398,7 +398,7 @@ ircd::fmt::snprintf::argument(const arg &val)
fmt::spec spec;
auto &start(begin(this->fmt));
const auto stop(end(this->fmt));
if(qi::parse(start, stop, parser, spec))
if(ircd::parse<invalid_format>(start, stop, parser, spec))
handle_specifier(this->out, idx++, spec, val);
string_view fmt

View file

@ -218,9 +218,25 @@ struct ircd::http::parser
:grammar
{
static size_t content_length(const string_view &val);
template<class gen,
class... attr>
bool operator()(const char *&start, const char *const &stop, gen&&, attr&&...) const;
}
const ircd::http::parser;
template<class gen,
class... attr>
inline bool
ircd::http::parser::operator()(const char *&start,
const char *const &stop,
gen&& g,
attr&&... a)
const
{
return ircd::parse(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
}
namespace ircd { namespace http
__attribute__((visibility("default")))
{
@ -600,7 +616,7 @@ try
const char *start(line::begin());
const auto res
{
qi::parse(start, line::end(), grammar, this->size)
parser(start, line::end(), grammar, this->size)
};
assert(res == true);
@ -753,7 +769,7 @@ try
const char *start(line.data());
const char *const stop(line.data() + line.size());
qi::parse(start, stop, grammar, *this);
parser(start, stop, grammar, *this);
}
catch(const qi::expectation_failure<const char *> &e)
{
@ -769,7 +785,7 @@ ircd::http::line::response::response(const line &line)
const char *start(line.data());
const char *const stop(line.data() + line.size());
qi::parse(start, stop, grammar, *this);
parser(start, stop, grammar, *this);
}
ircd::http::line::request::request(const line &line)
@ -782,7 +798,7 @@ try
const char *start(line.data());
const char *const stop(line.data() + line.size());
qi::parse(start, stop, grammar, *this);
parser(start, stop, grammar, *this);
}
catch(const qi::expectation_failure<const char *> &e)
{
@ -825,7 +841,7 @@ ircd::http::line::line(parse::capstan &pc)
string_view ret;
pc([&ret](const char *&start, const char *const &stop)
{
if(!qi::parse(start, stop, grammar, ret))
if(!parser(start, stop, grammar, ret))
{
ret = {};
return false;
@ -996,7 +1012,7 @@ const
const string_view &s(*this);
const char *start(s.begin()), *const stop(s.end());
qi::parse(start, stop, grammar);
parser(start, stop, grammar);
return ret;
}
@ -1016,7 +1032,7 @@ ircd::http::parser::content_length(const string_view &str)
const char *start(str.data());
const bool parsed
{
qi::parse(start, start + str.size(), grammar, ret)
http::parser(start, start + str.size(), grammar, ret)
};
if(!parsed || ret >= 256_GiB)
@ -1235,7 +1251,11 @@ ircd::http::status(const string_view &str)
short ret;
const char *start(str.data());
const bool parsed(qi::parse(start, start + str.size(), grammar, ret));
const bool parsed
{
parser(start, start + str.size(), grammar, ret)
};
if(!parsed || ret < 0 || ret >= 1000)
throw ircd::error
{

View file

@ -16,8 +16,6 @@ namespace ircd::json
// Instantiations of the grammars
struct parser extern const parser;
struct printer extern const printer;
const size_t &error_show_max {48};
}
#pragma GCC visibility pop
@ -189,6 +187,14 @@ ircd::json::parser
,"value"
};
template<class gen,
class... attr>
bool operator()(const char *&start, const char *const &stop, gen&&, attr&&...) const;
template<class gen,
class... attr>
bool operator()(const char *const &start, const char *const &stop, gen&&, attr&&...) const;
parser()
:parser::base_type{rule<>{}} // required by spirit
{
@ -460,8 +466,8 @@ noexcept
template<class gen,
class... attr>
[[gnu::visibility("internal")]]
void
[[using gnu: always_inline, gnu_inline, artificial]]
extern inline void
ircd::json::printer::operator()(mutable_buffer &out,
gen&& g,
attr&&... a)
@ -475,8 +481,8 @@ const
}
template<class gen>
[[gnu::visibility("internal")]]
void
[[using gnu: always_inline, gnu_inline, artificial]]
extern inline void
ircd::json::printer::operator()(mutable_buffer &out,
gen&& g)
const
@ -491,8 +497,8 @@ const
template<class it_a,
class it_b,
class closure>
[[gnu::visibility("internal")]]
inline void
[[using gnu: always_inline, gnu_inline, artificial]]
extern inline void
ircd::json::printer::list_protocol(mutable_buffer &out,
it_a it,
const it_b &end,
@ -503,14 +509,40 @@ ircd::json::printer::list_protocol(mutable_buffer &out,
lambda(out, *it);
for(++it; it != end; ++it)
{
static const auto &printer(json::printer);
const auto &printer(json::printer);
printer(out, printer.value_sep);
lambda(out, *it);
}
}
}
[[gnu::visibility("internal")]]
template<class gen,
class... attr>
[[using gnu: always_inline, gnu_inline, artificial]]
extern inline bool
ircd::json::parser::operator()(const char *const &start_,
const char *const &stop,
gen&& g,
attr&&...a)
const
{
const char *start(start_);
return operator()(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
}
template<class gen,
class... attr>
[[using gnu: always_inline, gnu_inline, artificial]]
extern inline bool
ircd::json::parser::operator()(const char *&start,
const char *const &stop,
gen&& g,
attr&&...a)
const
{
return ircd::parse<parse_error>(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
}
void
ircd::json::parser::throws_exceeded()
{
@ -2407,7 +2439,7 @@ const
ircd::json::vector::const_iterator
ircd::json::vector::begin()
const try
const
{
const_iterator ret
{
@ -2415,16 +2447,9 @@ const try
};
string_view &state(ret.state);
qi::parse(ret.start, ret.stop, vector_begin_parse, state);
parser(ret.start, ret.stop, vector_begin_parse, state);
return ret;
}
catch(const qi::expectation_failure<const char *> &e)
{
throw expectation_failure<parse_error>
{
e, string_view::data(), error_show_max
};
}
//
// vector::const_iterator::const_iterator
@ -2432,20 +2457,12 @@ catch(const qi::expectation_failure<const char *> &e)
ircd::json::vector::const_iterator &
ircd::json::vector::const_iterator::operator++()
try
{
this->state = {};
string_view &state(this->state);
qi::parse(start, stop, vector_next_parse, state);
parser(start, stop, vector_next_parse, state);
return *this;
}
catch(const qi::expectation_failure<const char *> &e)
{
throw expectation_failure<parse_error>
{
e, start, error_show_max
};
}
///////////////////////////////////////////////////////////////////////////////
//
@ -2689,10 +2706,10 @@ const try
string_view::begin(), string_view::end()
};
qi::parse(ret.start, ret.stop, object_begin_parse, ret.state);
parser(ret.start, ret.stop, object_begin_parse, ret.state);
return ret;
}
catch(const qi::expectation_failure<const char *> &e)
catch(const expectation_failure<parse_error> &e)
{
const auto type
{
@ -2702,13 +2719,11 @@ catch(const qi::expectation_failure<const char *> &e)
if(type != type::OBJECT)
throw type_error
{
"Expected JSON type OBJECT, not %s.", reflect(type)
"Expected JSON type OBJECT, not %s.",
reflect(type)
};
throw expectation_failure<parse_error>
{
e, string_view::begin(), error_show_max
};
throw;
}
//
@ -2717,21 +2732,13 @@ catch(const qi::expectation_failure<const char *> &e)
ircd::json::object::const_iterator &
ircd::json::object::const_iterator::operator++()
try
{
assert(start != stop);
state = {};
qi::parse(start, stop, object_next_parse, state);
parser(start, stop, object_next_parse, state);
return *this;
}
catch(const qi::expectation_failure<const char *> &e)
{
throw expectation_failure<parse_error>
{
e, start, error_show_max
};
}
//
// object::member
@ -3005,23 +3012,16 @@ const
ircd::json::array::const_iterator
ircd::json::array::begin()
const try
const
{
const_iterator ret
{
string_view::begin(), string_view::end()
};
qi::parse(ret.start, ret.stop, array_begin_parse, ret.state);
parser(ret.start, ret.stop, array_begin_parse, ret.state);
return ret;
}
catch(const qi::expectation_failure<const char *> &e)
{
throw expectation_failure<parse_error>
{
e, string_view::data(), error_show_max
};
}
ircd::string_view
ircd::json::array::operator[](const size_t &i)
@ -3087,21 +3087,13 @@ const
ircd::json::array::const_iterator &
ircd::json::array::const_iterator::operator++()
try
{
assert(start != stop);
state = string_view{};
qi::parse(start, stop, array_next_parse, state);
parser(start, stop, array_next_parse, state);
return *this;
}
catch(const qi::expectation_failure<const char *> &e)
{
throw expectation_failure<parse_error>
{
e, start, error_show_max
};
}
///////////////////////////////////////////////////////////////////////////////
//
@ -4064,7 +4056,7 @@ ircd::json::valid(const string_view &s,
noexcept try
{
const char *start(begin(s)), *const stop(end(s));
return qi::parse(start, stop, validation);
return parser(start, stop, validation);
}
catch(...)
{
@ -4074,23 +4066,15 @@ catch(...)
void
ircd::json::valid(const string_view &s)
try
{
const char *start(begin(s)), *const stop(end(s));
const bool ret
{
qi::parse(start, stop, validation_expect)
parser(start, stop, validation_expect)
};
assert(ret);
}
catch(const qi::expectation_failure<const char *> &e)
{
throw expectation_failure<parse_error>
{
e, begin(s), error_show_max
};
}
void
ircd::json::valid_output(const string_view &sv,
@ -4210,7 +4194,7 @@ ircd::json::type(const string_view &buf,
{
const bool ret
{
qi::parse(begin(buf), end(buf), type_parse_is[type])
parser(begin(buf), end(buf), type_parse_is[type])
};
return ret;
@ -4223,7 +4207,7 @@ ircd::json::type(const string_view &buf,
{
const bool ret
{
qi::parse(begin(buf), end(buf), type_parse_is_strict[type])
parser(begin(buf), end(buf), type_parse_is_strict[type])
};
return ret;
@ -4233,7 +4217,7 @@ enum ircd::json::type
ircd::json::type(const string_view &buf)
{
enum type ret;
if(!qi::parse(begin(buf), end(buf), type_parse, ret))
if(!parser(begin(buf), end(buf), type_parse, ret))
throw type_error
{
"Failed to derive JSON value type from input buffer."
@ -4247,7 +4231,7 @@ ircd::json::type(const string_view &buf,
std::nothrow_t)
{
enum type ret;
if(!qi::parse(begin(buf), end(buf), type_parse, ret))
if(!parser(begin(buf), end(buf), type_parse, ret))
return STRING;
return ret;
@ -4258,7 +4242,7 @@ ircd::json::type(const string_view &buf,
strict_t)
{
enum type ret;
if(!qi::parse(begin(buf), end(buf), type_parse_strict, ret))
if(!parser(begin(buf), end(buf), type_parse_strict, ret))
throw type_error
{
"Failed to derive JSON value type from input buffer."
@ -4273,7 +4257,7 @@ ircd::json::type(const string_view &buf,
std::nothrow_t)
{
enum type ret;
if(!qi::parse(begin(buf), end(buf), type_parse_strict, ret))
if(!parser(begin(buf), end(buf), type_parse_strict, ret))
return STRING;
return ret;

View file

@ -422,7 +422,7 @@ try
parse::head
};
qi::parse(start, stop, grammar, *this);
ircd::parse(start, stop, grammar, *this);
}
catch(const qi::expectation_failure<const char *> &e)
{

View file

@ -388,12 +388,7 @@ ircd::m::vm::fetch::state(const event &event,
try
{
const event::prev prev{event};
const size_t prev_miss
{
prev.prev_events_count() - prev.prev_events_exist()
};
if(!prev_miss)
if(prev.prev_exist())
return;
const auto &[sounding_depth, sounding_idx]