diff options
author | fqian@google.com <fqian@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-10 04:09:48 +0000 |
---|---|---|
committer | fqian@google.com <fqian@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-10 04:09:48 +0000 |
commit | 564eee25d576db623bd6b648b28b9b649e2a1b8b (patch) | |
tree | c80ce94a65a351febd62d23c9a63fe1d0d0ae128 /webkit/port | |
parent | efecec54fc5177976a766d94b4e8be2e444078c1 (diff) | |
download | chromium_src-564eee25d576db623bd6b648b28b9b649e2a1b8b.zip chromium_src-564eee25d576db623bd6b648b28b9b649e2a1b8b.tar.gz chromium_src-564eee25d576db623bd6b648b28b9b649e2a1b8b.tar.bz2 |
Patch for bug 1994:
Make sure that customized properties set on window.location and window.navigator survive
GC. Matches Safari and Firefox's behaviors.
Review URL: http://codereview.chromium.org/1884
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1973 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port')
-rw-r--r-- | webkit/port/bindings/v8/v8_custom.h | 21 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.cpp | 40 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.h | 5 | ||||
-rw-r--r-- | webkit/port/page/Navigator.h | 2 |
4 files changed, 59 insertions, 9 deletions
diff --git a/webkit/port/bindings/v8/v8_custom.h b/webkit/port/bindings/v8/v8_custom.h index b22854f..d501362 100644 --- a/webkit/port/bindings/v8/v8_custom.h +++ b/webkit/port/bindings/v8/v8_custom.h @@ -22,26 +22,31 @@ class V8Custom { // Constants. static const int kDOMWrapperObjectIndex = 0; static const int kDOMWrapperTypeIndex = 1; - static const int kDefaultWrapperInternalFieldCount = - kDOMWrapperTypeIndex + 1; + static const int kDefaultWrapperInternalFieldCount = 2; - static const int kDocumentMinimumInternalFieldCount = - kDefaultWrapperInternalFieldCount + 1; static const int kDocumentImplementationIndex = kDefaultWrapperInternalFieldCount + 0; + static const int kDocumentMinimumInternalFieldCount = + kDefaultWrapperInternalFieldCount + 1; - static const int kHTMLDocumentInternalFieldCount = - kDocumentMinimumInternalFieldCount + 2; static const int kHTMLDocumentMarkerIndex = kDocumentMinimumInternalFieldCount + 0; static const int kHTMLDocumentShadowIndex = kDocumentMinimumInternalFieldCount + 1; + static const int kHTMLDocumentInternalFieldCount = + kDocumentMinimumInternalFieldCount + 2; - static const int kXMLHttpRequestInternalFieldCount = - kDefaultWrapperInternalFieldCount + 1; static const int kXMLHttpRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0; + static const int kXMLHttpRequestInternalFieldCount = + kDefaultWrapperInternalFieldCount + 1; + static const int kDOMWindowLocationIndex = + kDefaultWrapperInternalFieldCount + 0; + static const int kDOMWindowNavigatorIndex = + kDefaultWrapperInternalFieldCount + 1; + static const int kDOMWindowInternalFieldCount = + kDefaultWrapperInternalFieldCount + 2; #define DECLARE_PROPERTY_ACCESSOR_GETTER(NAME) \ static v8::Handle<v8::Value> v8##NAME##AccessorGetter(\ diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp index d9152ed..184063e 100644 --- a/webkit/port/bindings/v8/v8_proxy.cpp +++ b/webkit/port/bindings/v8/v8_proxy.cpp @@ -55,6 +55,7 @@ #include "HTMLOptionsCollection.h" #include "Page.h" #include "DOMWindow.h" +#include "Location.h" #include "Navigator.h" // for MimeTypeArray #include "V8DOMWindow.h" #include "V8HTMLElement.h" @@ -1245,7 +1246,12 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate( default_signature), v8::None); desc->SetHiddenPrototype(true); - + + // Reserve spaces for references to location and navigator objects. + v8::Local<v8::ObjectTemplate> instance_template = + desc->InstanceTemplate(); + instance_template->SetInternalFieldCount( + V8Custom::kDOMWindowInternalFieldCount); break; } case V8ClassIndex::LOCATION: { @@ -1834,12 +1840,44 @@ v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type, if (!v8obj.IsEmpty()) { result = v8::Persistent<v8::Object>::New(v8obj); dom_object_map().set(obj, result); + + // Special case for Location and Navigator. Both Safari and FF let + // Location and Navigator JS wrappers survive GC. To mimic their + // behaviors, V8 creates hidden references from the DOMWindow to + // location and navigator objects. These references get cleared + // when the DOMWindow is reused by a new page. + if (type == V8ClassIndex::LOCATION) { + SetHiddenWindowReference(static_cast<Location*>(imp)->frame(), + V8Custom::kDOMWindowLocationIndex, result); + } else if (type == V8ClassIndex::NAVIGATOR) { + SetHiddenWindowReference(static_cast<Navigator*>(imp)->frame(), + V8Custom::kDOMWindowNavigatorIndex, result); + } } } return result; } +void V8Proxy::SetHiddenWindowReference(Frame* frame, + const int internal_index, + v8::Handle<v8::Object> jsobj) { + // Get DOMWindow + if (!frame) return; // Object might be detached from window + v8::Handle<v8::Context> context = GetContext(frame); + if (context.IsEmpty()) return; + + ASSERT(internal_index < V8Custom::kDOMWindowInternalFieldCount); + + v8::Handle<v8::Object> global = context->Global(); + ASSERT(!global.IsEmpty()); + // Look for real DOM wrapper. + global = LookupDOMWrapper(V8ClassIndex::DOMWINDOW, global); + ASSERT(global->GetInternalField(internal_index)->IsUndefined()); + global->SetInternalField(internal_index, jsobj); +} + + V8ClassIndex::V8WrapperType V8Proxy::GetDOMWrapperType( v8::Handle<v8::Object> object) { if (!MaybeDOMWrapper(object)) { diff --git a/webkit/port/bindings/v8/v8_proxy.h b/webkit/port/bindings/v8/v8_proxy.h index 23d1f95..e426cc7 100644 --- a/webkit/port/bindings/v8/v8_proxy.h +++ b/webkit/port/bindings/v8/v8_proxy.h @@ -437,6 +437,11 @@ class V8Proxy { Peerable* object, V8ClassIndex::V8WrapperType type); #endif + // Set hidden references in a DOMWindow object of a frame. + static void SetHiddenWindowReference(Frame* frame, + const int internal_index, + v8::Handle<v8::Object> jsobj); + static V8ClassIndex::V8WrapperType GetHTMLElementType(HTMLElement* elm); static v8::Local<v8::Object> InstantiateV8Object( diff --git a/webkit/port/page/Navigator.h b/webkit/port/page/Navigator.h index 90660a7..983daea 100644 --- a/webkit/port/page/Navigator.h +++ b/webkit/port/page/Navigator.h @@ -243,6 +243,8 @@ class Navigator : public RefCounted<Navigator> { return m_frame->settings()->isJavaEnabled(); } + Frame* frame() { return m_frame; } + void disconnectFrame() { m_frame = NULL; } private: |