Chromium Code Reviews| Index: webkit/plugins/npapi/webplugin_impl.cc |
| diff --git a/webkit/plugins/npapi/webplugin_impl.cc b/webkit/plugins/npapi/webplugin_impl.cc |
| index 880cb97804e19056e827256d9fd8fd8a5efd58ac..8875564934e8996dc7d7f97666a8938ee7737aeb 100644 |
| --- a/webkit/plugins/npapi/webplugin_impl.cc |
| +++ b/webkit/plugins/npapi/webplugin_impl.cc |
| @@ -243,10 +243,15 @@ bool WebPluginImpl::initialize(WebPluginContainer* container) { |
| if (!plugin_delegate) |
| return false; |
| + // Store the plugin's unique identifier, used by the container to track its |
| + // script objects. |
| + npp_ = plugin_delegate->GetPluginNPP(); |
| + |
| // Set the container before Initialize because the plugin may |
| - // synchronously call NPN_GetValue to get its container during its |
| - // initialization. |
| + // synchronously call NPN_GetValue to get its container, or make calls |
| + // passing script objects that need to be tracked, during initialization. |
| SetContainer(container); |
| + |
| bool ok = plugin_delegate->Initialize( |
| plugin_url_, arg_names_, arg_values_, this, load_manually_); |
| if (!ok) { |
| @@ -280,6 +285,14 @@ NPObject* WebPluginImpl::scriptableObject() { |
| return delegate_->GetPluginScriptableObject(); |
| } |
| +NPP WebPluginImpl::pluginNPP() { |
| + CHECK(npp_); |
| + // if (!delegate_) |
| + // return NULL; |
| + |
| + return npp_; // delegate_->GetPluginNPP(); |
|
jamesr
2013/05/15 22:32:15
hmm? what's up with the commented-out code here?
Wez
2013/05/15 23:14:16
Sorry, looks like this patch-set is stale. :(
|
| +} |
| + |
| bool WebPluginImpl::getFormValue(WebKit::WebString& value) { |
| if (!delegate_) |
| return false; |
| @@ -475,6 +488,7 @@ WebPluginImpl::WebPluginImpl( |
| webframe_(webframe), |
| delegate_(NULL), |
| container_(NULL), |
| + npp_(NULL), |
| plugin_url_(params.url), |
| load_manually_(params.loadManually), |
| first_geometry_update_(true), |
| @@ -1046,6 +1060,8 @@ void WebPluginImpl::SetContainer(WebPluginContainer* container) { |
| if (!container) |
| TearDownPluginInstance(NULL); |
| container_ = container; |
| + if (container_) |
| + container_->allowScriptObjects(); |
| } |
| void WebPluginImpl::HandleURLRequest(const char* url, |
| @@ -1324,19 +1340,32 @@ bool WebPluginImpl::ReinitializePluginForResponse( |
| void WebPluginImpl::TearDownPluginInstance( |
| WebURLLoader* loader_to_ignore) { |
| - // The container maintains a list of JSObjects which are related to this |
| - // plugin. Tell the frame we're gone so that it can invalidate all of |
| - // those sub JSObjects. |
| + // JavaScript garbage collection may cause plugin script object references to |
| + // be retained long after the plugin is destroyed. Some plugins won't cope |
| + // with their objects being released after they've been destroyed, and once |
| + // we've actually unloaded the plugin the object's releaseobject() code may |
| + // no longer be in memory. The container tracks the plugin's objects and lets |
| + // us invalidate them, releasing the references to them held by the JavaScript |
| + // runtime. |
| if (container_) { |
| container_->clearScriptObjects(); |
| container_->setWebLayer(NULL); |
| } |
| + // Call PluginDestroyed() first to prevent the plugin from calling us back |
| + // in the middle of tearing down the render tree. |
| if (delegate_) { |
| - // Call PluginDestroyed() first to prevent the plugin from calling us back |
| - // in the middle of tearing down the render tree. |
| + // The plugin may call into the browser and pass script objects even during |
| + // teardown, so temporarily re-enable plugin script objects. |
| + DCHECK(container_); |
| + container_->allowScriptObjects(); |
| + |
| delegate_->PluginDestroyed(); |
| delegate_ = NULL; |
| + |
| + // Invalidate any script objects created during teardown here, before the |
| + // plugin might actually be unloaded. |
| + container_->clearScriptObjects(); |
| } |
| // Cancel any pending requests because otherwise this deleted object will |