V8 Cannot set ObjectTemplate with name “console”

拥有回忆 提交于 2020-01-06 06:46:47

问题


I try to set a global object named console, but that specific name causes a crash and to me it seems like it's telling me that the object already exists. I can though set it to anything else. Why can I not set the object to name "console"?

V8 Version is 6.5.254.6

Error

# Fatal error in ../../src/objects.cc, line 6007
# Debug check failed: !it.IsFound().

Code Snippet

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;
    }
}

回答1:


Your observation is correct. When V8 initializes a Context, it installs a global console object into it, and assumes (guarded by a check) that a property with that name does not exist yet. When you provide your own "console", that check fails.

If you want to overwrite V8's built-in console, you'll have to create the Context first (via v8::Context::New), then delete (or overwrite) the console property on its global object.

If all you wanted was to have a console object in your embedder just like the one you know from browsers, then I'm happy to inform you that this work has already been done and you can simply use it :-)



来源:https://stackoverflow.com/questions/49620965/v8-cannot-set-objecttemplate-with-name-console

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!