我有这个简短的程序来测试v8中的持久句柄。如果我理解正确,持久句柄应该保持它的引用对象存活,即使在创建该对象的句柄范围被破坏之后,但是这个测试没有表明是这种情况。
我目前在Ubuntu 18.04,x86_64。我从操作系统的“libv8-dev”软件包中安装了v8。包的版本是“3.14.5.8-11ubuntu1”,它的源是“libv8-3.14”。
在这个测试中,我有一个在块之外声明的持久句柄。然后,在块内部,我从使用值9.8创建的数字的本地句柄分配持久句柄。本地句柄是在包含句柄范围的块中创建的。一旦块结束,我强制垃圾收集器通过在循环中发送空闲通知来完成它的工作,循环一旦垃圾收集器清理了它可以做的一切就结束了。作为测试的一部分,我这样做是为了查看持久句柄是否确实保留了数字,但事实并非如此。在程序结束时,打印持久句柄所持有的值会导致值“0”而不是预期值“9.8”。
#include "v8.h"
#include <iostream>
int main()
{
v8::HandleScope outer_handle_scope;
v8::Persistent<v8::Context> context(v8::Context::New());
v8::Context::Scope context_scope(context);
v8::Persistent<v8::Number> persistent_handle;
{
v8::HandleScope inner_handle_scope;
persistent_handle = v8::Persistent<v8::Number>(v8::Number::New(9.8));
}
while (!v8::V8::IdleNotification()) {}
/* Should print 9.8 but it prints 0 */
std::cout << persistent_handle->Value() << std::endl;
persistent_handle.Dispose();
return 0;
}
我相信该程序应该打印“9.8”,但它打印“0”,所以它看起来不像持久句柄使它的对象保持活动超出它的初始范围。
编辑1:经过额外测试后,程序看起来总是输出“0”表示小数值,如9.8或-3.4。但是,对于像10和-20这样的整数,程序将工作并输出相同的值。现在问题更加神秘了。
从嵌入到v8.h版本3.14中的文档:
/**
* "Casts" a plain handle which is known to be a persistent handle
* to a persistent handle.
*/
template <class S> explicit inline Persistent(Handle<S> that)
: Handle<T>(*that) { }
你想要的是Persistent::New
,它实际上创造了一个新的Persistent
。
也就是说,V8版本3.14是从2013年开始的。它可能很奇怪,和/或当前的文档可能不再适用于它。针对这样的旧API开发新应用程序将在升级后引起一些移植工作,因此我建议您立即开始使用最新版本。试试7.3,目前的稳定版本。