| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,13 +1,11 @@ | |||
| 1 | 1 | #include <algorithm> | |
| 2 | + #include <array> | ||
| 2 | 3 | #include <cassert> | |
| 3 | 4 | #include <cctype> | |
| 4 | - #include <cinttypes> | ||
| 5 | 5 | #include <cstdarg> | |
| 6 | 6 | #include <cstdio> | |
| 7 | 7 | #include <functional> | |
| 8 | - #include <iostream> | ||
| 9 | 8 | #include <map> | |
| 10 | - #include <set> | ||
| 11 | 9 | #include <string> | |
| 12 | 10 | #include <string_view> | |
| 13 | 11 | #include <vector> | |
@@ -72,42 +70,24 @@ size_t GetFileSize(const std::string& filename, int* error) { | |||
| 72 | 70 | return result; | |
| 73 | 71 | } | |
| 74 | 72 | ||
| 75 | - bool EndsWith(const std::string& str, std::string_view suffix) { | ||
| 76 | - size_t suffix_len = suffix.length(); | ||
| 77 | - size_t str_len = str.length(); | ||
| 78 | - if (str_len < suffix_len) { | ||
| 79 | - return false; | ||
| 80 | - } | ||
| 81 | - return str.compare(str_len - suffix_len, suffix_len, suffix) == 0; | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - bool StartsWith(const std::string& str, std::string_view prefix) { | ||
| 85 | - size_t prefix_len = prefix.length(); | ||
| 86 | - size_t str_len = str.length(); | ||
| 87 | - if (str_len < prefix_len) { | ||
| 88 | - return false; | ||
| 89 | - } | ||
| 90 | - return str.compare(0, prefix_len, prefix) == 0; | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - bool FilenameIsConfigGypi(const std::string& path) { | ||
| 94 | - return path == "config.gypi" || EndsWith(path, "/config.gypi"); | ||
| 73 | + constexpr bool FilenameIsConfigGypi(const std::string_view path) { | ||
| 74 | + return path == "config.gypi" || path.ends_with("/config.gypi"); | ||
| 95 | 75 | } | |
| 96 | 76 | ||
| 97 | 77 | typedef std::vector<std::string> FileList; | |
| 98 | 78 | typedef std::map<std::string, FileList> FileMap; | |
| 99 | 79 | ||
| 100 | 80 | bool SearchFiles(const std::string& dir, | |
| 101 | 81 | FileMap* file_map, | |
| 102 | - const std::string& extension) { | ||
| 82 | + std::string_view extension) { | ||
| 103 | 83 | uv_fs_t scan_req; | |
| 104 | 84 | int result = uv_fs_scandir(nullptr, &scan_req, dir.c_str(), 0, nullptr); | |
| 105 | 85 | bool errored = false; | |
| 106 | 86 | if (result < 0) { | |
| 107 | 87 | PrintUvError("scandir", dir.c_str(), result); | |
| 108 | 88 | errored = true; | |
| 109 | 89 | } else { | |
| 110 | - auto it = file_map->insert({extension, FileList()}).first; | ||
| 90 | + auto it = file_map->insert({std::string(extension), FileList()}).first; | ||
| 111 | 91 | FileList& files = it->second; | |
| 112 | 92 | files.reserve(files.size() + result); | |
| 113 | 93 | uv_dirent_t dent; | |
@@ -124,7 +104,7 @@ bool SearchFiles(const std::string& dir, | |||
| 124 | 104 | } | |
| 125 | 105 | ||
| 126 | 106 | std::string path = dir + '/' + dent.name; | |
| 127 | - if (EndsWith(path, extension)) { | ||
| 107 | + if (path.ends_with(extension)) { | ||
| 128 | 108 | files.emplace_back(path); | |
| 129 | 109 | continue; | |
| 130 | 110 | } | |
@@ -153,12 +133,11 @@ constexpr std::string_view kJsSuffix = ".js"; | |||
| 153 | 133 | constexpr std::string_view kGypiSuffix = ".gypi"; | |
| 154 | 134 | constexpr std::string_view depsPrefix = "deps/"; | |
| 155 | 135 | constexpr std::string_view libPrefix = "lib/"; | |
| 156 | - std::set<std::string_view> kAllowedExtensions{ | ||
| 157 | - kGypiSuffix, kJsSuffix, kMjsSuffix}; | ||
| 158 | 136 | ||
| 159 | - std::string_view HasAllowedExtensions(const std::string& filename) { | ||
| 160 | - for (const auto& ext : kAllowedExtensions) { | ||
| 161 | - if (EndsWith(filename, ext)) { | ||
| 137 | + constexpr std::string_view HasAllowedExtensions( | ||
| 138 | + const std::string_view filename) { | ||
| 139 | + for (const auto& ext : {kGypiSuffix, kJsSuffix, kMjsSuffix}) { | ||
| 140 | + if (filename.ends_with(ext)) { | ||
| 162 | 141 | return ext; | |
| 163 | 142 | } | |
| 164 | 143 | } | |
@@ -350,17 +329,17 @@ std::string GetFileId(const std::string& filename) { | |||
| 350 | 329 | size_t start = 0; | |
| 351 | 330 | std::string prefix; | |
| 352 | 331 | // Strip .mjs and .js suffix | |
| 353 | - if (EndsWith(filename, kMjsSuffix)) { | ||
| 332 | + if (filename.ends_with(kMjsSuffix)) { | ||
| 354 | 333 | end -= kMjsSuffix.size(); | |
| 355 | - } else if (EndsWith(filename, kJsSuffix)) { | ||
| 334 | + } else if (filename.ends_with(kJsSuffix)) { | ||
| 356 | 335 | end -= kJsSuffix.size(); | |
| 357 | 336 | } | |
| 358 | 337 | ||
| 359 | 338 | // deps/acorn/acorn/dist/acorn.js -> internal/deps/acorn/acorn/dist/acorn | |
| 360 | - if (StartsWith(filename, depsPrefix)) { | ||
| 339 | + if (filename.starts_with(depsPrefix)) { | ||
| 361 | 340 | start = depsPrefix.size(); | |
| 362 | 341 | prefix = "internal/deps/"; | |
| 363 | - } else if (StartsWith(filename, libPrefix)) { | ||
| 342 | + } else if (filename.starts_with(libPrefix)) { | ||
| 364 | 343 | // lib/internal/url.js -> internal/url | |
| 365 | 344 | start = libPrefix.size(); | |
| 366 | 345 | prefix = ""; | |
@@ -381,18 +360,52 @@ std::string GetVariableName(const std::string& id) { | |||
| 381 | 360 | return result; | |
| 382 | 361 | } | |
| 383 | 362 | ||
| 384 | - std::vector<std::string> GetCodeTable() { | ||
| 385 | - size_t size = 1 << 16; | ||
| 386 | - std::vector<std::string> code_table(size); | ||
| 387 | - for (size_t i = 0; i < size; ++i) { | ||
| 388 | - code_table[i] = std::to_string(i) + ','; | ||
| 363 | + // The function returns a string buffer and an array of | ||
| 364 | + // offsets. The string is just "0,1,2,3,...,65535,". | ||
| 365 | + // The second array contain the offsets indicating the | ||
| 366 | + // start of each substring ("0,", "1,", etc.) and the final | ||
| 367 | + // offset points just beyond the end of the string. | ||
| 368 | + // 382106 is the length of the string "0,1,2,3,...,65535,". | ||
| 369 | + // 65537 is 2**16 + 1 | ||
| 370 | + // This function could be constexpr, but it might become too expensive to | ||
| 371 | + // compile. | ||
| 372 | + std::pair<std::array<char, 382106>, std::array<uint32_t, 65537>> | ||
| 373 | + precompute_string() { | ||
| 374 | + // the string "0,1,2,3,...,65535,". | ||
| 375 | + std::array<char, 382106> str; | ||
| 376 | + // the offsets in the string pointing at the beginning of each substring | ||
| 377 | + std::array<uint32_t, 65537> off; | ||
| 378 | + off[0] = 0; | ||
| 379 | + char* p = &str[0]; | ||
| 380 | + constexpr auto const_int_to_str = [](uint16_t value, char* s) -> uint32_t { | ||
| 381 | + uint32_t index = 0; | ||
| 382 | + do { | ||
| 383 | + s[index++] = '0' + (value % 10); | ||
| 384 | + value /= 10; | ||
| 385 | + } while (value != 0); | ||
| 386 | + | ||
| 387 | + for (uint32_t i = 0; i < index / 2; ++i) { | ||
| 388 | + char temp = s[i]; | ||
| 389 | + s[i] = s[index - i - 1]; | ||
| 390 | + s[index - i - 1] = temp; | ||
| 391 | + } | ||
| 392 | + s[index] = ','; | ||
| 393 | + return index + 1; | ||
| 394 | + }; | ||
| 395 | + for (int i = 0; i < 65536; ++i) { | ||
| 396 | + size_t offset = const_int_to_str(i, p); | ||
| 397 | + p += offset; | ||
| 398 | + off[i + 1] = off[i] + offset; | ||
| 389 | 399 | } | |
| 390 | - return code_table; | ||
| 400 | + return {str, off}; | ||
| 391 | 401 | } | |
| 392 | 402 | ||
| 393 | - const std::string& GetCode(uint16_t index) { | ||
| 394 | - static std::vector<std::string> table = GetCodeTable(); | ||
| 395 | - return table[index]; | ||
| 403 | + const std::string_view GetCode(uint16_t index) { | ||
| 404 | + // We use about 644254 bytes of memory. An array of 65536 strings might use | ||
| 405 | + // 2097152 bytes so we save 3x the memory. | ||
| 406 | + static auto [backing_string, offsets] = precompute_string(); | ||
| 407 | + return std::string_view(&backing_string[offsets[index]], | ||
| 408 | + offsets[index + 1] - offsets[index]); | ||
| 396 | 409 | } | |
| 397 | 410 | ||
| 398 | 411 | #ifdef NODE_JS2C_USE_STRING_LITERALS | |
@@ -532,8 +545,7 @@ Fragment GetDefinitionImpl(const std::vector<char>& code, | |||
| 532 | 545 | // Avoid using snprintf on large chunks of data because it's much slower. | |
| 533 | 546 | // It's fine to use it on small amount of data though. | |
| 534 | 547 | if constexpr (is_two_byte) { | |
| 535 | - std::vector<uint16_t> utf16_codepoints; | ||
| 536 | - utf16_codepoints.resize(count); | ||
| 548 | + std::vector<uint16_t> utf16_codepoints(count); | ||
| 537 | 549 | size_t utf16_count = simdutf::convert_utf8_to_utf16( | |
| 538 | 550 | code.data(), | |
| 539 | 551 | code.size(), | |
@@ -542,8 +554,8 @@ Fragment GetDefinitionImpl(const std::vector<char>& code, | |||
| 542 | 554 | utf16_codepoints.resize(utf16_count); | |
| 543 | 555 | Debug("static size %zu\n", utf16_count); | |
| 544 | 556 | for (size_t i = 0; i < utf16_count; ++i) { | |
| 545 | - const std::string& str = GetCode(utf16_codepoints[i]); | ||
| 546 | - memcpy(result.data() + cur, str.c_str(), str.size()); | ||
| 557 | + std::string_view str = GetCode(utf16_codepoints[i]); | ||
| 558 | + memcpy(result.data() + cur, str.data(), str.size()); | ||
| 547 | 559 | cur += str.size(); | |
| 548 | 560 | } | |
| 549 | 561 | } else { | |
@@ -556,8 +568,8 @@ Fragment GetDefinitionImpl(const std::vector<char>& code, | |||
| 556 | 568 | i, | |
| 557 | 569 | ch); | |
| 558 | 570 | } | |
| 559 | - const std::string& str = GetCode(ch); | ||
| 560 | - memcpy(result.data() + cur, str.c_str(), str.size()); | ||
| 571 | + std::string_view str = GetCode(ch); | ||
| 572 | + memcpy(result.data() + cur, str.data(), str.size()); | ||
| 561 | 573 | cur += str.size(); | |
| 562 | 574 | } | |
| 563 | 575 | } | |
@@ -895,8 +907,8 @@ int Main(int argc, char* argv[]) { | |||
| 895 | 907 | int error = 0; | |
| 896 | 908 | const std::string& file = args[i]; | |
| 897 | 909 | if (IsDirectory(file, &error)) { | |
| 898 | - if (!SearchFiles(file, &file_map, std::string(kJsSuffix)) || | ||
| 899 | - !SearchFiles(file, &file_map, std::string(kMjsSuffix))) { | ||
| 910 | + if (!SearchFiles(file, &file_map, kJsSuffix) || | ||
| 911 | + !SearchFiles(file, &file_map, kMjsSuffix)) { | ||
| 900 | 912 | return 1; | |
| 901 | 913 | } | |
| 902 | 914 | } else if (error != 0) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments