From 872e6706ca482a8f053405831b0472d83ae7c20e Mon Sep 17 00:00:00 2001 From: Khafra Date: Thu, 20 Apr 2023 12:16:21 -0400 Subject: [PATCH] src: add v8 fast api for url canParse PR-URL: https://github.com/nodejs/node/pull/47552 Reviewed-By: Yagiz Nizipli Reviewed-By: Mohammed Keyvanzadeh --- src/node_external_reference.h | 3 +++ src/node_url.cc | 22 +++++++++++++++++++--- src/node_url.h | 7 +++++++ test/parallel/test-url-canParse-whatwg.js | 7 +++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/node_external_reference.h b/src/node_external_reference.h index b2a90ba5194316..85acbc114143da 100644 --- a/src/node_external_reference.h +++ b/src/node_external_reference.h @@ -19,6 +19,8 @@ using CFunctionCallbackWithInt64 = void (*)(v8::Local receiver, int64_t); using CFunctionCallbackWithBool = void (*)(v8::Local receiver, bool); +using CFunctionCallbackWithStrings = + bool (*)(v8::Local, const v8::FastOneByteString& input); // This class manages the external references from the V8 heap // to the C++ addresses in Node.js. @@ -32,6 +34,7 @@ class ExternalReferenceRegistry { V(CFunctionCallbackReturnDouble) \ V(CFunctionCallbackWithInt64) \ V(CFunctionCallbackWithBool) \ + V(CFunctionCallbackWithStrings) \ V(const v8::CFunctionInfo*) \ V(v8::FunctionCallback) \ V(v8::AccessorGetterCallback) \ diff --git a/src/node_url.cc b/src/node_url.cc index 1cb0a5fd210f36..e8df2796261dd0 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -5,6 +5,7 @@ #include "node_external_reference.h" #include "node_i18n.h" #include "util-inl.h" +#include "v8-fast-api-calls.h" #include "v8.h" #include @@ -14,7 +15,9 @@ namespace node { namespace url { +using v8::CFunction; using v8::Context; +using v8::FastOneByteString; using v8::FunctionCallbackInfo; using v8::HandleScope; using v8::Isolate; @@ -113,7 +116,6 @@ void BindingData::DomainToUnicode(const FunctionCallbackInfo& args) { .ToLocalChecked()); } -// TODO(@anonrig): Add V8 Fast API for CanParse method void BindingData::CanParse(const FunctionCallbackInfo& args) { CHECK_GE(args.Length(), 1); CHECK(args[0]->IsString()); // input @@ -140,6 +142,17 @@ void BindingData::CanParse(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(out.has_value()); } +bool BindingData::FastCanParse(Local receiver, + const FastOneByteString& input) { + std::string_view input_view(input.data, input.length); + + auto output = ada::parse(input_view); + + return output.has_value(); +} + +CFunction BindingData::fast_can_parse_(CFunction::Make(FastCanParse)); + void BindingData::Format(const FunctionCallbackInfo& args) { CHECK_GT(args.Length(), 4); CHECK(args[0]->IsString()); // url href @@ -320,20 +333,23 @@ void BindingData::Initialize(Local target, SetMethodNoSideEffect(context, target, "domainToASCII", DomainToASCII); SetMethodNoSideEffect(context, target, "domainToUnicode", DomainToUnicode); - SetMethodNoSideEffect(context, target, "canParse", CanParse); SetMethodNoSideEffect(context, target, "format", Format); SetMethod(context, target, "parse", Parse); SetMethod(context, target, "update", Update); + SetFastMethodNoSideEffect( + context, target, "canParse", CanParse, &fast_can_parse_); } void BindingData::RegisterExternalReferences( ExternalReferenceRegistry* registry) { registry->Register(DomainToASCII); registry->Register(DomainToUnicode); - registry->Register(CanParse); registry->Register(Format); registry->Register(Parse); registry->Register(Update); + registry->Register(CanParse); + registry->Register(FastCanParse); + registry->Register(fast_can_parse_.GetTypeInfo()); } std::string FromFilePath(const std::string_view file_path) { diff --git a/src/node_url.h b/src/node_url.h index ed68fe51fb4d10..735a191e5eac16 100644 --- a/src/node_url.h +++ b/src/node_url.h @@ -9,6 +9,8 @@ #include "node.h" #include "node_snapshotable.h" #include "util.h" +#include "v8-fast-api-calls.h" +#include "v8.h" #include @@ -47,6 +49,9 @@ class BindingData : public SnapshotableObject { static void DomainToUnicode(const v8::FunctionCallbackInfo& args); static void CanParse(const v8::FunctionCallbackInfo& args); + static bool FastCanParse(v8::Local receiver, + const v8::FastOneByteString& input); + static void Format(const v8::FunctionCallbackInfo& args); static void Parse(const v8::FunctionCallbackInfo& args); static void Update(const v8::FunctionCallbackInfo& args); @@ -63,6 +68,8 @@ class BindingData : public SnapshotableObject { void UpdateComponents(const ada::url_components& components, const ada::scheme::type type); + + static v8::CFunction fast_can_parse_; }; std::string FromFilePath(const std::string_view file_path); diff --git a/test/parallel/test-url-canParse-whatwg.js b/test/parallel/test-url-canParse-whatwg.js index 7f7d5d40aa7a28..d5ffee7053a716 100644 --- a/test/parallel/test-url-canParse-whatwg.js +++ b/test/parallel/test-url-canParse-whatwg.js @@ -10,3 +10,10 @@ assert.throws(() => { code: 'ERR_MISSING_ARGS', name: 'TypeError', }); + +{ + // This test is to ensure that the v8 fast api works. + for (let i = 0; i < 1e5; i++) { + assert(URL.canParse('https://www.example.com/path/?query=param#hash')); + } +}