嵌入式 V8 上下文和脚本编译崩溃 [英] Embedded V8 context and script compilation crash

查看:23
本文介绍了嵌入式 V8 上下文和脚本编译崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请教 V8 专家.我将 V8 嵌入到我的一个项目中,并且遇到了模块化代码的问题.最简单的例子是编译和运行一个打印Hello World!"的小脚本.来自 C++ 函数.工作版本如下:

Calling on V8 experts. I am embedding V8 in a project of mine and I am running into issues modularizing my code. The simplest example of this is compiling and running a small script that prints "Hello World!" from a C++ function. The working version is as follows:

void testV8(const v8::FunctionCallbackInfo<v8::Value>& args) {
    printf("Hello World!\n");
}

void working() {
    v8::Isolate* isolate = nullptr;
    std::string code = "testV8();";

    {
        // Basic initialization
        std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
        v8::V8::InitializePlatform(platform.get());
        v8::V8::Initialize();
        v8::Isolate::CreateParams initOptions;
        initOptions.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
        isolate = v8::Isolate::New(initOptions);
        isolate->Enter();

        // Create context
        v8::HandleScope handleScope(isolate);
        auto global = v8::ObjectTemplate::New(isolate);
        v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);

        // Enter context
        v8::Context::Scope contextScope(context);

        // Bind function
        v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(isolate, &testV8);
        auto name = v8::String::NewFromUtf8(isolate, "testV8").ToLocalChecked();
        context->Global()->Set(context, name, ft->GetFunction(context).ToLocalChecked());

        // Run script
        auto execCode = v8::String::NewFromUtf8(isolate, code.c_str()).ToLocalChecked();
        v8::Local<v8::Script> script;
        if (v8::Script::Compile(context, execCode).ToLocal(&script)) {
            v8::Local<v8::Value> result;
            script->Run(context).ToLocal(&result);
        }
    }
}

当我尝试将代码拆分为可管理的范围时(模仿我想稍后构建的包装类),我在脚本编译时崩溃:

When I try to split the code up into manageable scopes (mimicking wrapper classes I want to build later), I get a crash upon script compilation:

void testV8(const v8::FunctionCallbackInfo<v8::Value>& args) {
    printf("Hello World!\n");
}

void failing() {
    v8::Isolate* isolate = nullptr;
    std::string code = "testV8();";
    v8::Persistent<v8::Context> persistentContext;

    {
        // Basic initialization
        std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
        v8::V8::InitializePlatform(platform.get());
        v8::V8::Initialize();
        v8::Isolate::CreateParams initOptions;
        initOptions.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
        isolate = v8::Isolate::New(initOptions);
        isolate->Enter();

        // Create context
        v8::HandleScope handleScope(isolate);
        auto global = v8::ObjectTemplate::New(isolate);
        v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);

        // Save context
        persistentContext.Reset(isolate, context);
    }

    {
        // Rebuild scopes and enter context
        v8::Locker locker(isolate);
        v8::HandleScope handleScope(isolate);
        v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, persistentContext);
        v8::Context::Scope contextScope(context);

        // Bind function
        v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(isolate, &testV8);
        auto name = v8::String::NewFromUtf8(isolate, "testV8").ToLocalChecked();
        context->Global()->Set(context, name, ft->GetFunction(context).ToLocalChecked());
    }

    {
        // Rebuild scopes and enter context
        v8::Locker locker(isolate);
        v8::HandleScope handleScope(isolate);
        v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, persistentContext);
        v8::Context::Scope contextScope(context);

        // Run script
        auto execCode = v8::String::NewFromUtf8(isolate, code.c_str()).ToLocalChecked();
        v8::Local<v8::Script> script;
        if (v8::Script::Compile(context, execCode).ToLocal(&script)) {
            v8::Local<v8::Value> result;
            script->Run(context).ToLocal(&result);
        }
    }
}

在 xCode 上构建并在 Macbook 上运行此代码.我不知道我是否做错了什么,或者上下文是否存在一些错误.在线研究使我相信,以这种方式使用持久上下文可以在范围之间保持相同的上下文.这里出了什么问题?

Building on xCode and running on this code on a Macbook. I can't tell if I'm doing anything wrong or if there is some bug with the contexts. Research online leads me to believe that using persistent contexts this way is fine to keep the same context alive between scopes. What's going wrong here?

推荐答案

问题是一旦作用域结束,平台的 unique_ptr 就会被破坏.将其移入父作用域可修复它.

The problem is that the unique_ptr for the platform is getting destroyed once the scope ends. Moving it into the parent scope fixes it.

这篇关于嵌入式 V8 上下文和脚本编译崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆