Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options to compiler #374

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contrib/perf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ auto main(int argc, char **argv) noexcept -> int {
schema, sourcemeta::core::schema_official_walker,
sourcemeta::core::schema_official_resolver,
sourcemeta::blaze::default_schema_compiler,
sourcemeta::blaze::default_compile_options,
sourcemeta::blaze::Mode::FastValidation)};

sourcemeta::blaze::Evaluator evaluator;
Expand Down
24 changes: 15 additions & 9 deletions src/compiler/compile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace {

auto compile_subschema(const sourcemeta::blaze::Context &context,
const sourcemeta::blaze::SchemaContext &schema_context,
const sourcemeta::blaze::CompileOptions &options,
const sourcemeta::blaze::DynamicContext &dynamic_context,
const std::optional<std::string> &default_dialect)
-> sourcemeta::blaze::Instructions {
Expand Down Expand Up @@ -45,6 +46,7 @@ auto compile_subschema(const sourcemeta::blaze::Context &context,
schema_context.schema, entry.vocabularies, schema_context.base,
// TODO: This represents a copy
schema_context.labels, schema_context.references},
options,
{keyword, dynamic_context.base_schema_location,
dynamic_context.base_instance_location,
dynamic_context.property_as_target},
Expand All @@ -63,6 +65,7 @@ auto compile_subschema(const sourcemeta::blaze::Context &context,
auto precompile(
const sourcemeta::blaze::Context &context,
sourcemeta::blaze::SchemaContext &schema_context,
const sourcemeta::blaze::CompileOptions &options,
const sourcemeta::blaze::DynamicContext &dynamic_context,
const sourcemeta::core::SchemaFrame::Locations::value_type &entry)
-> sourcemeta::blaze::Instructions {
Expand Down Expand Up @@ -90,7 +93,7 @@ auto precompile(
nested_schema_context, dynamic_context,
sourcemeta::blaze::ValueUnsignedInteger{label},
sourcemeta::blaze::compile(
context, nested_schema_context,
context, nested_schema_context, options,
sourcemeta::blaze::relative_dynamic_context(),
sourcemeta::core::empty_pointer,
sourcemeta::core::empty_pointer, entry.first.second))};
Expand All @@ -103,8 +106,9 @@ namespace sourcemeta::blaze {
auto compile(const sourcemeta::core::JSON &schema,
const sourcemeta::core::SchemaWalker &walker,
const sourcemeta::core::SchemaResolver &resolver,
const Compiler &compiler, const Mode mode,
const std::optional<std::string> &default_dialect) -> Template {
const Compiler &compiler, const CompileOptions &options,
const Mode mode, const std::optional<std::string> &default_dialect)
-> Template {
assert(is_schema(schema));

// Make sure the input schema is bundled, otherwise we won't be able to
Expand Down Expand Up @@ -226,8 +230,8 @@ auto compile(const sourcemeta::core::JSON &schema,
{sourcemeta::core::SchemaReferenceType::Static, destination}));
const auto match{context.frame.locations().find(
{sourcemeta::core::SchemaReferenceType::Static, destination})};
for (auto &&substep :
precompile(context, schema_context, dynamic_context, *match)) {
for (auto &&substep : precompile(context, schema_context, options,
dynamic_context, *match)) {
compiler_template.push_back(std::move(substep));
}
}
Expand All @@ -245,15 +249,15 @@ auto compile(const sourcemeta::core::JSON &schema,
continue;
}

for (auto &&substep :
precompile(context, schema_context, dynamic_context, entry)) {
for (auto &&substep : precompile(context, schema_context, options,
dynamic_context, entry)) {
compiler_template.push_back(std::move(substep));
}
}
}

auto children{compile_subschema(context, schema_context, dynamic_context,
root_frame_entry.dialect)};
auto children{compile_subschema(context, schema_context, options,
dynamic_context, root_frame_entry.dialect)};

const bool track{
context.mode != Mode::FastValidation ||
Expand All @@ -275,6 +279,7 @@ auto compile(const sourcemeta::core::JSON &schema,
}

auto compile(const Context &context, const SchemaContext &schema_context,
const CompileOptions &options,
const DynamicContext &dynamic_context,
const sourcemeta::core::Pointer &schema_suffix,
const sourcemeta::core::Pointer &instance_suffix,
Expand Down Expand Up @@ -321,6 +326,7 @@ auto compile(const Context &context, const SchemaContext &schema_context,
""),
// TODO: This represents a copy
schema_context.labels, schema_context.references},
options,
{dynamic_context.keyword, destination_pointer,
dynamic_context.base_instance_location.concat(instance_suffix),
dynamic_context.property_as_target},
Expand Down
13 changes: 7 additions & 6 deletions src/compiler/default_compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
auto sourcemeta::blaze::default_schema_compiler(
const sourcemeta::blaze::Context &context,
const sourcemeta::blaze::SchemaContext &schema_context,
const sourcemeta::blaze::CompileOptions &options,
const sourcemeta::blaze::DynamicContext &dynamic_context,
const sourcemeta::blaze::Instructions &current)
-> sourcemeta::blaze::Instructions {
Expand Down Expand Up @@ -52,16 +53,16 @@ auto sourcemeta::blaze::default_schema_compiler(
#define COMPILE(vocabulary, _keyword, handler) \
if (schema_context.vocabularies.contains(vocabulary) && \
dynamic_context.keyword == (_keyword)) { \
return internal::handler(context, schema_context, dynamic_context, \
current); \
return internal::handler(context, schema_context, options, \
dynamic_context, current); \
}

#define COMPILE_ANY(vocabulary_1, vocabulary_2, _keyword, handler) \
if ((schema_context.vocabularies.contains(vocabulary_1) || \
schema_context.vocabularies.contains(vocabulary_2)) && \
dynamic_context.keyword == (_keyword)) { \
return internal::handler(context, schema_context, dynamic_context, \
current); \
return internal::handler(context, schema_context, options, \
dynamic_context, current); \
}

#define STOP_IF_SIBLING_KEYWORD(vocabulary, _keyword) \
Expand Down Expand Up @@ -630,8 +631,8 @@ auto sourcemeta::blaze::default_schema_compiler(
return {};
}

return internal::compiler_2019_09_core_annotation(context, schema_context,
dynamic_context, current);
return internal::compiler_2019_09_core_annotation(
context, schema_context, options, dynamic_context, current);
}

return {};
Expand Down
89 changes: 51 additions & 38 deletions src/compiler/default_compiler_2019_09.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ using namespace sourcemeta::blaze;

auto compiler_2019_09_applicator_dependentschemas(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &)
-> Instructions {
const CompileOptions &options, const DynamicContext &dynamic_context,
const Instructions &) -> Instructions {
assert(schema_context.schema.at(dynamic_context.keyword).is_object());

if (schema_context.schema.defines("type") &&
Expand Down Expand Up @@ -43,7 +43,7 @@ auto compiler_2019_09_applicator_dependentschemas(
make(sourcemeta::blaze::InstructionIndex::LogicalWhenDefines, context,
schema_context, relative_dynamic_context(dynamic_context),
make_property(dependent),
compile(context, schema_context,
compile(context, schema_context, options,
relative_dynamic_context(dynamic_context), {dependent},
sourcemeta::core::empty_pointer)));
}
Expand All @@ -57,8 +57,8 @@ auto compiler_2019_09_applicator_dependentschemas(

auto compiler_2019_09_validation_dependentrequired(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &)
-> Instructions {
const CompileOptions &, const DynamicContext &dynamic_context,
const Instructions &) -> Instructions {
if (!schema_context.schema.at(dynamic_context.keyword).is_object()) {
return {};
}
Expand Down Expand Up @@ -98,6 +98,7 @@ auto compiler_2019_09_validation_dependentrequired(

auto compiler_2019_09_core_annotation(const Context &context,
const SchemaContext &schema_context,
const CompileOptions &,
const DynamicContext &dynamic_context,
const Instructions &) -> Instructions {
return {make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,
Expand All @@ -108,8 +109,9 @@ auto compiler_2019_09_core_annotation(const Context &context,

auto compiler_2019_09_applicator_contains_with_options(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &,
const bool annotate, const bool track_evaluation) -> Instructions {
const CompileOptions &options, const DynamicContext &dynamic_context,
const Instructions &, const bool annotate, const bool track_evaluation)
-> Instructions {
if (schema_context.schema.defines("type") &&
schema_context.schema.at("type").is_string() &&
schema_context.schema.at("type").to_string() != "array") {
Expand Down Expand Up @@ -149,9 +151,10 @@ auto compiler_2019_09_applicator_contains_with_options(
return {};
}

Instructions children{compile(
context, schema_context, relative_dynamic_context(dynamic_context),
sourcemeta::core::empty_pointer, sourcemeta::core::empty_pointer)};
Instructions children{compile(context, schema_context, options,
relative_dynamic_context(dynamic_context),
sourcemeta::core::empty_pointer,
sourcemeta::core::empty_pointer)};

if (annotate) {
children.push_back(
Expand Down Expand Up @@ -187,26 +190,29 @@ auto compiler_2019_09_applicator_contains_with_options(

auto compiler_2019_09_applicator_contains(const Context &context,
const SchemaContext &schema_context,
const CompileOptions &options,
const DynamicContext &dynamic_context,
const Instructions &current)
-> Instructions {
return compiler_2019_09_applicator_contains_with_options(
context, schema_context, dynamic_context, current, false, false);
context, schema_context, options, dynamic_context, current, false, false);
}

auto compiler_2019_09_applicator_additionalproperties(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &)
const CompileOptions &options, const DynamicContext &dynamic_context,
const Instructions &)

-> Instructions {
return compiler_draft4_applicator_additionalproperties_with_options(
context, schema_context, dynamic_context,
context, schema_context, options, dynamic_context,
context.mode == Mode::Exhaustive,
requires_evaluation(context, schema_context));
}

auto compiler_2019_09_applicator_items(const Context &context,
const SchemaContext &schema_context,
const CompileOptions &options,
const DynamicContext &dynamic_context,
const Instructions &) -> Instructions {
// TODO: Be smarter about how we treat `unevaluatedItems` like how we do for
Expand All @@ -219,20 +225,20 @@ auto compiler_2019_09_applicator_items(const Context &context,

if (schema_context.schema.at(dynamic_context.keyword).is_array()) {
return compiler_draft4_applicator_items_with_options(
context, schema_context, dynamic_context,
context, schema_context, options, dynamic_context,
context.mode == Mode::Exhaustive, track);
}

return compiler_draft4_applicator_items_with_options(
context, schema_context, dynamic_context,
context, schema_context, options, dynamic_context,
context.mode == Mode::Exhaustive,
track && !schema_context.schema.defines("unevaluatedItems"));
}

auto compiler_2019_09_applicator_additionalitems(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &)
-> Instructions {
const CompileOptions &options, const DynamicContext &dynamic_context,
const Instructions &) -> Instructions {
// TODO: Be smarter about how we treat `unevaluatedItems` like how we do for
// `unevaluatedProperties`
const bool track{
Expand All @@ -242,15 +248,15 @@ auto compiler_2019_09_applicator_additionalitems(
})};

return compiler_draft4_applicator_additionalitems_with_options(
context, schema_context, dynamic_context,
context, schema_context, options, dynamic_context,
context.mode == Mode::Exhaustive,
track && !schema_context.schema.defines("unevaluatedItems"));
}

auto compiler_2019_09_applicator_unevaluateditems(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &)
-> Instructions {
const CompileOptions &options, const DynamicContext &dynamic_context,
const Instructions &) -> Instructions {
if (schema_context.schema.defines("type") &&
schema_context.schema.at("type").is_string() &&
schema_context.schema.at("type").to_string() != "array") {
Expand All @@ -274,9 +280,10 @@ auto compiler_2019_09_applicator_unevaluateditems(
}
}

Instructions children{compile(
context, schema_context, relative_dynamic_context(dynamic_context),
sourcemeta::core::empty_pointer, sourcemeta::core::empty_pointer)};
Instructions children{compile(context, schema_context, options,
relative_dynamic_context(dynamic_context),
sourcemeta::core::empty_pointer,
sourcemeta::core::empty_pointer)};

if (context.mode == Mode::Exhaustive) {
children.push_back(
Expand Down Expand Up @@ -305,17 +312,18 @@ auto compiler_2019_09_applicator_unevaluateditems(

auto compiler_2019_09_applicator_unevaluatedproperties(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &)
-> Instructions {
const CompileOptions &options, const DynamicContext &dynamic_context,
const Instructions &) -> Instructions {
if (schema_context.schema.defines("type") &&
schema_context.schema.at("type").is_string() &&
schema_context.schema.at("type").to_string() != "object") {
return {};
}

Instructions children{compile(
context, schema_context, relative_dynamic_context(dynamic_context),
sourcemeta::core::empty_pointer, sourcemeta::core::empty_pointer)};
Instructions children{compile(context, schema_context, options,
relative_dynamic_context(dynamic_context),
sourcemeta::core::empty_pointer,
sourcemeta::core::empty_pointer)};

if (context.mode == Mode::Exhaustive) {
children.push_back(
Expand Down Expand Up @@ -347,14 +355,18 @@ auto compiler_2019_09_applicator_unevaluatedproperties(
} else if (keyword == "patternProperties") {
if (subschema.is_object()) {
for (const auto &property : subschema.as_object()) {
const auto maybe_prefix{pattern_as_prefix(property.first)};
std::optional<std::basic_string<char>> maybe_prefix{std::nullopt};
if (options.simplify_regexes) {
maybe_prefix = pattern_as_prefix(property.first);
}
if (maybe_prefix.has_value()) {
filter_prefixes.push_back(maybe_prefix.value());
} else {
filter_regexes.push_back(
{parse_regex(property.first, schema_context.base,
schema_context.relative_pointer.initial().concat(
{"patternProperties"})),
{"patternProperties"}),
options.simplify_regexes),
property.first});
}
}
Expand Down Expand Up @@ -405,15 +417,16 @@ auto compiler_2019_09_applicator_unevaluatedproperties(

auto compiler_2019_09_core_recursiveref(const Context &context,
const SchemaContext &schema_context,
const CompileOptions &options,
const DynamicContext &dynamic_context,
const Instructions &current)
-> Instructions {
const auto &entry{static_frame_entry(context, schema_context)};
// In this case, just behave as a normal static reference
if (!context.frame.references().contains(
{sourcemeta::core::SchemaReferenceType::Dynamic, entry.pointer})) {
return compiler_draft4_core_ref(context, schema_context, dynamic_context,
current);
return compiler_draft4_core_ref(context, schema_context, options,
dynamic_context, current);
}

return {make(sourcemeta::blaze::InstructionIndex::ControlDynamicAnchorJump,
Expand All @@ -422,20 +435,20 @@ auto compiler_2019_09_core_recursiveref(const Context &context,

auto compiler_2019_09_applicator_properties(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &current)
-> Instructions {
const CompileOptions &options, const DynamicContext &dynamic_context,
const Instructions &current) -> Instructions {
return compiler_draft4_applicator_properties_with_options(
context, schema_context, dynamic_context, current,
context, schema_context, options, dynamic_context, current,
context.mode == Mode::Exhaustive,
requires_evaluation(context, schema_context));
}

auto compiler_2019_09_applicator_patternproperties(
const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context, const Instructions &)
-> Instructions {
const CompileOptions &options, const DynamicContext &dynamic_context,
const Instructions &) -> Instructions {
return compiler_draft4_applicator_patternproperties_with_options(
context, schema_context, dynamic_context,
context, schema_context, options, dynamic_context,
context.mode == Mode::Exhaustive,
requires_evaluation(context, schema_context));
}
Expand Down
Loading