V8EngineProxy::V8EngineProxy(bool enableDebugging, DebugMessageDispatcher* debugMessageDispatcher, int debugPort) :ProxyBase(V8EngineProxyClass), _GlobalObjectTemplateProxy(nullptr), _Strings(1000, _StringItem()), _Handles(1000, nullptr), _DisposedHandles(1000, -1), _NextNonTemplateObjectID(-2) { if (!_V8Initialized) // (the API changed: https://groups.google.com/forum/#!topic/v8-users/wjMwflJkfso) { v8::V8::InitializePlatform(v8::platform::CreateDefaultPlatform()); v8::V8::InitializeICU(); v8::V8::Initialize(); _V8Initialized = true; } _Isolate = Isolate::New(); BEGIN_ISOLATE_SCOPE(this); _Handles.clear(); _DisposedHandles.clear(); _Strings.clear(); _ManagedV8GarbageCollectionRequestCallback = nullptr; _Isolate->SetData(0, this); // (sets a reference in the isolate to the proxy [useful within callbacks]) if ((vector<bool>::size_type)_NextEngineID >= _DisposedEngines.capacity()) _DisposedEngines.resize(_DisposedEngines.capacity() + 32); if (_NextEngineID == 0) _DisposedEngines.clear(); // (need to clear the pre-allocated vector on first use) _DisposedEngines.push_back(false); _EngineID = _NextEngineID++; END_ISOLATE_SCOPE; }
V8EngineProxy::~V8EngineProxy() { if (Type != 0) // (type is 0 if this class was wiped with 0's {if used in a marshalling test}) { lock_guard<recursive_mutex> handleSection(_HandleSystemMutex); BEGIN_ISOLATE_SCOPE(this); // ... empty all handles to be sure they won't be accessed ... for (size_t i = 0; i < _Handles.size(); i++) _Handles[i]->_ClearHandleValue(); // ... flag engine as disposed ... _DisposedEngines[_EngineID] = true; // (this supports cases where the engine may be deleted while proxy objects are still in memory) // (note: once this flag is set, disposing handles causes the proxy instances to be deleted immediately [instead of caching]) // ... deleted disposed proxy handles ... // At this point the *disposed* (and hence, *cached*) proxy handles are no longer associated with managed handles, so the engine is now responsible to delete them) for (size_t i = 0; i < _DisposedHandles.size(); i++) _Handles[_DisposedHandles[i]]->_Dispose(false); // (engine is flagged as disposed, so this call will only delete the instance) // Note: the '_GlobalObjectTemplateProxy' instance is not deleted because the managed GC will do that later (if not before this). _GlobalObjectTemplateProxy = nullptr; _GlobalObject.Reset(); _Context.Reset(); END_ISOLATE_SCOPE; _Isolate->Dispose(); _Isolate = nullptr; // ... free the string cache ... for (size_t i = 0; i < _Strings.size(); i++) _Strings[i].Free(); } }
FunctionTemplateProxy::~FunctionTemplateProxy() { if (Type != 0) // (type is 0 if this class was wiped with 0's {if used in a marshalling test}) { // Note: the '_InstanceTemplate' and '_PrototypeTemplate' instances are not deleted because the managed GC will do that later. _InstanceTemplate = nullptr; _PrototypeTemplate = nullptr; if (!V8EngineProxy::IsDisposed(_EngineID)) { BEGIN_ISOLATE_SCOPE(_EngineProxy); BEGIN_CONTEXT_SCOPE(_EngineProxy); if (!_FunctionTemplate.IsEmpty()) _FunctionTemplate.Reset(); END_CONTEXT_SCOPE; END_ISOLATE_SCOPE; } _EngineProxy = nullptr; } }