Skip to content

Commit

Permalink
bootstrap: consolidate global properties definition
Browse files Browse the repository at this point in the history
`globalThis.process` and `globalThis.Buffer` has been re-defined with
a getter/setter pair.

`atob` and `bota` are defined as enumerable properties according to
WebIDL definition.
  • Loading branch information
legendecas committed Jun 9, 2022
1 parent c977ad6 commit ba792a8
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 93 deletions.
7 changes: 7 additions & 0 deletions lib/internal/bootstrap/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ defineOperation(globalThis, 'clearTimeout', timers.clearTimeout);
defineOperation(globalThis, 'setInterval', timers.setInterval);
defineOperation(globalThis, 'setTimeout', timers.setTimeout);

const buffer = require('buffer');
defineOperation(globalThis, 'atob', buffer.atob);
defineOperation(globalThis, 'btoa', buffer.btoa);

// https://www.w3.org/TR/FileAPI/#dfn-Blob
exposeInterface(globalThis, 'Blob', buffer.Blob);

// https://www.w3.org/TR/hr-time-2/#the-performance-attribute
defineReplacableAttribute(globalThis, 'performance',
require('perf_hooks').performance);
Expand Down
43 changes: 0 additions & 43 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ const {
FunctionPrototypeCall,
JSONParse,
ObjectDefineProperty,
ObjectDefineProperties,
ObjectGetPrototypeOf,
ObjectPreventExtensions,
ObjectSetPrototypeOf,
Expand Down Expand Up @@ -377,14 +376,6 @@ function setupProcessObject() {
configurable: false,
value: 'process'
});
// Make process globally available to users by putting it on the global proxy
ObjectDefineProperty(globalThis, 'process', {
__proto__: null,
value: process,
enumerable: false,
writable: true,
configurable: true
});
}

function setupGlobalProxy() {
Expand All @@ -399,46 +390,12 @@ function setupGlobalProxy() {

function setupBuffer() {
const {
Blob,
Buffer,
atob,
btoa,
} = require('buffer');
const bufferBinding = internalBinding('buffer');

// Only after this point can C++ use Buffer::New()
bufferBinding.setBufferPrototype(Buffer.prototype);
delete bufferBinding.setBufferPrototype;
delete bufferBinding.zeroFill;

ObjectDefineProperties(globalThis, {
'Blob': {
__proto__: null,
value: Blob,
enumerable: false,
writable: true,
configurable: true,
},
'Buffer': {
__proto__: null,
value: Buffer,
enumerable: false,
writable: true,
configurable: true,
},
'atob': {
__proto__: null,
value: atob,
enumerable: false,
writable: true,
configurable: true,
},
'btoa': {
__proto__: null,
value: btoa,
enumerable: false,
writable: true,
configurable: true,
},
});
}
6 changes: 3 additions & 3 deletions src/api/environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,9 @@ MaybeLocal<Value> LoadEnvironment(

// TODO(addaleax): Avoid having a global table for all scripts.
std::string name = "embedder_main_" + std::to_string(env->thread_id());
native_module::NativeModuleEnv::Add(
name.c_str(),
UnionBytes(**main_utf16, main_utf16->length()));
bool added = native_module::NativeModuleEnv::Add(
name.c_str(), UnionBytes(**main_utf16, main_utf16->length()));
CHECK(added);
env->set_main_utf16(std::move(main_utf16));
std::vector<Local<String>> params = {
env->process_string(),
Expand Down
139 changes: 92 additions & 47 deletions test/cctest/test_linked_binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,24 @@ TEST_F(LinkedBindingTest, SimpleTest) {

v8::Local<v8::Context> context = isolate_->GetCurrentContext();

const char* run_script =
"process._linkedBinding('cctest_linkedbinding').key";
v8::Local<v8::Script> script = v8::Script::Compile(
context,
v8::String::NewFromOneByte(isolate_,
reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked();
v8::Local<v8::Value> completion_value =
node::LoadEnvironment(
*test_env,
[&](const node::StartExecutionCallbackInfo& info)
-> v8::MaybeLocal<v8::Value> {
const char* run_script =
"process._linkedBinding('cctest_linkedbinding').key";
v8::Local<v8::Script> script =
v8::Script::Compile(
context,
v8::String::NewFromOneByte(
isolate_, reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
return script->Run(context);
})
.ToLocalChecked();

v8::String::Utf8Value utf8val(isolate_, completion_value);
CHECK_NOT_NULL(*utf8val);
CHECK_EQ(strcmp(*utf8val, "value"), 0);
Expand Down Expand Up @@ -69,15 +78,24 @@ TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingTest) {

v8::Local<v8::Context> context = isolate_->GetCurrentContext();

const char* run_script =
"process._linkedBinding('local_linked').key";
v8::Local<v8::Script> script = v8::Script::Compile(
context,
v8::String::NewFromOneByte(isolate_,
reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked();
v8::Local<v8::Value> completion_value =
node::LoadEnvironment(
*test_env,
[&](const node::StartExecutionCallbackInfo& info)
-> v8::MaybeLocal<v8::Value> {
const char* run_script =
"process._linkedBinding('local_linked').key";
v8::Local<v8::Script> script =
v8::Script::Compile(
context,
v8::String::NewFromOneByte(
isolate_, reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
return script->Run(context);
})
.ToLocalChecked();

v8::String::Utf8Value utf8val(isolate_, completion_value);
CHECK_NOT_NULL(*utf8val);
CHECK_EQ(strcmp(*utf8val, "value"), 0);
Expand Down Expand Up @@ -113,15 +131,24 @@ TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingNapiTest) {

v8::Local<v8::Context> context = isolate_->GetCurrentContext();

const char* run_script =
"process._linkedBinding('local_linked_napi').hello";
v8::Local<v8::Script> script = v8::Script::Compile(
context,
v8::String::NewFromOneByte(isolate_,
reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked();
v8::Local<v8::Value> completion_value =
node::LoadEnvironment(
*test_env,
[&](const node::StartExecutionCallbackInfo& info)
-> v8::MaybeLocal<v8::Value> {
const char* run_script =
"process._linkedBinding('local_linked_napi').hello";
v8::Local<v8::Script> script =
v8::Script::Compile(
context,
v8::String::NewFromOneByte(
isolate_, reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
return script->Run(context);
})
.ToLocalChecked();

v8::String::Utf8Value utf8val(isolate_, completion_value);
CHECK_NOT_NULL(*utf8val);
CHECK_EQ(strcmp(*utf8val, "world"), 0);
Expand Down Expand Up @@ -169,17 +196,25 @@ TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingNapiInstanceDataTest) {
AddLinkedBinding(*test_env, local_linked_napi_id);

v8::Local<v8::Context> context = isolate_->GetCurrentContext();

const char* run_script =
"process._linkedBinding('local_linked_napi_id').hello";
v8::Local<v8::Script> script = v8::Script::Compile(
context,
v8::String::NewFromOneByte(isolate_,
reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
v8::Local<v8::Value> completion_value =
script->Run(context).ToLocalChecked();
node::LoadEnvironment(
*test_env,
[&](const node::StartExecutionCallbackInfo& info)
-> v8::MaybeLocal<v8::Value> {
const char* run_script =
"process._linkedBinding('local_linked_napi_id').hello";
v8::Local<v8::Script> script =
v8::Script::Compile(
context,
v8::String::NewFromOneByte(
isolate_,
reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
return script->Run(context);
})
.ToLocalChecked();

CHECK(completion_value->IsExternal());
instance_data = static_cast<int*>(
completion_value.As<v8::External>()->Value());
Expand All @@ -206,16 +241,26 @@ TEST_F(LinkedBindingTest, ManyBindingsTest) {

v8::Local<v8::Context> context = isolate_->GetCurrentContext();

const char* run_script =
"for (let i = 1; i <= 5; i++)process._linkedBinding(`local_linked${i}`);"
"process._linkedBinding('local_linked_napi').hello";
v8::Local<v8::Script> script = v8::Script::Compile(
context,
v8::String::NewFromOneByte(isolate_,
reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked();
v8::Local<v8::Value> completion_value =
node::LoadEnvironment(
*test_env,
[&](const node::StartExecutionCallbackInfo& info)
-> v8::MaybeLocal<v8::Value> {
const char* run_script =
"for (let i = 1; i <= 5; "
"i++)process._linkedBinding(`local_linked${i}`);"
"process._linkedBinding('local_linked_napi').hello";
v8::Local<v8::Script> script =
v8::Script::Compile(
context,
v8::String::NewFromOneByte(
isolate_, reinterpret_cast<const uint8_t*>(run_script))
.ToLocalChecked())
.ToLocalChecked();
return script->Run(context);
})
.ToLocalChecked();

v8::String::Utf8Value utf8val(isolate_, completion_value);
CHECK_NOT_NULL(*utf8val);
CHECK_EQ(strcmp(*utf8val, "world"), 0);
Expand Down
2 changes: 2 additions & 0 deletions test/parallel/test-global.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ builtinModules.forEach((moduleName) => {
'clearImmediate',
'clearInterval',
'clearTimeout',
'atob',
'btoa',
'performance',
'setImmediate',
'setInterval',
Expand Down

0 comments on commit ba792a8

Please sign in to comment.