| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -127,7 +127,6 @@ static void Has(const FunctionCallbackInfo<Value>& args) { | |||
| 127 | 127 | ||
| 128 | 128 | static bool FastHas(Local<Value> receiver, | |
| 129 | 129 | Local<Value> scope_arg, | |
| 130 | - Local<Value> resource_arg, | ||
| 131 | 130 | // NOLINTNEXTLINE(runtime/references) This is V8 api. | |
| 132 | 131 | FastApiCallbackOptions& options) { | |
| 133 | 132 | TRACK_V8_FAST_API_CALL("permission.has"); | |
@@ -148,8 +147,31 @@ static bool FastHas(Local<Value> receiver, | |||
| 148 | 147 | return false; | |
| 149 | 148 | } | |
| 150 | 149 | ||
| 151 | - if (resource_arg->IsUndefined()) { | ||
| 152 | - return env->permission()->is_granted(env, scope); | ||
| 150 | + return env->permission()->is_granted(env, scope); | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + static bool FastHasResource( | ||
| 154 | + Local<Value> receiver, | ||
| 155 | + Local<Value> scope_arg, | ||
| 156 | + Local<Value> resource_arg, | ||
| 157 | + // NOLINTNEXTLINE(runtime/references) This is V8 api. | ||
| 158 | + FastApiCallbackOptions& options) { | ||
| 159 | + TRACK_V8_FAST_API_CALL("permission.has"); | ||
| 160 | + auto isolate = options.isolate; | ||
| 161 | + v8::HandleScope handle_scope(isolate); | ||
| 162 | + auto context = isolate->GetCurrentContext(); | ||
| 163 | + | ||
| 164 | + Environment* env = Environment::GetCurrent(context); | ||
| 165 | + | ||
| 166 | + Local<String> str; | ||
| 167 | + if (!scope_arg->ToString(context).ToLocal(&str)) { | ||
| 168 | + return false; | ||
| 169 | + } | ||
| 170 | + Utf8Value utf8_scope(isolate, str); | ||
| 171 | + PermissionScope scope = | ||
| 172 | + Permission::StringToPermission(utf8_scope.ToStringView()); | ||
| 173 | + if (scope == PermissionScope::kPermissionsRoot) { | ||
| 174 | + return false; | ||
| 153 | 175 | } | |
| 154 | 176 | ||
| 155 | 177 | Local<String> res_str; | |
@@ -164,7 +186,8 @@ static bool FastHas(Local<Value> receiver, | |||
| 164 | 186 | return env->permission()->is_granted(env, scope, utf8_res.ToStringView()); | |
| 165 | 187 | } | |
| 166 | 188 | ||
| 167 | - static CFunction fast_has_(CFunction::Make(FastHas)); | ||
| 189 | + static CFunction fast_has_methods_[] = {CFunction::Make(FastHas), | ||
| 190 | + CFunction::Make(FastHasResource)}; | ||
| 168 | 191 | ||
| 169 | 192 | } // namespace | |
| 170 | 193 | ||
@@ -370,15 +393,18 @@ void Initialize(Local<Object> target, | |||
| 370 | 393 | Local<Value> unused, | |
| 371 | 394 | Local<Context> context, | |
| 372 | 395 | void* priv) { | |
| 373 | - SetFastMethodNoSideEffect(context, target, "has", Has, &fast_has_); | ||
| 396 | + SetFastMethodNoSideEffect( | ||
| 397 | + context, target, "has", Has, {fast_has_methods_, 2}); | ||
| 374 | 398 | SetMethod(context, target, "drop", Drop); | |
| 375 | 399 | ||
| 376 | 400 | target->SetIntegrityLevel(context, IntegrityLevel::kFrozen).FromJust(); | |
| 377 | 401 | } | |
| 378 | 402 | ||
| 379 | 403 | void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |
| 380 | 404 | registry->Register(Has); | |
| 381 | - registry->Register(fast_has_); | ||
| 405 | + for (const CFunction& method : fast_has_methods_) { | ||
| 406 | + registry->Register(method); | ||
| 407 | + } | ||
| 382 | 408 | registry->Register(Drop); | |
| 383 | 409 | } | |
| 384 | 410 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -468,6 +468,31 @@ void SetFastMethodNoSideEffect( | |||
| 468 | 468 | that->Set(name_string, t); | |
| 469 | 469 | } | |
| 470 | 470 | ||
| 471 | + void SetFastMethodNoSideEffect( | ||
| 472 | + Local<v8::Context> context, | ||
| 473 | + Local<v8::Object> that, | ||
| 474 | + const std::string_view name, | ||
| 475 | + v8::FunctionCallback slow_callback, | ||
| 476 | + const v8::MemorySpan<const v8::CFunction>& methods) { | ||
| 477 | + Isolate* isolate = Isolate::GetCurrent(); | ||
| 478 | + Local<v8::Function> function = FunctionTemplate::NewWithCFunctionOverloads( | ||
| 479 | + isolate, | ||
| 480 | + slow_callback, | ||
| 481 | + Local<Value>(), | ||
| 482 | + Local<v8::Signature>(), | ||
| 483 | + 0, | ||
| 484 | + v8::ConstructorBehavior::kThrow, | ||
| 485 | + v8::SideEffectType::kHasNoSideEffect, | ||
| 486 | + methods) | ||
| 487 | + ->GetFunction(context) | ||
| 488 | + .ToLocalChecked(); | ||
| 489 | + const v8::NewStringType type = v8::NewStringType::kInternalized; | ||
| 490 | + Local<v8::String> name_string = | ||
| 491 | + v8::String::NewFromUtf8(isolate, name.data(), type, name.size()) | ||
| 492 | + .ToLocalChecked(); | ||
| 493 | + that->Set(context, name_string, function).Check(); | ||
| 494 | + } | ||
| 495 | + | ||
| 471 | 496 | void SetMethodNoSideEffect(Local<v8::Context> context, | |
| 472 | 497 | Local<v8::Object> that, | |
| 473 | 498 | const std::string_view name, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -912,6 +912,12 @@ void SetFastMethodNoSideEffect( | |||
| 912 | 912 | const std::string_view name, | |
| 913 | 913 | v8::FunctionCallback slow_callback, | |
| 914 | 914 | const v8::MemorySpan<const v8::CFunction>& methods); | |
| 915 | + void SetFastMethodNoSideEffect( | ||
| 916 | + v8::Local<v8::Context> context, | ||
| 917 | + v8::Local<v8::Object> that, | ||
| 918 | + const std::string_view name, | ||
| 919 | + v8::FunctionCallback slow_callback, | ||
| 920 | + const v8::MemorySpan<const v8::CFunction>& methods); | ||
| 915 | 921 | void SetProtoMethod(v8::Isolate* isolate, | |
| 916 | 922 | v8::Local<v8::FunctionTemplate> that, | |
| 917 | 923 | const std::string_view name, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,38 @@ | |||
| 1 | + // Flags: --permission --allow-fs-read=* --allow-fs-write=* --allow-natives-syntax --expose-internals --no-warnings | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + const common = require('../common'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + const { internalBinding } = require('internal/test/binding'); | ||
| 7 | + const path = require('path'); | ||
| 8 | + | ||
| 9 | + // Test that process.permission.has() uses the V8 fast API path. | ||
| 10 | + | ||
| 11 | + // Test with scope only (no resource argument). | ||
| 12 | + function testHasScope() { | ||
| 13 | + assert.strictEqual(process.permission.has('fs.read', __filename), true); | ||
| 14 | + assert.strictEqual(process.permission.has('fs.write', __dirname), true); | ||
| 15 | + assert.strictEqual( | ||
| 16 | + process.permission.has('fs.read', path.resolve('/nonexistent')), | ||
| 17 | + true | ||
| 18 | + ); | ||
| 19 | + assert.strictEqual(process.permission.has('fs.read'), true); | ||
| 20 | + assert.strictEqual(process.permission.has('fs.write'), true); | ||
| 21 | + assert.strictEqual(process.permission.has('child'), false); | ||
| 22 | + assert.strictEqual(process.permission.has('worker'), false); | ||
| 23 | + assert.strictEqual(process.permission.has('invalid-key'), false); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + // Warm up and optimize for the fast API path. | ||
| 27 | + eval('%PrepareFunctionForOptimization(testHasScope)'); | ||
| 28 | + testHasScope(); | ||
| 29 | + testHasScope(); | ||
| 30 | + | ||
| 31 | + eval('%OptimizeFunctionOnNextCall(testHasScope)'); | ||
| 32 | + testHasScope(); | ||
| 33 | + | ||
| 34 | + if (common.isDebug) { | ||
| 35 | + const { getV8FastApiCallCount } = internalBinding('debug'); | ||
| 36 | + // After optimization: testHasScope = 4, testHasResource = 3, testHasInvalid = 1 | ||
| 37 | + assert.strictEqual(getV8FastApiCallCount('permission.has'), 8); | ||
| 38 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments