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) {
isolate->SetWasmLoadSourceMapCallback(Shell::WasmLoadSourceMapCallback);
}
InitializeModuleEmbedderData(context);
Context::Scope scope(context);
if (options.include_arguments) {
Context::Scope scope(context);
const std::vector<const char*>& args = options.arguments;
int size = static_cast<int>(args.size());
Local<Array> array = Array::New(isolate, size);
......@@ -3258,6 +3258,15 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
isolate, "arguments", NewStringType::kInternalized);
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);
}
......
......@@ -228,6 +228,7 @@ class Genesis {
void InitializeExperimentalGlobal();
void InitializeIteratorFunctions();
void InitializeCallSiteBuiltins();
void InitializeConsole(Handle<JSObject> extras_binding);
#define DECLARE_FEATURE_INITIALIZATION(id, descr) void InitializeGlobal_##id();
......@@ -2794,71 +2795,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
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
{ // -- I n t l
Handle<JSObject> intl =
......@@ -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) \
void Genesis::InitializeGlobal_##id() {}
......@@ -5702,6 +5712,8 @@ bool Genesis::InstallExtrasBindings() {
SimpleInstallFunction(isolate(), extras_binding, "trace", Builtin::kTrace, 5,
true);
InitializeConsole(extras_binding);
native_context()->set_extras_binding_object(*extras_binding);
return true;
......
......@@ -169,6 +169,7 @@
V(_, computed_string, "<computed>") \
V(_, configurable_string, "configurable") \
V(_, conjunction_string, "conjunction") \
V(_, console_string, "console") \
V(_, constrain_string, "constrain") \
V(_, construct_string, "construct") \
V(_, constructor_string, "constructor") \
......
......@@ -1068,6 +1068,17 @@ UNINITIALIZED_TEST(ConsoleTimeEvents) {
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
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
const char* source_text =
"console.time();"
......
......@@ -854,6 +854,16 @@ TEST(TerminateConsole) {
isolate, TerminateCurrentThread, DoLoopCancelTerminate);
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
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());
v8::TryCatch try_catch(isolate);
CHECK(!isolate->IsExecutionTerminating());
......
......@@ -418,6 +418,33 @@ bool StrictAccessCheck(v8::Local<v8::Context> accessing_context,
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 {
public:
~InspectorExtension() override = default;
......@@ -777,6 +804,7 @@ int InspectorTestMain(int argc, char* argv[]) {
{
InspectorIsolateData::SetupGlobalTasks frontend_extensions;
frontend_extensions.emplace_back(new UtilsExtension());
frontend_extensions.emplace_back(new ConsoleExtension());
TaskRunner frontend_runner(std::move(frontend_extensions),
kFailOnUncaughtExceptions, &ready_semaphore,
startup_data.data ? &startup_data : nullptr,
......@@ -791,6 +819,7 @@ int InspectorTestMain(int argc, char* argv[]) {
InspectorIsolateData::SetupGlobalTasks backend_extensions;
backend_extensions.emplace_back(new SetTimeoutExtension());
backend_extensions.emplace_back(new ConsoleExtension());
backend_extensions.emplace_back(new InspectorExtension());
TaskRunner backend_runner(
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