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 # 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>) 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_ONDEMAND_SAFETY_RAILS) if(SIMDJSON_API_USAGE_CHECKS)
message(STATUS "Ondemand safety rails enabled. Ondemand user code will be checked at runtime. This will be slower than normal!") 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_ONDEMAND_SAFETY_RAILS) target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_API_USAGE_CHECKS=1)
endif(SIMDJSON_ONDEMAND_SAFETY_RAILS) endif(SIMDJSON_API_USAGE_CHECKS)
option(SIMDJSON_BASH "Allow usage of bash within CMake" ON) 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(child_depth >= 1 && child_depth < INT32_MAX);
SIMDJSON_ASSUME(_depth == child_depth - 1); SIMDJSON_ASSUME(_depth == child_depth - 1);
_depth = child_depth; _depth = child_depth;
#if SIMDJSON_API_USAGE_CHECKS
parser->start_positions[_depth] = token.index; parser->start_positions[_depth] = token.index;
#endif
} }
simdjson_really_inline depth_t json_iterator::depth() const noexcept { 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_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(child_depth >= 1 && child_depth < INT32_MAX);
SIMDJSON_ASSUME(_depth == child_depth - 1); SIMDJSON_ASSUME(_depth == child_depth - 1);
#if SIMDJSON_API_USAGE_CHECKS
SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]);
#endif
token.set_position(position); token.set_position(position);
_depth = child_depth; _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_really_inline error_code json_iterator::optional_error(error_code _error, const char *message) noexcept {
SIMDJSON_ASSUME(_error == INCORRECT_TYPE || _error == NO_SUCH_FIELD); 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 token_position position() const noexcept;
simdjson_really_inline void reenter_child(token_position position, depth_t child_depth) 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: protected:
simdjson_really_inline json_iterator(const uint8_t *buf, ondemand::parser *parser) noexcept; 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 // string_capacity copied from document::allocate
size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64); size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64);
string_buf.reset(new (std::nothrow) uint8_t[string_capacity]); 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]); start_positions.reset(new (std::nothrow) token_position[new_max_depth]);
#endif
if (implementation) { if (implementation) {
SIMDJSON_TRY( implementation->set_capacity(new_capacity) ); SIMDJSON_TRY( implementation->set_capacity(new_capacity) );
SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) ); SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) );

View File

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

View File

@ -94,7 +94,9 @@ simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator
} else { } else {
if ((error = skip_child() )) { abandon(); return error; } if ((error = skip_child() )) { abandon(); return error; }
if ((error = has_next_field().get(has_value) )) { 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) { while (has_value) {
// Get the key and colon, stopping at the 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 // Finish the previous value and see if , or } is next
if ((error = skip_child() )) { abandon(); return error; } if ((error = skip_child() )) { abandon(); return error; }
if ((error = has_next_field().get(has_value) )) { 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: // After initial processing, we will be in one of two states: