summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorager@chromium.org <ager@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-09 14:38:09 +0000
committerager@chromium.org <ager@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-09 14:38:09 +0000
commitb045a67113c1d3c511aed76d618732d6a251919a (patch)
treee2624b3029e3f05757c96d8355dd36d06ca94e3f /webkit
parentf39b11ef0d10b596df75782bf8db0f7f494abc8f (diff)
downloadchromium_src-b045a67113c1d3c511aed76d618732d6a251919a.zip
chromium_src-b045a67113c1d3c511aed76d618732d6a251919a.tar.gz
chromium_src-b045a67113c1d3c511aed76d618732d6a251919a.tar.bz2
Reapply caching of the document JavaScript wrapper on the global
object. Because initialization of a context can now instantiate a document wrapper, we have to be careful if the context initialization happens when attempting to create that very same document wrapper. We therefore make sure that the context is initialized before checking if a node already has a wrapper. Review URL: http://codereview.chromium.org/118430 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17939 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/port/bindings/v8/v8_proxy.cpp55
-rw-r--r--webkit/port/bindings/v8/v8_proxy.h8
2 files changed, 51 insertions, 12 deletions
diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp
index 85b963f..0494044 100644
--- a/webkit/port/bindings/v8/v8_proxy.cpp
+++ b/webkit/port/bindings/v8/v8_proxy.cpp
@@ -1791,6 +1791,24 @@ void V8Proxy::ClearDocumentWrapper()
}
+void V8Proxy::UpdateDocumentWrapperCache()
+{
+ v8::HandleScope handle_scope;
+ v8::Context::Scope context_scope(GetContext());
+ v8::Handle<v8::Value> document_wrapper = NodeToV8Object(m_frame->document());
+ m_context->Global()->ForceSet(v8::String::New("document"),
+ document_wrapper,
+ static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
+}
+
+
+void V8Proxy::ClearDocumentWrapperCache()
+{
+ ASSERT(!m_context.IsEmpty());
+ m_context->Global()->ForceDelete(v8::String::New("document"));
+}
+
+
void V8Proxy::DisposeContextHandles() {
if (!m_context.IsEmpty()) {
m_context.Dispose();
@@ -1836,6 +1854,11 @@ void V8Proxy::clearForNavigation()
v8::Context::Scope context_scope(m_context);
+ // Clear the document wrapper cache before turning on access checks on
+ // the old DOMWindow wrapper. This way, access to the document wrapper
+ // will be protected by the security checks on the DOMWindow wrapper.
+ ClearDocumentWrapperCache();
+
// Turn on access check on the old DOMWindow wrapper.
v8::Handle<v8::Object> wrapper =
LookupDOMWrapper(V8ClassIndex::DOMWINDOW, m_global);
@@ -1900,10 +1923,10 @@ void V8Proxy::updateDocument()
return;
}
- {
- v8::HandleScope scope;
- SetSecurityToken();
- }
+ // We have a new document and we need to update the cache.
+ UpdateDocumentWrapperCache();
+
+ updateSecurityOrigin();
}
void V8Proxy::updateSecurityOrigin()
@@ -2181,6 +2204,8 @@ void V8Proxy::InitContextIfNeeded()
v8::Handle<v8::Object> v8_global = context->Global();
v8_global->Set(implicit_proto_string, js_window);
+ updateDocument();
+
SetSecurityToken();
m_frame->loader()->dispatchWindowObjectAvailable();
@@ -2908,6 +2933,19 @@ v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node)
{
if (!node) return v8::Null();
+ // Find the context to which the node belongs and create the wrapper
+ // in that context. If the node is not in a document, the current
+ // context is used.
+ //
+ // Getting the context might initialize the context which can instantiate
+ // a document wrapper. Therefore, we get the context before checking if
+ // the node already has a wrapper.
+ v8::Local<v8::Context> context;
+ Document* doc = node->document();
+ if (doc) {
+ context = V8Proxy::GetContext(doc->frame());
+ }
+
v8::Handle<v8::Object> wrapper = getDOMNodeMap().get(node);
if (!wrapper.IsEmpty())
return wrapper;
@@ -2973,14 +3011,7 @@ v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node)
type = V8ClassIndex::NODE;
}
- // Find the context to which the node belongs and create the wrapper
- // in that context. If the node is not in a document, the current
- // context is used.
- v8::Local<v8::Context> context;
- Document* doc = node->document();
- if (doc) {
- context = V8Proxy::GetContext(doc->frame());
- }
+ // Enter the node's context and create the wrapper in that context.
if (!context.IsEmpty()) {
context->Enter();
}
diff --git a/webkit/port/bindings/v8/v8_proxy.h b/webkit/port/bindings/v8/v8_proxy.h
index a00c5f9..5fe78bf 100644
--- a/webkit/port/bindings/v8/v8_proxy.h
+++ b/webkit/port/bindings/v8/v8_proxy.h
@@ -502,6 +502,14 @@ class V8Proxy {
void SetSecurityToken();
void ClearDocumentWrapper();
void UpdateDocumentWrapper(v8::Handle<v8::Value> wrapper);
+
+ // The JavaScript wrapper for the document object is cached on the global
+ // object for fast access. UpdateDocumentWrapperCache sets the wrapper
+ // for the current document on the global object. ClearDocumentWrapperCache
+ // deletes the document wrapper from the global object.
+ void UpdateDocumentWrapperCache();
+ void ClearDocumentWrapperCache();
+
// Dispose global handles of m_contexts and friends.
void DisposeContextHandles();