Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 255f017

Browse filesBrowse files
joyeecheungBridgeAR
authored andcommitted
buffer: move initialization of buffer prototype into node.js
Instead of exposing it in `lib/internal/buffer.js` after deleting it from the binding and then do the initialization in `lib/buffer.js`, which results in an implicit dependency on the order in which these modules are loaded. PR-URL: #25292 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 42fc754 commit 255f017
Copy full SHA for 255f017

File tree

Expand file treeCollapse file tree

5 files changed

+69
-47
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+69
-47
lines changed
Open diff view settings
Collapse file

‎lib/buffer.js‎

Copy file name to clipboardExpand all lines: lib/buffer.js
+32-8Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,22 @@ const {
3535
swap32: _swap32,
3636
swap64: _swap64,
3737
kMaxLength,
38-
kStringMaxLength
38+
kStringMaxLength,
39+
zeroFill: bindingZeroFill,
40+
41+
// Additional Buffer methods
42+
asciiSlice,
43+
base64Slice,
44+
latin1Slice,
45+
hexSlice,
46+
ucs2Slice,
47+
utf8Slice,
48+
asciiWrite,
49+
base64Write,
50+
latin1Write,
51+
hexWrite,
52+
ucs2Write,
53+
utf8Write
3954
} = internalBinding('buffer');
4055
const {
4156
getOwnNonIndexProperties,
@@ -75,10 +90,6 @@ const { validateString } = require('internal/validators');
7590

7691
const internalBuffer = require('internal/buffer');
7792

78-
const { setupBufferJS } = internalBuffer;
79-
80-
const bindingObj = {};
81-
8293
class FastBuffer extends Uint8Array {}
8394
FastBuffer.prototype.constructor = Buffer;
8495
internalBuffer.FastBuffer = FastBuffer;
@@ -89,6 +100,19 @@ for (const [name, method] of Object.entries(internalBuffer.readWrites)) {
89100
Buffer.prototype[name] = method;
90101
}
91102

103+
Buffer.prototype.asciiSlice = asciiSlice;
104+
Buffer.prototype.base64Slice = base64Slice;
105+
Buffer.prototype.latin1Slice = latin1Slice;
106+
Buffer.prototype.hexSlice = hexSlice;
107+
Buffer.prototype.ucs2Slice = ucs2Slice;
108+
Buffer.prototype.utf8Slice = utf8Slice;
109+
Buffer.prototype.asciiWrite = asciiWrite;
110+
Buffer.prototype.base64Write = base64Write;
111+
Buffer.prototype.latin1Write = latin1Write;
112+
Buffer.prototype.hexWrite = hexWrite;
113+
Buffer.prototype.ucs2Write = ucs2Write;
114+
Buffer.prototype.utf8Write = utf8Write;
115+
92116
const constants = Object.defineProperties({}, {
93117
MAX_LENGTH: {
94118
value: kMaxLength,
@@ -105,11 +129,11 @@ const constants = Object.defineProperties({}, {
105129
Buffer.poolSize = 8 * 1024;
106130
let poolSize, poolOffset, allocPool;
107131

108-
setupBufferJS(Buffer.prototype, bindingObj);
109-
132+
// A toggle used to access the zero fill setting of the array buffer allocator
133+
// in C++.
110134
// |zeroFill| can be undefined when running inside an isolate where we
111135
// do not own the ArrayBuffer allocator. Zero fill is always on in that case.
112-
const zeroFill = bindingObj.zeroFill || [0];
136+
const zeroFill = bindingZeroFill || [0];
113137

114138
function createUnsafeBuffer(size) {
115139
return new FastBuffer(createUnsafeArrayBuffer(size));
Collapse file

‎lib/internal/bootstrap/node.js‎

Copy file name to clipboardExpand all lines: lib/internal/bootstrap/node.js
+8-4Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -653,11 +653,15 @@ function setupGlobalVariables() {
653653
}
654654
});
655655

656-
// This, as side effect, removes `setupBufferJS` from the buffer binding,
657-
// and exposes it on `internal/buffer`.
658-
NativeModule.require('internal/buffer');
656+
const { Buffer } = NativeModule.require('buffer');
657+
const bufferBinding = internalBinding('buffer');
659658

660-
global.Buffer = NativeModule.require('buffer').Buffer;
659+
// Only after this point can C++ use Buffer::New()
660+
bufferBinding.setBufferPrototype(Buffer.prototype);
661+
delete bufferBinding.setBufferPrototype;
662+
delete bufferBinding.zeroFill;
663+
664+
global.Buffer = Buffer;
661665
process.domain = null;
662666
process._exiting = false;
663667
}
Collapse file

‎lib/internal/buffer.js‎

Copy file name to clipboardExpand all lines: lib/internal/buffer.js
-7Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
'use strict';
22

3-
const binding = internalBinding('buffer');
43
const {
54
ERR_BUFFER_OUT_OF_BOUNDS,
65
ERR_INVALID_ARG_TYPE,
76
ERR_OUT_OF_RANGE
87
} = require('internal/errors').codes;
98
const { validateNumber } = require('internal/validators');
10-
const { setupBufferJS } = binding;
11-
12-
// Remove from the binding so that function is only available as exported here.
13-
// (That is, for internal use only.)
14-
delete binding.setupBufferJS;
159

1610
// Temporary buffers to convert numbers.
1711
const float32Array = new Float32Array(1);
@@ -779,7 +773,6 @@ function writeFloatBackwards(val, offset = 0) {
779773

780774
// FastBuffer wil be inserted here by lib/buffer.js
781775
module.exports = {
782-
setupBufferJS,
783776
// Container to export all read write functions.
784777
readWrites: {
785778
readUIntLE,
Collapse file

‎src/node_buffer.cc‎

Copy file name to clipboardExpand all lines: src/node_buffer.cc
+28-28Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,38 +1055,12 @@ static void EncodeUtf8String(const FunctionCallbackInfo<Value>& args) {
10551055
}
10561056

10571057

1058-
// pass Buffer object to load prototype methods
1059-
void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
1058+
void SetBufferPrototype(const FunctionCallbackInfo<Value>& args) {
10601059
Environment* env = Environment::GetCurrent(args);
10611060

10621061
CHECK(args[0]->IsObject());
10631062
Local<Object> proto = args[0].As<Object>();
10641063
env->set_buffer_prototype_object(proto);
1065-
1066-
env->SetMethodNoSideEffect(proto, "asciiSlice", StringSlice<ASCII>);
1067-
env->SetMethodNoSideEffect(proto, "base64Slice", StringSlice<BASE64>);
1068-
env->SetMethodNoSideEffect(proto, "latin1Slice", StringSlice<LATIN1>);
1069-
env->SetMethodNoSideEffect(proto, "hexSlice", StringSlice<HEX>);
1070-
env->SetMethodNoSideEffect(proto, "ucs2Slice", StringSlice<UCS2>);
1071-
env->SetMethodNoSideEffect(proto, "utf8Slice", StringSlice<UTF8>);
1072-
1073-
env->SetMethod(proto, "asciiWrite", StringWrite<ASCII>);
1074-
env->SetMethod(proto, "base64Write", StringWrite<BASE64>);
1075-
env->SetMethod(proto, "latin1Write", StringWrite<LATIN1>);
1076-
env->SetMethod(proto, "hexWrite", StringWrite<HEX>);
1077-
env->SetMethod(proto, "ucs2Write", StringWrite<UCS2>);
1078-
env->SetMethod(proto, "utf8Write", StringWrite<UTF8>);
1079-
1080-
if (auto zero_fill_field = env->isolate_data()->zero_fill_field()) {
1081-
CHECK(args[1]->IsObject());
1082-
auto binding_object = args[1].As<Object>();
1083-
auto array_buffer = ArrayBuffer::New(env->isolate(),
1084-
zero_fill_field,
1085-
sizeof(*zero_fill_field));
1086-
auto name = FIXED_ONE_BYTE_STRING(env->isolate(), "zeroFill");
1087-
auto value = Uint32Array::New(array_buffer, 0, 1);
1088-
CHECK(binding_object->Set(env->context(), name, value).FromJust());
1089-
}
10901064
}
10911065

10921066

@@ -1096,7 +1070,7 @@ void Initialize(Local<Object> target,
10961070
void* priv) {
10971071
Environment* env = Environment::GetCurrent(context);
10981072

1099-
env->SetMethod(target, "setupBufferJS", SetupBufferJS);
1073+
env->SetMethod(target, "setBufferPrototype", SetBufferPrototype);
11001074
env->SetMethodNoSideEffect(target, "createFromString", CreateFromString);
11011075

11021076
env->SetMethodNoSideEffect(target, "byteLengthUtf8", ByteLengthUtf8);
@@ -1121,6 +1095,32 @@ void Initialize(Local<Object> target,
11211095
target->Set(env->context(),
11221096
FIXED_ONE_BYTE_STRING(env->isolate(), "kStringMaxLength"),
11231097
Integer::New(env->isolate(), String::kMaxLength)).FromJust();
1098+
1099+
env->SetMethodNoSideEffect(target, "asciiSlice", StringSlice<ASCII>);
1100+
env->SetMethodNoSideEffect(target, "base64Slice", StringSlice<BASE64>);
1101+
env->SetMethodNoSideEffect(target, "latin1Slice", StringSlice<LATIN1>);
1102+
env->SetMethodNoSideEffect(target, "hexSlice", StringSlice<HEX>);
1103+
env->SetMethodNoSideEffect(target, "ucs2Slice", StringSlice<UCS2>);
1104+
env->SetMethodNoSideEffect(target, "utf8Slice", StringSlice<UTF8>);
1105+
1106+
env->SetMethod(target, "asciiWrite", StringWrite<ASCII>);
1107+
env->SetMethod(target, "base64Write", StringWrite<BASE64>);
1108+
env->SetMethod(target, "latin1Write", StringWrite<LATIN1>);
1109+
env->SetMethod(target, "hexWrite", StringWrite<HEX>);
1110+
env->SetMethod(target, "ucs2Write", StringWrite<UCS2>);
1111+
env->SetMethod(target, "utf8Write", StringWrite<UTF8>);
1112+
1113+
// It can be a nullptr when running inside an isolate where we
1114+
// do not own the ArrayBuffer allocator.
1115+
if (uint32_t* zero_fill_field = env->isolate_data()->zero_fill_field()) {
1116+
Local<ArrayBuffer> array_buffer = ArrayBuffer::New(
1117+
env->isolate(), zero_fill_field, sizeof(*zero_fill_field));
1118+
CHECK(target
1119+
->Set(env->context(),
1120+
FIXED_ONE_BYTE_STRING(env->isolate(), "zeroFill"),
1121+
Uint32Array::New(array_buffer, 0, 1))
1122+
.FromJust());
1123+
}
11241124
}
11251125

11261126
} // anonymous namespace
Collapse file

‎src/node_internals.h‎

Copy file name to clipboardExpand all lines: src/node_internals.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ v8::MaybeLocal<v8::Uint8Array> New(Environment* env,
233233
size_t byte_offset,
234234
size_t length) {
235235
v8::Local<v8::Uint8Array> ui = v8::Uint8Array::New(ab, byte_offset, length);
236+
CHECK(!env->buffer_prototype_object().IsEmpty());
236237
v8::Maybe<bool> mb =
237238
ui->SetPrototype(env->context(), env->buffer_prototype_object());
238239
if (mb.IsNothing())

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.