Skip to content

Commit

Permalink
fixup: fast call
Browse files Browse the repository at this point in the history
  • Loading branch information
ronag committed Jul 29, 2024
1 parent ce07761 commit 7328b6f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 13 deletions.
14 changes: 4 additions & 10 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const {
byteLengthUtf8,
compare: _compare,
compareOffset,
copyArrayBuffer,
copy: _copy,
createFromString,
fill: bindingFill,
isAscii: bindingIsAscii,
Expand Down Expand Up @@ -204,7 +204,7 @@ function toInteger(n, defaultVal) {
return defaultVal;
}

function _copy(source, target, targetStart, sourceStart, sourceEnd) {
function copyImpl(source, target, targetStart, sourceStart, sourceEnd) {
if (!isUint8Array(source))
throw new ERR_INVALID_ARG_TYPE('source', ['Buffer', 'Uint8Array'], source);
if (!isUint8Array(target))
Expand Down Expand Up @@ -253,13 +253,7 @@ function _copyActual(source, target, targetStart, sourceStart, sourceEnd) {
return 0;

if (sourceStart !== 0 || sourceEnd < source.length) {
copyArrayBuffer(
target.buffer,
target.byteOffset + targetStart,
source.buffer,
source.byteOffset + sourceStart,
nb,
);
_copy(source, target, targetStart, sourceStart, sourceEnd);
} else {
TypedArrayPrototypeSet(target, source, targetStart);
}
Expand Down Expand Up @@ -816,7 +810,7 @@ ObjectDefineProperty(Buffer.prototype, 'offset', {

Buffer.prototype.copy =
function copy(target, targetStart, sourceStart, sourceEnd) {
return _copy(this, target, targetStart, sourceStart, sourceEnd);
return copyImpl(this, target, targetStart, sourceStart, sourceEnd);
};

// No need to verify that "buf.length <= MAX_UINT32" since it's a read-only
Expand Down
41 changes: 38 additions & 3 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
}

// bytesCopied = copy(buffer, target[, targetStart][, sourceStart][, sourceEnd])
void Copy(const FunctionCallbackInfo<Value> &args) {
void SlowCopy(const FunctionCallbackInfo<Value> &args) {
Environment* env = Environment::GetCurrent(args);

THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
Expand Down Expand Up @@ -606,6 +606,39 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
args.GetReturnValue().Set(to_copy);
}

size_t FastCopy(Local<Value> receiver,
Local<Value> source_obj,
Local<Value> target_obj,
size_t target_start,
size_t source_start,
size_t source_end) {
ArrayBufferViewContents<char> source(source_obj);
SPREAD_BUFFER_ARG(target_obj, target);

// Copy 0 bytes; we're done
if (target_start >= target_length || source_start >= source_end)
return 0;

if (source_start > source.length()) {
// TODO (fix): V8 12.8 allows throwing in fast call.
assert(false);
return 0;
}

if (source_end - source_start > target_length - target_start)
source_end = source_start + target_length - target_start;

uint32_t to_copy = std::min<size_t>(
std::min<size_t>(source_end - source_start, target_length - target_start),
source.length() - source_start);

memmove(target_data + target_start, source.data() + source_start, to_copy);

return to_copy;
}

static v8::CFunction fast_copy(
v8::CFunction::Make(FastCopy));

void Fill(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Expand Down Expand Up @@ -1275,7 +1308,7 @@ void Initialize(Local<Object> target,
"byteLengthUtf8",
SlowByteLengthUtf8,
&fast_byte_length_utf8);
SetMethod(context, target, "copy", Copy);
SetFastMethod(context, target, "copy", SlowCopy, &fast_copy);
SetMethodNoSideEffect(context, target, "compare", Compare);
SetMethodNoSideEffect(context, target, "compareOffset", CompareOffset);
SetMethod(context, target, "fill", Fill);
Expand Down Expand Up @@ -1334,7 +1367,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(SlowByteLengthUtf8);
registry->Register(fast_byte_length_utf8.GetTypeInfo());
registry->Register(FastByteLengthUtf8);
registry->Register(Copy);
registry->Register(SlowCopy);
registry->Register(fast_copy.GetTypeInfo());
registry->Register(FastCopy);
registry->Register(Compare);
registry->Register(CompareOffset);
registry->Register(Fill);
Expand Down

0 comments on commit 7328b6f

Please sign in to comment.