From ca5b91f9cc42664369a281dc359ca5c92002c52a Mon Sep 17 00:00:00 2001 From: davidot Date: Sun, 11 Sep 2022 10:25:25 +0200 Subject: [PATCH] test262-runner: Overwrite __assertion_failed when compiling for Serenity We also protect against recursive assert failures, for example due to being out of memory. With this change the runner now compiles and runs on Serenity :^). --- Tests/LibJS/CMakeLists.txt | 9 ++++++++ Tests/LibJS/test262-runner.cpp | 41 +++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/Tests/LibJS/CMakeLists.txt b/Tests/LibJS/CMakeLists.txt index ce684ced41..2d8159c385 100644 --- a/Tests/LibJS/CMakeLists.txt +++ b/Tests/LibJS/CMakeLists.txt @@ -11,3 +11,12 @@ link_with_locale_data(test-bytecode-js) serenity_test(test-value-js.cpp LibJS LIBS LibJS) link_with_locale_data(test-value-js) + +serenity_component( + test262-runner + TARGETS test262-runner +) +add_executable(test262-runner test262-runner.cpp) +target_link_libraries(test262-runner LibJS LibCore) +link_with_locale_data(test262-runner) +install(TARGETS test262-runner RUNTIME DESTINATION bin OPTIONAL) diff --git a/Tests/LibJS/test262-runner.cpp b/Tests/LibJS/test262-runner.cpp index e1135c14da..8f7dcbd76a 100644 --- a/Tests/LibJS/test262-runner.cpp +++ b/Tests/LibJS/test262-runner.cpp @@ -502,21 +502,40 @@ static bool verify_test(Result& result, TestMetadata const& met } static FILE* saved_stdout_fd; +static bool g_in_assert = false; -void __assert_fail(char const* assertion, char const* file, unsigned int line, char const* function) +[[noreturn]] static void handle_failed_assert(char const* assert_failed_message) { - JsonObject assert_fail_result; - assert_fail_result.set("test", s_current_test); - assert_fail_result.set("assert_fail", true); - assert_fail_result.set("result", "assert_fail"); - assert_fail_result.set("output", String::formatted("{}:{}: {}: Assertion `{}' failed.", file, line, function, assertion)); - outln(saved_stdout_fd, "RESULT {}{}", assert_fail_result.to_string(), '\0'); - // (Attempt to) Ensure that messages are written before quitting. - fflush(saved_stdout_fd); - fflush(stderr); - abort(); + if (!g_in_assert) { + // Just in case we trigger an assert while creating the JSON output just + // immediately stop if we are already in a failed assert. + g_in_assert = true; + JsonObject assert_fail_result; + assert_fail_result.set("test", s_current_test); + assert_fail_result.set("assert_fail", true); + assert_fail_result.set("result", "assert_fail"); + assert_fail_result.set("output", assert_failed_message); + outln(saved_stdout_fd, "RESULT {}{}", assert_fail_result.to_string(), '\0'); + // (Attempt to) Ensure that messages are written before quitting. + fflush(saved_stdout_fd); + fflush(stderr); + } + exit(12); } +#ifdef __serenity__ +void __assertion_failed(char const* assertion) +{ + handle_failed_assert(assertion); +} +#else +[[noreturn]] void __assert_fail(char const* assertion, char const* file, unsigned int line, char const* function) +{ + auto full_message = String::formatted("{}:{}: {}: Assertion `{}' failed.", file, line, function, assertion); + handle_failed_assert(full_message.characters()); +} +#endif + int main(int argc, char** argv) { int timeout = 10;