Commit 0823b36d authored by legendecas's avatar legendecas Committed by V8 LUCI CQ

[init] Install console API to context extras binding

Not all environments (like ShadowRealm) would expect console
APIs to present in their globals. Moving console API to
context's extras binding to allow them to be still
snapshotted to not slow down the bootstrap.

The console API is not removed from the global in this CL,
but it is planned to be removed in the later release.

Bug: v8:11989
Change-Id: Ieca09e0bafdf8943e8fff8fee97fc21c2326320f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3364786Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Chengzhong Wu <legendecas@gmail.com>
Cr-Commit-Position: refs/heads/main@{#78998}
parent 604f6614
...@@ -3243,8 +3243,8 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) { ...@@ -3243,8 +3243,8 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
isolate->SetWasmLoadSourceMapCallback(Shell::WasmLoadSourceMapCallback); isolate->SetWasmLoadSourceMapCallback(Shell::WasmLoadSourceMapCallback);
} }
InitializeModuleEmbedderData(context); InitializeModuleEmbedderData(context);
if (options.include_arguments) {
Context::Scope scope(context); Context::Scope scope(context);
if (options.include_arguments) {
const std::vector<const char*>& args = options.arguments; const std::vector<const char*>& args = options.arguments;
int size = static_cast<int>(args.size()); int size = static_cast<int>(args.size());
Local<Array> array = Array::New(isolate, size); Local<Array> array = Array::New(isolate, size);
...@@ -3258,6 +3258,15 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) { ...@@ -3258,6 +3258,15 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
isolate, "arguments", NewStringType::kInternalized); isolate, "arguments", NewStringType::kInternalized);
context->Global()->Set(context, name, array).FromJust(); context->Global()->Set(context, name, array).FromJust();
} }
{
// setup console global.
Local<String> name = String::NewFromUtf8Literal(
isolate, "console", NewStringType::kInternalized);
Local<Value> console =
context->GetExtrasBindingObject()->Get(context, name).ToLocalChecked();
context->Global()->Set(context, name, console).FromJust();
}
return handle_scope.Escape(context); return handle_scope.Escape(context);
} }
......
...@@ -228,6 +228,7 @@ class Genesis { ...@@ -228,6 +228,7 @@ class Genesis {
void InitializeExperimentalGlobal(); void InitializeExperimentalGlobal();
void InitializeIteratorFunctions(); void InitializeIteratorFunctions();
void InitializeCallSiteBuiltins(); void InitializeCallSiteBuiltins();
void InitializeConsole(Handle<JSObject> extras_binding);
#define DECLARE_FEATURE_INITIALIZATION(id, descr) void InitializeGlobal_##id(); #define DECLARE_FEATURE_INITIALIZATION(id, descr) void InitializeGlobal_##id();
...@@ -2794,71 +2795,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, ...@@ -2794,71 +2795,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
InstallToStringTag(isolate_, math, "Math"); InstallToStringTag(isolate_, math, "Math");
} }
{ // -- C o n s o l e
Handle<String> name = factory->InternalizeUtf8String("console");
Handle<NativeContext> context(isolate()->native_context());
Handle<SharedFunctionInfo> info =
factory->NewSharedFunctionInfoForBuiltin(name, Builtin::kIllegal);
info->set_language_mode(LanguageMode::kStrict);
Handle<JSFunction> cons =
Factory::JSFunctionBuilder{isolate(), info, context}.Build();
Handle<JSObject> empty = factory->NewJSObject(isolate_->object_function());
JSFunction::SetPrototype(cons, empty);
Handle<JSObject> console = factory->NewJSObject(cons, AllocationType::kOld);
DCHECK(console->IsJSObject());
JSObject::AddProperty(isolate_, global, name, console, DONT_ENUM);
SimpleInstallFunction(isolate_, console, "debug", Builtin::kConsoleDebug, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "error", Builtin::kConsoleError, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "info", Builtin::kConsoleInfo, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "log", Builtin::kConsoleLog, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "warn", Builtin::kConsoleWarn, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "dir", Builtin::kConsoleDir, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "dirxml", Builtin::kConsoleDirXml,
0, false, NONE);
SimpleInstallFunction(isolate_, console, "table", Builtin::kConsoleTable, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "trace", Builtin::kConsoleTrace, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "group", Builtin::kConsoleGroup, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "groupCollapsed",
Builtin::kConsoleGroupCollapsed, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "groupEnd",
Builtin::kConsoleGroupEnd, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "clear", Builtin::kConsoleClear, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "count", Builtin::kConsoleCount, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "countReset",
Builtin::kConsoleCountReset, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "assert",
Builtin::kFastConsoleAssert, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "profile",
Builtin::kConsoleProfile, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "profileEnd",
Builtin::kConsoleProfileEnd, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "time", Builtin::kConsoleTime, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "timeLog",
Builtin::kConsoleTimeLog, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "timeEnd",
Builtin::kConsoleTimeEnd, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "timeStamp",
Builtin::kConsoleTimeStamp, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "context",
Builtin::kConsoleContext, 1, true, NONE);
InstallToStringTag(isolate_, console, "Object");
}
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
{ // -- I n t l { // -- I n t l
Handle<JSObject> intl = Handle<JSObject> intl =
...@@ -4395,6 +4331,80 @@ void Genesis::InitializeCallSiteBuiltins() { ...@@ -4395,6 +4331,80 @@ void Genesis::InitializeCallSiteBuiltins() {
} }
} }
void Genesis::InitializeConsole(Handle<JSObject> extras_binding) {
HandleScope scope(isolate());
Factory* factory = isolate_->factory();
// -- C o n s o l e
Handle<String> name = factory->console_string();
Handle<NativeContext> context(isolate_->native_context());
Handle<JSGlobalObject> global(context->global_object(), isolate());
Handle<SharedFunctionInfo> info =
factory->NewSharedFunctionInfoForBuiltin(name, Builtin::kIllegal);
info->set_language_mode(LanguageMode::kStrict);
Handle<JSFunction> cons =
Factory::JSFunctionBuilder{isolate(), info, context}.Build();
Handle<JSObject> empty = factory->NewJSObject(isolate_->object_function());
JSFunction::SetPrototype(cons, empty);
Handle<JSObject> console = factory->NewJSObject(cons, AllocationType::kOld);
DCHECK(console->IsJSObject());
JSObject::AddProperty(isolate_, extras_binding, name, console, DONT_ENUM);
// TODO(v8:11989): remove this in the next release
JSObject::AddProperty(isolate_, global, name, console, DONT_ENUM);
SimpleInstallFunction(isolate_, console, "debug", Builtin::kConsoleDebug, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "error", Builtin::kConsoleError, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "info", Builtin::kConsoleInfo, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "log", Builtin::kConsoleLog, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "warn", Builtin::kConsoleWarn, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "dir", Builtin::kConsoleDir, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "dirxml", Builtin::kConsoleDirXml, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "table", Builtin::kConsoleTable, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "trace", Builtin::kConsoleTrace, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "group", Builtin::kConsoleGroup, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "groupCollapsed",
Builtin::kConsoleGroupCollapsed, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "groupEnd",
Builtin::kConsoleGroupEnd, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "clear", Builtin::kConsoleClear, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "count", Builtin::kConsoleCount, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "countReset",
Builtin::kConsoleCountReset, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "assert",
Builtin::kFastConsoleAssert, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "profile", Builtin::kConsoleProfile,
0, false, NONE);
SimpleInstallFunction(isolate_, console, "profileEnd",
Builtin::kConsoleProfileEnd, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "time", Builtin::kConsoleTime, 0,
false, NONE);
SimpleInstallFunction(isolate_, console, "timeLog", Builtin::kConsoleTimeLog,
0, false, NONE);
SimpleInstallFunction(isolate_, console, "timeEnd", Builtin::kConsoleTimeEnd,
0, false, NONE);
SimpleInstallFunction(isolate_, console, "timeStamp",
Builtin::kConsoleTimeStamp, 0, false, NONE);
SimpleInstallFunction(isolate_, console, "context", Builtin::kConsoleContext,
1, true, NONE);
InstallToStringTag(isolate_, console, "Object");
}
#define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \ #define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
void Genesis::InitializeGlobal_##id() {} void Genesis::InitializeGlobal_##id() {}
...@@ -5702,6 +5712,8 @@ bool Genesis::InstallExtrasBindings() { ...@@ -5702,6 +5712,8 @@ bool Genesis::InstallExtrasBindings() {
SimpleInstallFunction(isolate(), extras_binding, "trace", Builtin::kTrace, 5, SimpleInstallFunction(isolate(), extras_binding, "trace", Builtin::kTrace, 5,
true); true);
InitializeConsole(extras_binding);
native_context()->set_extras_binding_object(*extras_binding); native_context()->set_extras_binding_object(*extras_binding);
return true; return true;
......
...@@ -169,6 +169,7 @@ ...@@ -169,6 +169,7 @@
V(_, computed_string, "<computed>") \ V(_, computed_string, "<computed>") \
V(_, configurable_string, "configurable") \ V(_, configurable_string, "configurable") \
V(_, conjunction_string, "conjunction") \ V(_, conjunction_string, "conjunction") \
V(_, console_string, "console") \
V(_, constrain_string, "constrain") \ V(_, constrain_string, "constrain") \
V(_, construct_string, "construct") \ V(_, construct_string, "construct") \
V(_, constructor_string, "constructor") \ V(_, constructor_string, "constructor") \
......
...@@ -1068,6 +1068,17 @@ UNINITIALIZED_TEST(ConsoleTimeEvents) { ...@@ -1068,6 +1068,17 @@ UNINITIALIZED_TEST(ConsoleTimeEvents) {
v8::Isolate* isolate = v8::Isolate::New(create_params); v8::Isolate* isolate = v8::Isolate::New(create_params);
{ {
ScopedLoggerInitializer logger(isolate); ScopedLoggerInitializer logger(isolate);
{
// setup console global.
v8::HandleScope scope(isolate);
v8::Local<v8::String> name = v8::String::NewFromUtf8Literal(
isolate, "console", v8::NewStringType::kInternalized);
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::Local<v8::Value> console = context->GetExtrasBindingObject()
->Get(context, name)
.ToLocalChecked();
context->Global()->Set(context, name, console).FromJust();
}
// Test that console time events are properly logged // Test that console time events are properly logged
const char* source_text = const char* source_text =
"console.time();" "console.time();"
......
...@@ -854,6 +854,16 @@ TEST(TerminateConsole) { ...@@ -854,6 +854,16 @@ TEST(TerminateConsole) {
isolate, TerminateCurrentThread, DoLoopCancelTerminate); isolate, TerminateCurrentThread, DoLoopCancelTerminate);
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global); v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
{
// setup console global.
v8::HandleScope scope(isolate);
v8::Local<v8::String> name = v8::String::NewFromUtf8Literal(
isolate, "console", v8::NewStringType::kInternalized);
v8::Local<v8::Value> console =
context->GetExtrasBindingObject()->Get(context, name).ToLocalChecked();
context->Global()->Set(context, name, console).FromJust();
}
CHECK(!isolate->IsExecutionTerminating()); CHECK(!isolate->IsExecutionTerminating());
v8::TryCatch try_catch(isolate); v8::TryCatch try_catch(isolate);
CHECK(!isolate->IsExecutionTerminating()); CHECK(!isolate->IsExecutionTerminating());
......
...@@ -418,6 +418,33 @@ bool StrictAccessCheck(v8::Local<v8::Context> accessing_context, ...@@ -418,6 +418,33 @@ bool StrictAccessCheck(v8::Local<v8::Context> accessing_context,
return accessing_context.IsEmpty(); return accessing_context.IsEmpty();
} }
class ConsoleExtension : public InspectorIsolateData::SetupGlobalTask {
public:
~ConsoleExtension() override = default;
void Run(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> global) override {
v8::Local<v8::String> name =
v8::String::NewFromUtf8Literal(isolate, "console");
global->SetAccessor(name, &ConsoleGetterCallback, nullptr, {}, v8::DEFAULT,
v8::DontEnum);
}
private:
static void ConsoleGetterCallback(
v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info) {
v8::Isolate* isolate = info.GetIsolate();
v8::HandleScope scope(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::Local<v8::String> name =
v8::String::NewFromUtf8Literal(isolate, "console");
v8::Local<v8::Object> console = context->GetExtrasBindingObject()
->Get(context, name)
.ToLocalChecked()
.As<v8::Object>();
info.GetReturnValue().Set(console);
}
};
class InspectorExtension : public InspectorIsolateData::SetupGlobalTask { class InspectorExtension : public InspectorIsolateData::SetupGlobalTask {
public: public:
~InspectorExtension() override = default; ~InspectorExtension() override = default;
...@@ -777,6 +804,7 @@ int InspectorTestMain(int argc, char* argv[]) { ...@@ -777,6 +804,7 @@ int InspectorTestMain(int argc, char* argv[]) {
{ {
InspectorIsolateData::SetupGlobalTasks frontend_extensions; InspectorIsolateData::SetupGlobalTasks frontend_extensions;
frontend_extensions.emplace_back(new UtilsExtension()); frontend_extensions.emplace_back(new UtilsExtension());
frontend_extensions.emplace_back(new ConsoleExtension());
TaskRunner frontend_runner(std::move(frontend_extensions), TaskRunner frontend_runner(std::move(frontend_extensions),
kFailOnUncaughtExceptions, &ready_semaphore, kFailOnUncaughtExceptions, &ready_semaphore,
startup_data.data ? &startup_data : nullptr, startup_data.data ? &startup_data : nullptr,
...@@ -791,6 +819,7 @@ int InspectorTestMain(int argc, char* argv[]) { ...@@ -791,6 +819,7 @@ int InspectorTestMain(int argc, char* argv[]) {
InspectorIsolateData::SetupGlobalTasks backend_extensions; InspectorIsolateData::SetupGlobalTasks backend_extensions;
backend_extensions.emplace_back(new SetTimeoutExtension()); backend_extensions.emplace_back(new SetTimeoutExtension());
backend_extensions.emplace_back(new ConsoleExtension());
backend_extensions.emplace_back(new InspectorExtension()); backend_extensions.emplace_back(new InspectorExtension());
TaskRunner backend_runner( TaskRunner backend_runner(
std::move(backend_extensions), kStandardPropagateUncaughtExceptions, std::move(backend_extensions), kStandardPropagateUncaughtExceptions,
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment