| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent efb649e commit d4ced88
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,10 +39,8 @@ void FreeRecursivelyNode( | |||
| 39 | 39 | return; | |
| 40 | 40 | } | |
| 41 | 41 | ||
| 42 | - if (node->children.size()) { | ||
| 43 | - for (auto& c : node->children) { | ||
| 44 | - FreeRecursivelyNode(c.second); | ||
| 45 | - } | ||
| 42 | + for (auto& [label, child] : node->children) { | ||
| 43 | + FreeRecursivelyNode(child); | ||
| 46 | 44 | } | |
| 47 | 45 | ||
| 48 | 46 | delete node->wildcard_child; | |
@@ -106,7 +104,7 @@ void PrintTree(const node::permission::FSPermission::RadixTree::Node* node, | |||
| 106 | 104 | node::DebugCategory::PERMISSION_MODEL, "%s%s\n", indent, node->prefix); | |
| 107 | 105 | } | |
| 108 | 106 | ||
| 109 | - if (node->children.size() > 0) { | ||
| 107 | + if (!node->children.empty()) { | ||
| 110 | 108 | size_t count = 0; | |
| 111 | 109 | size_t total = node->children.size(); | |
| 112 | 110 | ||
@@ -120,10 +118,10 @@ void PrintTree(const node::permission::FSPermission::RadixTree::Node* node, | |||
| 120 | 118 | } | |
| 121 | 119 | } | |
| 122 | 120 | ||
| 123 | - for (const auto& pair : node->children) { | ||
| 121 | + for (const auto& [label, child] : node->children) { | ||
| 124 | 122 | count++; | |
| 125 | 123 | bool child_is_last = (count == total); | |
| 126 | - PrintTree(pair.second, depth + 1, next_branch_prefix, child_is_last); | ||
| 124 | + PrintTree(child, depth + 1, next_branch_prefix, child_is_last); | ||
| 127 | 125 | } | |
| 128 | 126 | } | |
| 129 | 127 | } | |
@@ -278,8 +276,8 @@ FSPermission::RadixTree::~RadixTree() { | |||
| 278 | 276 | } | |
| 279 | 277 | ||
| 280 | 278 | void FSPermission::RadixTree::Clear() { | |
| 281 | - for (auto& c : root_node_->children) { | ||
| 282 | - FreeRecursivelyNode(c.second); | ||
| 279 | + for (auto& [label, child] : root_node_->children) { | ||
| 280 | + FreeRecursivelyNode(child); | ||
| 283 | 281 | } | |
| 284 | 282 | root_node_->children.clear(); | |
| 285 | 283 | delete root_node_->wildcard_child; | |
@@ -294,15 +292,14 @@ bool FSPermission::RadixTree::Lookup(std::string_view s, | |||
| 294 | 292 | return when_empty_return; | |
| 295 | 293 | } | |
| 296 | 294 | size_t parent_node_prefix_len = current_node->prefix.length(); | |
| 297 | - const std::string path(s); | ||
| 298 | - auto path_len = path.length(); | ||
| 295 | + auto path_len = s.length(); | ||
| 299 | 296 | ||
| 300 | 297 | while (true) { | |
| 301 | 298 | if (parent_node_prefix_len == path_len && current_node->IsEndNode()) { | |
| 302 | 299 | return true; | |
| 303 | 300 | } | |
| 304 | 301 | ||
| 305 | - auto node = current_node->NextNode(path, parent_node_prefix_len); | ||
| 302 | + auto node = current_node->NextNode(s, parent_node_prefix_len); | ||
| 306 | 303 | if (node == nullptr) { | |
| 307 | 304 | return false; | |
| 308 | 305 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | 6 | #include "v8.h" | |
| 7 | 7 | ||
| 8 | - #include <unordered_map> | ||
| 8 | + #include <vector> | ||
| 9 | 9 | #include "permission/permission_base.h" | |
| 10 | 10 | #include "util.h" | |
| 11 | 11 | ||
@@ -28,16 +28,30 @@ class FSPermission final : public PermissionBase { | |||
| 28 | 28 | struct RadixTree { | |
| 29 | 29 | struct Node { | |
| 30 | 30 | std::string prefix; | |
| 31 | - std::unordered_map<char, Node*> children; | ||
| 32 | - Node* wildcard_child; | ||
| 33 | - bool is_leaf; | ||
| 31 | + std::vector<std::pair<char, Node*>> children; | ||
| 32 | + Node* wildcard_child = nullptr; | ||
| 33 | + bool is_leaf = false; | ||
| 34 | 34 | ||
| 35 | - explicit Node(const std::string& pre) | ||
| 36 | - : prefix(pre), wildcard_child(nullptr), is_leaf(false) {} | ||
| 35 | + explicit Node(std::string_view pre) | ||
| 36 | + : prefix(pre) {} | ||
| 37 | 37 | ||
| 38 | - Node() : wildcard_child(nullptr), is_leaf(false) {} | ||
| 38 | + Node() = default; | ||
| 39 | 39 | ||
| 40 | - Node* CreateChild(const std::string& path_prefix) { | ||
| 40 | + Node* FindChild(char label) const { | ||
| 41 | + for (const auto& [c, node] : children) { | ||
| 42 | + if (c == label) return node; | ||
| 43 | + } | ||
| 44 | + return nullptr; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + void SetChild(char label, Node* node) { | ||
| 48 | + for (auto& [c, n] : children) { | ||
| 49 | + if (c == label) { n = node; return; } | ||
| 50 | + } | ||
| 51 | + children.emplace_back(label, node); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + Node* CreateChild(std::string_view path_prefix) { | ||
| 41 | 55 | if (path_prefix.empty() && !is_leaf) { | |
| 42 | 56 | is_leaf = true; | |
| 43 | 57 | return this; | |
@@ -46,10 +60,11 @@ class FSPermission final : public PermissionBase { | |||
| 46 | 60 | CHECK(!path_prefix.empty()); | |
| 47 | 61 | char label = path_prefix[0]; | |
| 48 | 62 | ||
| 49 | - Node* child = children[label]; | ||
| 63 | + Node* child = FindChild(label); | ||
| 50 | 64 | if (child == nullptr) { | |
| 51 | - children[label] = new Node(path_prefix); | ||
| 52 | - return children[label]; | ||
| 65 | + child = new Node(path_prefix); | ||
| 66 | + children.emplace_back(label, child); | ||
| 67 | + return child; | ||
| 53 | 68 | } | |
| 54 | 69 | bool child_was_end_node = child->IsEndNode(); | |
| 55 | 70 | ||
@@ -58,13 +73,13 @@ class FSPermission final : public PermissionBase { | |||
| 58 | 73 | size_t prefix_len = path_prefix.length(); | |
| 59 | 74 | for (; i < child->prefix.length(); ++i) { | |
| 60 | 75 | if (i >= prefix_len || path_prefix[i] != child->prefix[i]) { | |
| 61 | - std::string parent_prefix = child->prefix.substr(0, i); | ||
| 62 | - std::string child_prefix = child->prefix.substr(i); | ||
| 76 | + std::string parent_prefix(child->prefix.substr(0, i)); | ||
| 77 | + std::string child_prefix(child->prefix.substr(i)); | ||
| 63 | 78 | ||
| 64 | 79 | child->prefix = child_prefix; | |
| 65 | 80 | Node* split_child = new Node(parent_prefix); | |
| 66 | - split_child->children[child_prefix[0]] = child; | ||
| 67 | - children[parent_prefix[0]] = split_child; | ||
| 81 | + split_child->children.emplace_back(child_prefix[0], child); | ||
| 82 | + SetChild(parent_prefix[0], split_child); | ||
| 68 | 83 | ||
| 69 | 84 | return split_child->CreateChild(path_prefix.substr(i)); | |
| 70 | 85 | } | |
@@ -83,24 +98,23 @@ class FSPermission final : public PermissionBase { | |||
| 83 | 98 | return wildcard_child; | |
| 84 | 99 | } | |
| 85 | 100 | ||
| 86 | - Node* NextNode(const std::string& path, size_t idx) const { | ||
| 101 | + Node* NextNode(std::string_view path, size_t idx) const { | ||
| 87 | 102 | if (idx >= path.length()) { | |
| 88 | 103 | return nullptr; | |
| 89 | 104 | } | |
| 90 | 105 | ||
| 91 | 106 | // wildcard node takes precedence | |
| 92 | 107 | if (children.size() > 1) { | |
| 93 | - auto it = children.find('*'); | ||
| 94 | - if (it != children.end()) { | ||
| 95 | - return it->second; | ||
| 108 | + Node* wc = FindChild('*'); | ||
| 109 | + if (wc != nullptr) { | ||
| 110 | + return wc; | ||
| 96 | 111 | } | |
| 97 | 112 | } | |
| 98 | 113 | ||
| 99 | - auto it = children.find(path[idx]); | ||
| 100 | - if (it == children.end()) { | ||
| 114 | + Node* child = FindChild(path[idx]); | ||
| 115 | + if (child == nullptr) { | ||
| 101 | 116 | return nullptr; | |
| 102 | 117 | } | |
| 103 | - auto child = it->second; | ||
| 104 | 118 | // match prefix | |
| 105 | 119 | size_t prefix_len = child->prefix.length(); | |
| 106 | 120 | for (size_t i = 0; i < path.length(); ++i) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,12 +3,14 @@ | |||
| 3 | 3 | #include "env-inl.h" | |
| 4 | 4 | #include "memory_tracker-inl.h" | |
| 5 | 5 | #include "node.h" | |
| 6 | + #include "node_debug.h" | ||
| 6 | 7 | #include "node_diagnostics_channel.h" | |
| 7 | 8 | #include "node_errors.h" | |
| 8 | 9 | #include "node_external_reference.h" | |
| 9 | 10 | #include "node_file.h" | |
| 10 | 11 | ||
| 11 | 12 | #include "permission/permission_base.h" | |
| 13 | + #include "v8-fast-api-calls.h" | ||
| 12 | 14 | #include "v8-template.h" | |
| 13 | 15 | #include "v8.h" | |
| 14 | 16 | ||
@@ -18,13 +20,16 @@ | |||
| 18 | 20 | ||
| 19 | 21 | namespace node { | |
| 20 | 22 | ||
| 23 | + using v8::CFunction; | ||
| 21 | 24 | using v8::Context; | |
| 22 | 25 | using v8::DictionaryTemplate; | |
| 26 | + using v8::FastApiCallbackOptions; | ||
| 23 | 27 | using v8::FunctionCallbackInfo; | |
| 24 | 28 | using v8::IntegrityLevel; | |
| 25 | 29 | using v8::Local; | |
| 26 | 30 | using v8::MaybeLocal; | |
| 27 | 31 | using v8::Object; | |
| 32 | + using v8::String; | ||
| 28 | 33 | using v8::Undefined; | |
| 29 | 34 | using v8::Value; | |
| 30 | 35 | ||
@@ -121,6 +126,47 @@ static void Has(const FunctionCallbackInfo<Value>& args) { | |||
| 121 | 126 | return args.GetReturnValue().Set(env->permission()->is_granted(env, scope)); | |
| 122 | 127 | } | |
| 123 | 128 | ||
| 129 | + static bool FastHas(Local<Value> receiver, | ||
| 130 | + Local<Value> scope_arg, | ||
| 131 | + Local<Value> resource_arg, | ||
| 132 | + // NOLINTNEXTLINE(runtime/references) This is V8 api. | ||
| 133 | + FastApiCallbackOptions& options) { | ||
| 134 | + TRACK_V8_FAST_API_CALL("permission.has"); | ||
| 135 | + auto isolate = options.isolate; | ||
| 136 | + v8::HandleScope handle_scope(isolate); | ||
| 137 | + auto context = isolate->GetCurrentContext(); | ||
| 138 | + | ||
| 139 | + Environment* env = Environment::GetCurrent(context); | ||
| 140 | + | ||
| 141 | + Local<String> str; | ||
| 142 | + if (!scope_arg->ToString(context).ToLocal(&str)) { | ||
| 143 | + return false; | ||
| 144 | + } | ||
| 145 | + Utf8Value utf8_scope(isolate, str); | ||
| 146 | + PermissionScope scope = | ||
| 147 | + Permission::StringToPermission(utf8_scope.ToStringView()); | ||
| 148 | + if (scope == PermissionScope::kPermissionsRoot) { | ||
| 149 | + return false; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + if (resource_arg->IsUndefined()) { | ||
| 153 | + return env->permission()->is_granted(env, scope); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + Local<String> res_str; | ||
| 157 | + if (!resource_arg->ToString(context).ToLocal(&res_str)) { | ||
| 158 | + return false; | ||
| 159 | + } | ||
| 160 | + Utf8Value utf8_res(isolate, res_str); | ||
| 161 | + if (utf8_res.length() == 0) { | ||
| 162 | + return false; | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + return env->permission()->is_granted(env, scope, utf8_res.ToStringView()); | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + static CFunction fast_has_(CFunction::Make(FastHas)); | ||
| 169 | + | ||
| 124 | 170 | } // namespace | |
| 125 | 171 | ||
| 126 | 172 | #define V(Name, label, _, __) \ | |
@@ -349,14 +395,15 @@ void Initialize(Local<Object> target, | |||
| 349 | 395 | Local<Value> unused, | |
| 350 | 396 | Local<Context> context, | |
| 351 | 397 | void* priv) { | |
| 352 | - SetMethodNoSideEffect(context, target, "has", Has); | ||
| 398 | + SetFastMethodNoSideEffect(context, target, "has", Has, &fast_has_); | ||
| 353 | 399 | SetMethod(context, target, "drop", Drop); | |
| 354 | 400 | ||
| 355 | 401 | target->SetIntegrityLevel(context, IntegrityLevel::kFrozen).FromJust(); | |
| 356 | 402 | } | |
| 357 | 403 | ||
| 358 | 404 | void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |
| 359 | 405 | registry->Register(Has); | |
| 406 | + registry->Register(fast_has_); | ||
| 360 | 407 | registry->Register(Drop); | |
| 361 | 408 | } | |
| 362 | 409 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments