V8 无法使用名称 "console" 设置 ObjectTemplate
V8 Cannot set ObjectTemplate with name "console"
我尝试设置一个名为 console 的全局对象,但该特定名称导致崩溃,对我来说它似乎在告诉我该对象已经存在。我可以将它设置为其他任何东西。为什么我不能将对象设置为名称 "console"?
V8 版本为 6.5.254.6
错误
# Fatal error in ../../src/objects.cc, line 6007
# Debug check failed: !it.IsFound().
代码片段
isolate->Enter();
v8::HandleScope handle_scope(isolate);
// Create globals
auto globalObj = v8::ObjectTemplate::New(isolate);
// Create console object
auto consoleObj = v8::ObjectTemplate::New(isolate);
// Log
auto logcb = [](V8CallbackArgs args) {
auto& log = Log::Instance();
for (size_t i = 1; i < args.Length(); i++)
log << *v8::String::Utf8Value(args[i]);
log << std::endl;
};
consoleObj->Set(v8::String::NewFromUtf8(isolate, "log"), v8::FunctionTemplate::New(isolate, logcb));
// Set global object
globalObj->Set(v8::String::NewFromUtf8(isolate, "console"), consoleObj); // nonono cannot have it console, con is ok though
// Create script context
context = v8::Persistent<v8::Context, v8::CopyablePersistentTraits<v8::Context>>(isolate, v8::Context::New(isolate, nullptr, globalObj));
{
v8::Context::Scope context_scope(context.Get(isolate));
v8::TryCatch tc(isolate);
auto source = v8::String::NewFromUtf8(src.c_str());
auto script = v8::Script::Compile(source);
if (script->Run().IsEmpty() && CV8ScriptRuntime::isDebug) {
v8loge "Error loading script \"" << filepath << "\n" << std::endl
<< "Exception: " << *v8::String::Utf8Value(tc.Exception()) << std::endl
<< "Stack trace: " << *v8::String::Utf8Value(tc.StackTrace()) << std::endl << Log::White;
}
}
您的观察是正确的。当 V8 初始化一个 Context
时,它会在其中安装一个全局 console
对象,并假定(通过检查保护)具有该名称的 属性 尚不存在。当您提供自己的 "console" 时,该检查失败。
如果你想覆盖 V8 的 built-in console
,你必须先创建 Context
(通过 v8::Context::New
),然后删除(或覆盖) console
属性 在其全局对象上。
如果您只想在您的嵌入器中拥有一个 console
对象,就像您从浏览器中了解到的那样,那么我很高兴地通知您,这项工作已经完成,您可以简单地使用它:-)
我尝试设置一个名为 console 的全局对象,但该特定名称导致崩溃,对我来说它似乎在告诉我该对象已经存在。我可以将它设置为其他任何东西。为什么我不能将对象设置为名称 "console"?
V8 版本为 6.5.254.6
错误
# Fatal error in ../../src/objects.cc, line 6007
# Debug check failed: !it.IsFound().
代码片段
isolate->Enter();
v8::HandleScope handle_scope(isolate);
// Create globals
auto globalObj = v8::ObjectTemplate::New(isolate);
// Create console object
auto consoleObj = v8::ObjectTemplate::New(isolate);
// Log
auto logcb = [](V8CallbackArgs args) {
auto& log = Log::Instance();
for (size_t i = 1; i < args.Length(); i++)
log << *v8::String::Utf8Value(args[i]);
log << std::endl;
};
consoleObj->Set(v8::String::NewFromUtf8(isolate, "log"), v8::FunctionTemplate::New(isolate, logcb));
// Set global object
globalObj->Set(v8::String::NewFromUtf8(isolate, "console"), consoleObj); // nonono cannot have it console, con is ok though
// Create script context
context = v8::Persistent<v8::Context, v8::CopyablePersistentTraits<v8::Context>>(isolate, v8::Context::New(isolate, nullptr, globalObj));
{
v8::Context::Scope context_scope(context.Get(isolate));
v8::TryCatch tc(isolate);
auto source = v8::String::NewFromUtf8(src.c_str());
auto script = v8::Script::Compile(source);
if (script->Run().IsEmpty() && CV8ScriptRuntime::isDebug) {
v8loge "Error loading script \"" << filepath << "\n" << std::endl
<< "Exception: " << *v8::String::Utf8Value(tc.Exception()) << std::endl
<< "Stack trace: " << *v8::String::Utf8Value(tc.StackTrace()) << std::endl << Log::White;
}
}
您的观察是正确的。当 V8 初始化一个 Context
时,它会在其中安装一个全局 console
对象,并假定(通过检查保护)具有该名称的 属性 尚不存在。当您提供自己的 "console" 时,该检查失败。
如果你想覆盖 V8 的 built-in console
,你必须先创建 Context
(通过 v8::Context::New
),然后删除(或覆盖) console
属性 在其全局对象上。
如果您只想在您的嵌入器中拥有一个 console
对象,就像您从浏览器中了解到的那样,那么我很高兴地通知您,这项工作已经完成,您可以简单地使用它:-)