Allow object lookup safety to be disabled

Use cmake -DSIMDJSON_API_USAGE_CHECKS=OFF ..
This commit is contained in:
John Keiser 2021-01-29 09:46:09 -08:00
parent e4626d233c
commit 0d1c99a6ad
6 changed files with 28 additions and 8 deletions

View File

@ -172,11 +172,11 @@ endif()
#
# Other optional flags
#
option(SIMDJSON_ONDEMAND_SAFETY_RAILS "Validate ondemand user code at runtime to ensure it is being used correctly. Defaults to ON for debug builds, OFF for release builds." $<IF:$<CONFIG:DEBUG>,ON,OFF>)
if(SIMDJSON_ONDEMAND_SAFETY_RAILS)
message(STATUS "Ondemand safety rails enabled. Ondemand user code will be checked at runtime. This will be slower than normal!")
target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_ONDEMAND_SAFETY_RAILS)
endif(SIMDJSON_ONDEMAND_SAFETY_RAILS)
option(SIMDJSON_API_USAGE_CHECKS "Validate ondemand user code at runtime to ensure it is being used correctly. Turning this off disables some checks that have a small performance impact. Defaults to ON." ON)
if(SIMDJSON_API_USAGE_CHECKS)
message(STATUS "Ondemand safety rails enabled. Ondemand user code will be checked at runtime. Turn this on for production to get maximum performance!")
target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_API_USAGE_CHECKS=1)
endif(SIMDJSON_API_USAGE_CHECKS)
option(SIMDJSON_BASH "Allow usage of bash within CMake" ON)

View File

@ -157,7 +157,9 @@ simdjson_really_inline void json_iterator::descend_to(depth_t child_depth) noexc
SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX);
SIMDJSON_ASSUME(_depth == child_depth - 1);
_depth = child_depth;
#if SIMDJSON_API_USAGE_CHECKS
parser->start_positions[_depth] = token.index;
#endif
}
simdjson_really_inline depth_t json_iterator::depth() const noexcept {
@ -181,11 +183,19 @@ simdjson_really_inline token_position json_iterator::position() const noexcept {
simdjson_really_inline void json_iterator::reenter_child(token_position position, depth_t child_depth) noexcept {
SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX);
SIMDJSON_ASSUME(_depth == child_depth - 1);
#if SIMDJSON_API_USAGE_CHECKS
SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]);
#endif
token.set_position(position);
_depth = child_depth;
}
#if SIMDJSON_API_USAGE_CHECKS
simdjson_really_inline token_position json_iterator::start_position(depth_t depth) const noexcept {
return parser->start_positions[depth];
}
#endif
simdjson_really_inline error_code json_iterator::optional_error(error_code _error, const char *message) noexcept {
SIMDJSON_ASSUME(_error == INCORRECT_TYPE || _error == NO_SUCH_FIELD);

View File

@ -181,6 +181,9 @@ public:
simdjson_really_inline token_position position() const noexcept;
simdjson_really_inline void reenter_child(token_position position, depth_t child_depth) noexcept;
#if SIMDJSON_API_USAGE_CHECKS
simdjson_really_inline token_position start_position(depth_t depth) const noexcept;
#endif
protected:
simdjson_really_inline json_iterator(const uint8_t *buf, ondemand::parser *parser) noexcept;

View File

@ -8,7 +8,9 @@ simdjson_warn_unused simdjson_really_inline error_code parser::allocate(size_t n
// string_capacity copied from document::allocate
size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64);
string_buf.reset(new (std::nothrow) uint8_t[string_capacity]);
#if SIMDJSON_API_USAGE_CHECKS
start_positions.reset(new (std::nothrow) token_position[new_max_depth]);
#endif
if (implementation) {
SIMDJSON_TRY( implementation->set_capacity(new_capacity) );
SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) );

View File

@ -110,7 +110,9 @@ private:
/** @private [for benchmarking access] The implementation to use */
std::unique_ptr<internal::dom_parser_implementation> implementation{};
std::unique_ptr<uint8_t[]> string_buf{};
#if SIMDJSON_API_USAGE_CHECKS
std::unique_ptr<token_position[]> start_positions{};
#endif
/**
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
@ -123,7 +125,6 @@ private:
simdjson_warn_unused error_code allocate(size_t capacity, size_t max_depth=DEFAULT_MAX_DEPTH) noexcept;
friend class json_iterator;
friend class value_iterator;
};
} // namespace ondemand

View File

@ -94,7 +94,9 @@ simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator
} else {
if ((error = skip_child() )) { abandon(); return error; }
if ((error = has_next_field().get(has_value) )) { abandon(); return error; }
// if (_json_iter->parser->start_positions[_depth] != _start_position) { return OUT_OF_ORDER_ITERATION; }
#if SIMDJSON_API_USAGE_CHECKS
if (_json_iter->start_position(_depth) != _start_position) { return OUT_OF_ORDER_ITERATION; }
#endif
}
while (has_value) {
// Get the key and colon, stopping at the value.
@ -170,7 +172,9 @@ simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator
// Finish the previous value and see if , or } is next
if ((error = skip_child() )) { abandon(); return error; }
if ((error = has_next_field().get(has_value) )) { abandon(); return error; }
// if (_json_iter->parser->start_positions[_depth] != _start_position) { return OUT_OF_ORDER_ITERATION; }
#if SIMDJSON_API_USAGE_CHECKS
if (_json_iter->start_position(_depth) != _start_position) { return OUT_OF_ORDER_ITERATION; }
#endif
}
// After initial processing, we will be in one of two states: