Hi Ben, Yes, however what I need to store is the v8::FunctionTemplate, v8::Local<v8::FunctionTemplate> to be more specific, which does not inherit from Value and there is a static_assert that checks for that.
So perhaps, maybe if go to the real problem a different solution may arise. I have a Js wrapper C++ base class from which all C++-to-Js must inherit, this is based on the code for Node.js, so when I write a new class that inherits from this wrapper, I need to allocate a FunctionTemplate on the isolate/context pair, like so: I removed some lines, but otherwise you can look at this code here: https://github.com/AeonGames/AeonGUI/blob/master/core/dom/EventTarget.cpp#L23 void EventTarget::Initialize ( v8::Isolate* aIsolate ) { v8::Local<v8::Context> context = aIsolate->GetCurrentContext(); //--------------------------------------- // Store constructor on a callback data object v8::Local<v8::ObjectTemplate> constructor_data_template = v8::ObjectTemplate::New ( aIsolate ); constructor_data_template->SetInternalFieldCount ( 1 ); v8::Local<v8::Object> constructor_data = constructor_data_template->NewInstance ( context ).ToLocalChecked(); // Prepare EventTarget constructor template v8::Local<v8::FunctionTemplate> constructor_template = v8::FunctionTemplate::New ( aIsolate, JsObjectWrap::New<EventTarget>, constructor_data ); // <----- THIS IS THE FunctionTemplate I NEED TO STORE constructor_template->SetClassName ( v8::String::NewFromUtf8 ( aIsolate, "EventTarget" ).ToLocalChecked() ); constructor_template->InstanceTemplate()->SetInternalFieldCount ( 1 ); AddFunctionTemplate ( aIsolate, typeid ( EventTarget ), constructor_template ); // <---- THIS IS MY CURRENT SOLUTION //---------------------------------------------------------------- v8::Local<v8::Function> event = event_template->GetFunction ( context ).ToLocalChecked(); context->Global()->Set ( context, v8::String::NewFromUtf8 ( aIsolate, "Event" ).ToLocalChecked(), event ).FromJust(); v8::Local<v8::Function> constructor = constructor_template->GetFunction ( context ).ToLocalChecked(); constructor_data->SetInternalField ( 0, constructor ); context->Global()->Set ( context, v8::String::NewFromUtf8 ( aIsolate, "EventTarget" ).ToLocalChecked(), constructor ).FromJust(); } Then, when I want to have Node inherit from EventTarget I write a similar static function (the previous one is also static) https://github.com/AeonGames/AeonGUI/blob/master/core/dom/Node.cpp#L221 void Node::Initialize ( v8::Isolate* aIsolate ) { if ( HasFunctionTemplate ( aIsolate, typeid ( Node ) ) ) { throw std::runtime_error ( "Isolate already initialized." ); } v8::Local<v8::Context> context = aIsolate->GetCurrentContext(); // Prepare Node constructor template v8::Local<v8::FunctionTemplate> constructor_template = v8::FunctionTemplate::New ( aIsolate ); constructor_template->SetClassName ( v8::String::NewFromUtf8 ( aIsolate, "Node" ).ToLocalChecked() ); constructor_template->Inherit ( EventTarget::GetFunctionTemplate ( aIsolate, typeid ( EventTarget ) ) ); // <-- THIS IS WHAT I REALLY NEED AddFunctionTemplate ( aIsolate, typeid ( Node ), constructor_template ); v8::Local<v8::Function> constructor = constructor_template->GetFunction ( context ).ToLocalChecked(); context->Global()->Set ( context, v8::String::NewFromUtf8 ( aIsolate, "Node" ).ToLocalChecked(), constructor ).FromJust(); } As I said before, this works but I feel that makes the code too verbose and prone to error, for example now I am now forced to have a trivial Finalize function on all classes: void Node::Finalize ( v8::Isolate* aIsolate ) { RemoveFunctionTemplate ( aIsolate, typeid ( Node ) ); } because the FunctionTemplate objects are stored as Persistent Handles in this map: static std::unordered_map<std::pair<v8::Isolate*, size_t>, v8::Persistent<v8::FunctionTemplate, v8::CopyablePersistentTraits<v8::FunctionTemplate>>> FunctionTemplates{}; So I need to free them all, unlike a Local. So, perhaps there is a way where I can either store the template in the constructor, or maybe there is a way to have Node inherit from EventTarget without requiring the FunctionTemplate, but instead require just the function? Thanks for taking a look! On Wednesday, October 21, 2020 at 5:39:59 PM UTC-6 boi...@gmail.com wrote: > Rodrigo, you should be able to trivially cast a v8::Function or v8::Object > to v8::Value is that what you're trying to do? In that case you don't need > to put them in a v8::External. You can pass those objects to > data->SetInternalField safely I would think. > Ben > > > On Tuesday, 20 October 2020 at 15:10:00 UTC+10:30 Rodrigo Hernandez wrote: > >> So, coming back to this, is there a way to cast/convert/wrap a local >> template (function or object) into a v8::Value? >> I am thinking about hiding them inside an internal field so I could do: >> >> context->global()->GetFunction("constructor")->GetInternalField(X). >> >> how safe would it be to cast them to a void* and wrapping them inside a >> v8::External? >> >> On Sunday, October 11, 2020 at 11:40:27 AM UTC-6 Rodrigo Hernandez wrote: >> >>> Thanks Ben, I see how those are less optimal, I was hoping for something >>> along the lines of context->global()->GetFunctionTemplate("constructor"), >>> or something along those lines. >>> The only problem I have with my approach is that I need a Finalize >>> function on each wrapped class that pretty much just resets the permanent >>> handles. >>> >>> Thanks Again! >>> On Sunday, October 11, 2020 at 1:49:10 AM UTC-6 Ben Noordhuis wrote: >>> >>>> On Sat, Oct 10, 2020 at 10:44 PM Rodrigo Hernandez >>>> <kwizatz.ae...@gmail.com> wrote: >>>> > >>>> > Hello, >>>> > >>>> > So, suppose I am wrapping a C++ class around a JS constructor, I've >>>> already created and initialized the isolate, created and initialized a >>>> context, I have the FunctionTemplate for the constructor and I have >>>> instantiated the function and I can call it from Js as x() or new X(), >>>> > all this is fine, the function template context is finished and the >>>> handle lost. >>>> > >>>> > But then I want to create another wrapped object for a class that >>>> inherits from the first one. >>>> > Is there a way to retrieve the base class FunctionTemplate so in the >>>> child class I can call child->Inherit(base)? >>>> > >>>> > Is there another way of doing this? >>>> > >>>> > Right now I am keeping a C++ unordered_map of isolate to persistent >>>> handle to function templates, and that works, but is that the only option? >>>> > >>>> > Thanks! >>>> >>>> It's not the only option but it's a pretty good solution. Less optimal >>>> solutions: >>>> >>>> - store them in the snapshot with SnapshotCreator::AddData() (but you >>>> can only retrieve it once) >>>> - scan the heap for them with Isolate::VisitHandlesWithClassIds(). >>>> >>>> No doubt there are more ways to stow them away somewhere. >>>> >>> -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/v8-users/5e7796f0-fff2-46a4-a6bb-5c1632342145n%40googlegroups.com.