I have this short program to test a persistent handle in v8. If I understand correctly, a persistent handle should keep it's referenced object alive even after the handle scope in which that object was created gets destroyed but this test does not show that is the case.
I am currently on Ubuntu 18.04, x86_64. I installed v8 from the operating system's "libv8-dev" package. The package's version is "3.14.5.8-11ubuntu1" and it's source is "libv8-3.14".
In this test, I have a persistent handle declared outside of a block. Then, inside the block, I assign to the persistent handle from a local handle of a number created with the value 9.8. The local handle was created in a block containing a handle scope. Once the block ends, I force the garbage collector to do it's work by sending idle notifications in a loop which ends once the garbage collector has cleaned up everything it can. I do this as part of the test to see if the persistent handle really does keep the number held but it doesn't. Near the end of the program, printing the value held by the persistent handle results in the value "0" instead of the expected value "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;
}
I believe the program should have printed "9.8" but it prints "0", so it doesn't seem like the persistent handle keeps it's object alive beyond it's initial scope.
Edit 1: After additional tests, it looks like the program will always output "0" for fractional values like 9.8 or -3.4. However, for whole numbers like 10 and -20, the program will work and output the same value. The problem is now even more mysterious.
From the documentation embedded into version 3.14 of v8.h:
/**
* "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) { }
What you want instead is Persistent::New
, which actually creates a new Persistent
.
That said, V8 version 3.14 is from 2013. It may well be weird, and/or current documentation may not apply to it any more. Developing new applications against such an old API will cause some porting effort once you upgrade, so I recommend to start with an up-to-date version right away. Try 7.3, the current stable version.