void ScriptController::clearScriptObjects() { PluginObjectMap::iterator it = m_pluginObjects.begin(); for (; it != m_pluginObjects.end(); ++it) { _NPN_UnregisterObject(it->value); _NPN_ReleaseObject(it->value); } m_pluginObjects.clear(); #if ENABLE(NETSCAPE_PLUGIN_API) if (m_wrappedWindowScriptNPObject) { NPObjectWrapper* windowScriptObjectWrapper = NPObjectWrapper::getWrapper(m_wrappedWindowScriptNPObject); ASSERT(windowScriptObjectWrapper); NPObject* windowScriptNPObject = NPObjectWrapper::getUnderlyingNPObject(m_wrappedWindowScriptNPObject); ASSERT(windowScriptNPObject); // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window // script object properly. // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point. _NPN_DeallocateObject(windowScriptNPObject); // Clear out the wrapped window script object pointer held by the wrapper. windowScriptObjectWrapper->clear(); _NPN_ReleaseObject(m_wrappedWindowScriptNPObject); m_wrappedWindowScriptNPObject = 0; } #endif }
PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget) { ASSERT(widget); if (widget->isFrameView()) return 0; #if ENABLE(NETSCAPE_PLUGIN_API) NPObject* npObject = PlatformBridge::pluginScriptableObject(widget); if (!npObject) return 0; // Frame Memory Management for NPObjects // ------------------------------------- // NPObjects are treated differently than other objects wrapped by JS. // NPObjects can be created either by the browser (e.g. the main // window object) or by the plugin (the main plugin object // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame // is especially careful to ensure NPObjects terminate at frame teardown because // if a plugin leaks a reference, it could leak its objects (or the browser's objects). // // The Frame maintains a list of plugin objects (m_pluginObjects) // which it can use to quickly find the wrapped embed object. // // Inside the NPRuntime, we've added a few methods for registering // wrapped NPObjects. The purpose of the registration is because // javascript garbage collection is non-deterministic, yet we need to // be able to tear down the plugin objects immediately. When an object // is registered, javascript can use it. When the object is destroyed, // or when the object's "owning" object is destroyed, the object will // be un-registered, and the javascript engine must not use it. // // Inside the javascript engine, the engine can keep a reference to the // NPObject as part of its wrapper. However, before accessing the object // it must consult the _NPN_Registry. v8::Local<v8::Object> wrapper = createV8ObjectForNPObject(npObject, 0); #ifdef ANDROID_FIX // TODO: this should be up streamed. // HTMLEmbedElement::getInstance() will call this function with its closest // ancestor who has the objectTag. So this "widget" may be already in the // HashMap. If it does, even m_pluginObjects.set() is a no-op, we do need to // call _NPN_ReleaseObject on the npObject to balance the reference count. PluginObjectMap::iterator it = m_pluginObjects.find(widget); if (it != m_pluginObjects.end()) { ASSERT(it->second == npObject); _NPN_ReleaseObject(it->second); } #endif // Track the plugin object. We've been given a reference to the object. m_pluginObjects.set(widget, npObject); return V8ScriptInstance::create(wrapper); #else return 0; #endif }
void HTMLPlugInElement::detach(const AttachContext& context) { // Update the widget the next time we attach (detaching destroys the plugin). // FIXME: None of this "needsWidgetUpdate" related code looks right. if (renderer() && !useFallbackContent()) setNeedsWidgetUpdate(true); if (m_isDelayingLoadEvent) { m_isDelayingLoadEvent = false; document().decrementLoadEventDelayCount(); } // Only try to persist a plugin widget we actually own. Widget* plugin = ownedWidget(); if (plugin && plugin->pluginShouldPersist()) m_persistedPluginWidget = plugin; resetInstance(); // FIXME - is this next line necessary? setWidget(nullptr); if (m_isCapturingMouseEvents) { if (LocalFrame* frame = document().frame()) frame->eventHandler().setCapturingMouseEventsNode(nullptr); m_isCapturingMouseEvents = false; } if (m_NPObject) { _NPN_ReleaseObject(m_NPObject); m_NPObject = 0; } HTMLFrameOwnerElement::detach(context); }
void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle) { PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle); if (it == m_pluginObjects.end()) return; _NPN_UnregisterObject(it->value); _NPN_ReleaseObject(it->value); m_pluginObjects.remove(it); }
void ScriptController::clearScriptObjects() { PluginObjectMap::iterator it = m_pluginObjects.begin(); for (; it != m_pluginObjects.end(); ++it) { _NPN_UnregisterObject(it->value); _NPN_ReleaseObject(it->value); } m_pluginObjects.clear(); if (m_windowScriptNPObject) { // Dispose of the underlying V8 object before releasing our reference // to it, so that if a plugin fails to release it properly we will // only leak the NPObject wrapper, not the object, its document, or // anything else they reference. disposeUnderlyingV8Object(m_isolate, m_windowScriptNPObject); _NPN_ReleaseObject(m_windowScriptNPObject); m_windowScriptNPObject = 0; } }
void forgetV8ObjectForNPObject(NPObject* object) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::HandleScope scope(isolate); v8::Handle<v8::Object> wrapper = staticNPObjectMap().getNewLocal(isolate, object); if (!wrapper.IsEmpty()) { V8DOMWrapper::clearNativeInfo(wrapper, npObjectTypeInfo()); staticNPObjectMap().removeAndDispose(object); _NPN_ReleaseObject(object); } }
void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle) { #if ENABLE(NETSCAPE_PLUGIN_API) PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle); if (it == m_pluginObjects.end()) return; _NPN_UnregisterObject(it->second); _NPN_ReleaseObject(it->second); m_pluginObjects.remove(it); #endif }
inline void DOMWrapperMap<NPObject>::makeWeakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* wrapper, DOMWrapperMap<NPObject>*) { NPObject* npObject = static_cast<NPObject*>(toNative(*wrapper)); ASSERT(npObject); ASSERT(staticNPObjectMap().get(npObject) == *wrapper); // Must remove from our map before calling _NPN_ReleaseObject(). _NPN_ReleaseObject can // call forgetV8ObjectForNPObject, which uses the table as well. staticNPObjectMap().removeAndDispose(npObject); if (_NPN_IsAlive(npObject)) _NPN_ReleaseObject(npObject); }
void _NPN_ReleaseVariantValue (NPVariant *variant) { assert (variant); if (variant->type == NPVariantType_Object) { _NPN_ReleaseObject (variant->value.objectValue); variant->value.objectValue = 0; } else if (variant->type == NPVariantType_String) { free ((void *)variant->value.stringValue.UTF8Characters); variant->value.stringValue.UTF8Characters = 0; variant->value.stringValue.UTF8Length = 0; } variant->type = NPVariantType_Void; }
void ScriptController::clearScriptObjects() { PluginObjectMap::iterator it = m_pluginObjects.begin(); for (; it != m_pluginObjects.end(); ++it) { _NPN_UnregisterObject(it->second); _NPN_ReleaseObject(it->second); } m_pluginObjects.clear(); #if ENABLE(NETSCAPE_PLUGIN_API) if (m_windowScriptNPObject) { // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window // script object properly. // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point. _NPN_DeallocateObject(m_windowScriptNPObject); m_windowScriptNPObject = 0; } #endif }
void WebBindings::releaseObject(NPObject* object) { return _NPN_ReleaseObject(object); }
CInstance::~CInstance() { _NPN_ReleaseObject(_object); }
void NPN_ReleaseObject(NPObject *obj) { _NPN_ReleaseObject(obj); }