|
36 | 36 |
|
37 | 37 | #include <unordered_set> |
38 | 38 | #include <vector> |
| 39 | +// The C++ style guide recommends using <re2> instead of <regex>. However, the |
| 40 | +// former isn't available in V8. |
| 41 | +#include <regex> // NOLINT(build/c++11) |
39 | 42 | #include "src/api.h" |
40 | 43 | #include "src/log-utils.h" |
41 | 44 | #include "src/log.h" |
@@ -257,30 +260,41 @@ class TestCodeEventHandler : public v8::CodeEventHandler { |
257 | 260 | explicit TestCodeEventHandler(v8::Isolate* isolate) |
258 | 261 | : v8::CodeEventHandler(isolate) {} |
259 | 262 |
|
260 | | - const char* FindLine(const char* prefix, const char* suffix = nullptr, |
261 | | - const char* start = nullptr) { |
262 | | - if (!log_.length()) return NULL; |
263 | | - const char* c_log = log_.c_str(); |
264 | | - if (start == nullptr) start = c_log; |
265 | | - const char* end = c_log + log_.length(); |
266 | | - return FindLogLine(start, end, prefix, suffix); |
| 263 | + size_t CountLines(std::string prefix, std::string suffix = std::string()) { |
| 264 | + if (!log_.length()) return 0; |
| 265 | + |
| 266 | + std::regex expression("(^|\\n)" + prefix + ".*" + suffix + "(?=\\n|$)"); |
| 267 | + |
| 268 | + size_t match_count(std::distance( |
| 269 | + std::sregex_iterator(log_.begin(), log_.end(), expression), |
| 270 | + std::sregex_iterator())); |
| 271 | + |
| 272 | + return match_count; |
267 | 273 | } |
268 | 274 |
|
269 | 275 | void Handle(v8::CodeEvent* code_event) override { |
270 | | - const char* code_type = |
271 | | - v8::CodeEvent::GetCodeEventTypeName(code_event->GetCodeType()); |
272 | | - char function_name[1000]; |
273 | | - strncpy(function_name, code_type, 1000); |
274 | | - function_name[strlen(code_type)] = ' '; |
275 | | - code_event->GetFunctionName()->WriteUtf8( |
276 | | - function_name + strlen(code_type) + 1, 1000); |
277 | | - function_name[strlen(function_name) + 1] = '\0'; |
278 | | - function_name[strlen(function_name)] = '\n'; |
279 | | - |
280 | | - log_ += std::string(function_name); |
| 276 | + std::string log_line = ""; |
| 277 | + log_line += v8::CodeEvent::GetCodeEventTypeName(code_event->GetCodeType()); |
| 278 | + log_line += " "; |
| 279 | + log_line += FormatName(code_event); |
| 280 | + log_line += "\n"; |
| 281 | + log_ += log_line; |
281 | 282 | } |
282 | 283 |
|
283 | 284 | private: |
| 285 | + std::string FormatName(v8::CodeEvent* code_event) { |
| 286 | + std::string name = std::string(code_event->GetComment()); |
| 287 | + if (name.empty()) { |
| 288 | + v8::Local<v8::String> functionName = code_event->GetFunctionName(); |
| 289 | + std::string buffer(functionName->Utf8Length() + 1, 0); |
| 290 | + functionName->WriteUtf8(&buffer[0], functionName->Utf8Length() + 1); |
| 291 | + // Sanitize name, removing unwanted \0 resulted from WriteUtf8 |
| 292 | + name = std::string(buffer.c_str()); |
| 293 | + } |
| 294 | + |
| 295 | + return name; |
| 296 | + } |
| 297 | + |
284 | 298 | std::string log_; |
285 | 299 | }; |
286 | 300 |
|
@@ -854,21 +868,24 @@ TEST(ExternalCodeEventListener) { |
854 | 868 | "testCodeEventListenerBeforeStart('1', 1);"; |
855 | 869 | CompileRun(source_text_before_start); |
856 | 870 |
|
857 | | - CHECK_NULL(code_event_handler.FindLine("LazyCompile", |
858 | | - "testCodeEventListenerBeforeStart")); |
| 871 | + CHECK_EQ(code_event_handler.CountLines("LazyCompile", |
| 872 | + "testCodeEventListenerBeforeStart"), |
| 873 | + 0); |
859 | 874 |
|
860 | 875 | code_event_handler.Enable(); |
861 | 876 |
|
862 | | - CHECK_NOT_NULL(code_event_handler.FindLine( |
863 | | - "LazyCompile", "testCodeEventListenerBeforeStart")); |
| 877 | + CHECK_GE(code_event_handler.CountLines("LazyCompile", |
| 878 | + "testCodeEventListenerBeforeStart"), |
| 879 | + 1); |
864 | 880 |
|
865 | 881 | const char* source_text_after_start = |
866 | 882 | "function testCodeEventListenerAfterStart(a,b) { return a + b };" |
867 | 883 | "testCodeEventListenerAfterStart('1', 1);"; |
868 | 884 | CompileRun(source_text_after_start); |
869 | 885 |
|
870 | | - CHECK_NOT_NULL(code_event_handler.FindLine( |
871 | | - "LazyCompile", "testCodeEventListenerAfterStart")); |
| 886 | + CHECK_GE(code_event_handler.CountLines("LazyCompile", |
| 887 | + "testCodeEventListenerAfterStart"), |
| 888 | + 1); |
872 | 889 |
|
873 | 890 | context->Exit(); |
874 | 891 | } |
@@ -897,21 +914,28 @@ TEST(ExternalCodeEventListenerWithInterpretedFramesNativeStack) { |
897 | 914 | "testCodeEventListenerBeforeStart('1', 1);"; |
898 | 915 | CompileRun(source_text_before_start); |
899 | 916 |
|
900 | | - CHECK_NULL(code_event_handler.FindLine("InterpretedFunction", |
901 | | - "testCodeEventListenerBeforeStart")); |
| 917 | + CHECK_EQ(code_event_handler.CountLines("InterpretedFunction", |
| 918 | + "testCodeEventListenerBeforeStart"), |
| 919 | + 0); |
902 | 920 |
|
903 | 921 | code_event_handler.Enable(); |
904 | 922 |
|
905 | | - CHECK_NOT_NULL(code_event_handler.FindLine( |
906 | | - "InterpretedFunction", "testCodeEventListenerBeforeStart")); |
| 923 | + CHECK_GE(code_event_handler.CountLines("InterpretedFunction", |
| 924 | + "testCodeEventListenerBeforeStart"), |
| 925 | + 1); |
907 | 926 |
|
908 | 927 | const char* source_text_after_start = |
909 | 928 | "function testCodeEventListenerAfterStart(a,b) { return a + b };" |
910 | 929 | "testCodeEventListenerAfterStart('1', 1);"; |
911 | 930 | CompileRun(source_text_after_start); |
912 | 931 |
|
913 | | - CHECK_NOT_NULL(code_event_handler.FindLine( |
914 | | - "InterpretedFunction", "testCodeEventListenerAfterStart")); |
| 932 | + CHECK_GE(code_event_handler.CountLines("InterpretedFunction", |
| 933 | + "testCodeEventListenerAfterStart"), |
| 934 | + 1); |
| 935 | + |
| 936 | + CHECK_EQ( |
| 937 | + code_event_handler.CountLines("Builtin", "InterpreterEntryTrampoline"), |
| 938 | + 1); |
915 | 939 |
|
916 | 940 | context->Exit(); |
917 | 941 | } |
|
0 commit comments