Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions src/node_blob.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
#include "env-inl.h"
#include "memory_tracker-inl.h"
#include "node_bob-inl.h"
#include "node_debug.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_file.h"
#include "path.h"
#include "permission/permission.h"
#include "util.h"
#include "v8-fast-api-calls.h"
#include "v8-value.h"
#include "v8.h"

#include <algorithm>
Expand All @@ -22,7 +25,9 @@ using v8::ArrayBuffer;
using v8::ArrayBufferView;
using v8::BackingStore;
using v8::BackingStoreInitializationMode;
using v8::CFunction;
using v8::Context;
using v8::FastApiCallbackOptions;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
Expand Down Expand Up @@ -130,7 +135,11 @@ void Blob::CreatePerIsolateProperties(IsolateData* isolate_data,
SetMethod(isolate, target, "createBlob", New);
SetMethod(isolate, target, "storeDataObject", StoreDataObject);
SetMethod(isolate, target, "getDataObject", GetDataObject);
SetMethod(isolate, target, "revokeObjectURL", RevokeObjectURL);
SetFastMethod(isolate,
target,
"revokeObjectURL",
RevokeObjectURL,
&fast_revoke_object_url_method);
SetMethod(isolate, target, "concat", Concat);
SetMethod(isolate, target, "createBlobFromFilePath", BlobFromFilePath);
}
Expand Down Expand Up @@ -450,15 +459,11 @@ void Blob::StoreDataObject(const FunctionCallbackInfo<Value>& args) {
std::string(*type, type.length())));
}

// TODO(@anonrig): Add V8 Fast API to the following function
void Blob::RevokeObjectURL(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1);
CHECK(args[0]->IsString());
Realm* realm = Realm::GetCurrent(args);
void RevokeObjectURLImpl(Realm* realm, Local<String> input_str) {
BlobBindingData* binding_data = realm->GetBindingData<BlobBindingData>();
Isolate* isolate = realm->isolate();

Utf8Value input(isolate, args[0].As<String>());
Utf8Value input(isolate, input_str);
auto out = ada::parse<ada::url_aggregator>(input.ToStringView());

if (!out) {
Expand All @@ -477,6 +482,27 @@ void Blob::RevokeObjectURL(const FunctionCallbackInfo<Value>& args) {
}
}

void Blob::RevokeObjectURL(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1);
CHECK(args[0]->IsString());
Realm* realm = Realm::GetCurrent(args);
RevokeObjectURLImpl(realm, args[0].As<String>());
}

void Blob::FastRevokeObjectURL(Local<Value> receiver,
Local<Value> raw_input,
FastApiCallbackOptions& options) {
TRACK_V8_FAST_API_CALL("blob.revokeObjectURL");
CHECK(raw_input->IsString());
auto isolate = options.isolate;
HandleScope handleScope(isolate);
Realm* realm = Realm::GetCurrent(isolate->GetCurrentContext());
RevokeObjectURLImpl(realm, raw_input.As<String>());
}

CFunction Blob::fast_revoke_object_url_method =
CFunction::Make(Blob::FastRevokeObjectURL);

void Blob::GetDataObject(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsString());
Realm* realm = Realm::GetCurrent(args);
Expand Down Expand Up @@ -584,9 +610,11 @@ void Blob::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(Blob::StoreDataObject);
registry->Register(Blob::GetDataObject);
registry->Register(Blob::RevokeObjectURL);
registry->Register(Blob::FastRevokeObjectURL);
registry->Register(Blob::Reader::Pull);
registry->Register(Concat);
registry->Register(BlobFromFilePath);
registry->Register(fast_revoke_object_url_method.GetTypeInfo());
}

} // namespace node
Expand Down
15 changes: 11 additions & 4 deletions src/node_blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include "v8-template.h"
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include <string>
#include <unordered_map>
#include <vector>
#include "async_wrap.h"
#include "base_object.h"
#include "dataqueue/queue.h"
Expand All @@ -13,12 +16,9 @@
#include "node_internals.h"
#include "node_snapshotable.h"
#include "node_worker.h"
#include "v8-fast-api-calls.h"
#include "v8.h"

#include <string>
#include <unordered_map>
#include <vector>

namespace node {

class Blob : public BaseObject {
Expand All @@ -39,6 +39,13 @@ class Blob : public BaseObject {
static void StoreDataObject(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetDataObject(const v8::FunctionCallbackInfo<v8::Value>& args);
static void RevokeObjectURL(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FastRevokeObjectURL(
v8::Local<v8::Value> receiver,
v8::Local<v8::Value> raw_input,
// NOLINTNEXTLINE(runtime/references) This is V8 api.
v8::FastApiCallbackOptions& options);

static v8::CFunction fast_revoke_object_url_method;

static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
Environment* env);
Expand Down
8 changes: 6 additions & 2 deletions src/node_external_reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

namespace node {

using CFunctionCallbackWithalueAndOptions = bool (*)(
using CFunctionCallbackWithValueAndOptions = void (*)(
v8::Local<v8::Value>, v8::Local<v8::Value>, v8::FastApiCallbackOptions&);
using CFunctionCallbackWithValueAndOptionsReturnBool = bool (*)(
v8::Local<v8::Value>, v8::Local<v8::Value>, v8::FastApiCallbackOptions&);
using CFunctionCallbackWithMultipleValueAndOptions =
bool (*)(v8::Local<v8::Value>,
Expand Down Expand Up @@ -46,6 +48,7 @@ using CFunctionCallbackWithInt64 = void (*)(v8::Local<v8::Object> unused,
using CFunctionCallbackWithBool = void (*)(v8::Local<v8::Object> unused,
v8::Local<v8::Object> receiver,
bool);

using CFunctionCallbackWithString =
bool (*)(v8::Local<v8::Value>, const v8::FastOneByteString& input);
using CFunctionCallbackWithStrings =
Expand Down Expand Up @@ -103,7 +106,8 @@ class ExternalReferenceRegistry {
#define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \
V(CFunctionA) \
V(CFunctionCallback) \
V(CFunctionCallbackWithalueAndOptions) \
V(CFunctionCallbackWithValueAndOptions) \
V(CFunctionCallbackWithValueAndOptionsReturnBool) \
V(CFunctionCallbackWithMultipleValueAndOptions) \
V(CFunctionCallbackWithOneByteString) \
V(CFunctionCallbackReturnBool) \
Expand Down
32 changes: 32 additions & 0 deletions test/parallel/test-url-revokeobjecturl-fast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Flags: --expose-internals --allow-natives-syntax
'use strict';
const common = require('../common');
const assert = require('node:assert');

const { internalBinding } = require('internal/test/binding');

// Because registering a Blob URL requires generating a random
// UUID, it can only be done if crypto support is enabled.
if (!common.hasCrypto) {
common.skip('missing crypto');
}

const blob = new Blob([JSON.stringify({ hello: 'world' }, null, 2)], {
type: 'application/json',
});

function testFastPath() {
const objURL = URL.createObjectURL(blob);
URL.revokeObjectURL(objURL);
}

eval('%PrepareFunctionForOptimization(URL.revokeObjectURL)');
testFastPath();

eval('%OptimizeFunctionOnNextCall(URL.revokeObjectURL)');
testFastPath();

if (common.isDebug) {
const { getV8FastApiCallCount } = internalBinding('debug');
assert.strictEqual(getV8FastApiCallCount('blob.revokeObjectURL'), 1);
}
Loading