|
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