javascript - 嵌入式 V8 上下文和脚本编译崩溃
问题描述
召集 V8 专家。我将 V8 嵌入到我的一个项目中,并且在模块化我的代码时遇到了问题。最简单的例子是编译并运行一个打印“Hello World!”的小脚本。来自 C++ 函数。工作版本如下:
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);
}
}
}
当我尝试将代码拆分为可管理的范围时(模仿我想稍后构建的包装类),我在脚本编译时遇到了崩溃:
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 上运行此代码。我不知道我是否做错了什么,或者上下文是否存在错误。在线研究使我相信,以这种方式使用持久上下文可以很好地在作用域之间保持相同的上下文。这里出了什么问题?
解决方案
问题是一旦范围结束,平台的 unique_ptr 就会被破坏。将其移动到父范围可以修复它。
推荐阅读
- docusaurus - 在 Docusarus 中挂钩 React Router 事件?
- ios - SwiftUI | 警告:绑定首选项 _ 尝试每帧更新多次。可能的原因?
- python - python程序中的运行时错误将中缀转换为后缀
- javascript - reactjs不能合并两个pdf
- ios - 如何在 macbook pro big sur 上安装 expo CLI?
- javascript - 有没有办法像猫鼬一样在 Sequelize 时间戳中设置“过期”选项?
- laravel - Laravel 天文可翻译更新方法
- reactjs - 使用面临问题的打字稿创建反应应用程序
- xcode - 无法构建 iOS 应用程序 Xcode 构建的错误输出:
- python-3.x - 为什么我的 Selenium 代码只返回我请求的数据的一半