You need to maintain the allocations when an object is instantiated from an exposed object in JavaScript. It's not V8's responsibility to determine how your objects are created and destroyed -- Not to mention that could have a lot of unintended side effects.
Okay, let's say that you have a class called Foo and you have a static method wrap on the class. "wrap" does as intended and wraps the class to be exposed to JavaScript.
Edit: I expanded everything out. Usually I have all this v8 nonsense typedef'd to some degree. So, in case you want a handy typedef'd v8, here ya go:
#define String_new v8::String::New
#define Context_new v8::Context::New
typedef v8::ObjectTemplate Object_template;
typedef v8::AccessorInfo Accessor_info;
typedef v8::String String;
typedef v8::Context Context;
typedef v8::FunctionTemplate Function_template;
typedef v8::Local<v8::String> Local_string;
typedef v8::Local<v8::Value> Local_value;
typedef v8::Local<v8::Object> Local_object;
typedef v8::HandleScope Handle_scope;
typedef v8::Context::Scope Scope;
typedef v8::Context::Scope Context_scope;
typedef v8::Handle<Object_template> Handle_object_template;
typedef v8::Handle<v8::Object> Handle_object;
typedef v8::Handle<v8::Value> Handle_value;
typedef v8::Handle<v8::String> Handle_string;
typedef v8::Handle<v8::Context> Handle_context;
typedef v8::Handle<Object_template> Handle_object_template;
typedef v8::Handle<v8::External> Handle_external;
typedef v8::Handle<v8::Function> Handle_function;
typedef v8::Handle<v8::Script> Handle_script;
typedef v8::Persistent<Object_template> Persistent_object_template;
typedef v8::Persistent<v8::Object> Persistent_object;
typedef v8::Persistent<v8::Context> Persistent_context;
typedef v8::Persistent<v8::Function> Persistent_function;
typedef v8::Persistent<v8::String> Persistent_string;
typedef v8::TryCatch Try_catch;
typedef v8::Exception Exception;
typedef v8::Arguments Arguments;
typedef void (Object_template_extension)(Handle_object_template*);
Alright, now down to the fun.
namespace {
v8::Persistent<Object_template> foo_tmpl;
}
v8::Handle<v8::Value> Foo::wrap(const Arguments& args)
{
v8::HandleScope handle_scope;
Foo* foo = new Foo();
// The whole create only once thing
if (tmpl->IsEmpty()) {
v8::Handle<v8::ObjectTemplate> result = create_template();
result->SetInternalFieldCount(1);
*tmpl = Persistent_object_template::New(result);
}
// Here's your magic
OBJECT_MAINTAINER->add_object(foo);
// assigning the template/setting internal field
v8::Handle<v8::ObjectTemplate> templ = *tmpl;
v8::Handle<v8::Object> result = templ->NewInstance();
v8::Handle<v8::External> class_ptr = v8::External::New(foo);
result->SetInternalField(0, foo);
// Now we can store a reference to itself that way we use "this"
foo->self = v8::Persistent<v8::Object>::New(handle_scope.Close(result));
return foo->self;
}
This is just a really close-minded method that could be approached from a multitude of directions. Whenever you expose a class, it has to be instantiated. So, you have to dynamically create that instance. Handle your memory like you want, but just clean up afterwards.
Anyhow, now you can expose what you want to v8.
some_template->Set(v8::String::New("Foo"), v8::FunctionTemplate::New(Foo::wrap));
Wahlah, multiple instances.