10

I want my class to hold a v8::Context and a v8::External as members. Therefore, I thought I had to use persistent handles.

class ScriptHelper {
public:
    ScriptHelper(v8::Persistent<v8::Context> Context) : context(Context) {
        // ...
    }
    // ...
private:
    v8::Persistent<v8::Context> context;
    v8::Persistent<v8::External> external;
};

However, persistent handles are non copyable in V8, so the code does not compile. The error occurs in the lines where the two memberes get initialized. For the context, this is in the initializer list of the constructor, for the external this is inside the constructor body.

1> error C2440: '=' : cannot convert from 'v8::Primitive *' to 'v8::Object *volatile '
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1> include\v8\v8.h(603) : see reference to function template instantiation 'void v8::NonCopyablePersistentTraits::Uncompilable(void)' being compiled

I thought about using pointers to persistent handles but that seems counter intuitive since the concept of handles already implies some kind of reference. Moreover, I think the handles would get destructed then so that V8's internal garbage collector could clean up the objects.

How can I store V8 objects as class members persistently?

Update: Even if I use pointer to persistent handles, I have get same compiler errors for methods that return persistent handles.

danijar
  • 32,406
  • 45
  • 166
  • 297

1 Answers1

23

By default, persistent handles use a non copyable trait. Explicitly passing the copyable trait as template argument makes them work like in prior versions.

Persistent<Value, CopyablePersistentTraits<Value>> persistent(isolate, value);
danijar
  • 32,406
  • 45
  • 166
  • 297
  • 1
    Thanks @danijar! In my case, I was trying to use `Persistent::New(isolate, value)` which apparently doesn't allow `CopyablePersistentTraits` as a second argument. The way you created the object above works perfectly though. – Jake Stoeffler Apr 02 '14 at 04:20
  • Great. This works, but now MakeWeak isn't in Persistent anymore :( – xaxxon Dec 28 '15 at 05:19
  • Hi @danijar, I have used your strategy to get a `Local` from a `Persistent`, seems that not work anymore, maybe because I have not take advantage of the constructor? Could you please look at this [post](https://stackoverflow.com/questions/64979842/how-can-i-include-another-js-file-file-in-todays-v8) for me? – calvin Nov 25 '20 at 03:34