Index: webkit/port/bindings/v8/v8_proxy.cpp |
=================================================================== |
--- webkit/port/bindings/v8/v8_proxy.cpp (revision 6421) |
+++ webkit/port/bindings/v8/v8_proxy.cpp (working copy) |
@@ -1353,6 +1353,32 @@ |
} |
+v8::Local<v8::Function> V8Proxy::GetConstructor(V8ClassIndex::V8WrapperType t) |
+{ |
+ ASSERT(ContextInitialized()); |
+ v8::Local<v8::Value> cached = |
+ m_dom_constructor_cache->Get(v8::Integer::New(V8ClassIndex::ToInt(t))); |
+ if (cached->IsFunction()) { |
+ return v8::Local<v8::Function>::Cast(cached); |
+ } |
+ |
+ // Not in cache. |
+ { |
+ v8::Handle<v8::FunctionTemplate> templ = GetTemplate(t); |
+ v8::TryCatch try_catch; |
+ // This might fail if we're running out of stack or memory. |
+ v8::Local<v8::Function> value = templ->GetFunction(); |
+ if (value.IsEmpty()) |
+ return v8::Local<v8::Function>(); |
+ m_dom_constructor_cache->Set(v8::Integer::New(t), value); |
+ // Hotmail fix, see comments in v8_proxy.h above |
+ // m_dom_constructor_cache. |
+ value->Set(v8::String::New("__proto__"), m_object_prototype); |
+ return value; |
+ } |
+} |
+ |
+ |
v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate( |
V8ClassIndex::V8WrapperType type) |
{ |
@@ -1803,14 +1829,32 @@ |
} |
+void V8Proxy::DisposeContext() { |
+ ASSERT(!m_context.IsEmpty()); |
+ m_context.Dispose(); |
+ m_context.Clear(); |
+ |
+#ifndef NDEBUG |
+ UnregisterGlobalHandle(this, m_object_prototype); |
+ UnregisterGlobalHandle(this, m_dom_constructor_cache); |
+#endif |
+ |
+ ASSERT(!m_dom_constructor_cache.IsEmpty()); |
+ m_dom_constructor_cache.Dispose(); |
+ m_dom_constructor_cache.Clear(); |
+ |
+ ASSERT(!m_object_prototype.IsEmpty()); |
+ m_object_prototype.Dispose(); |
+ m_object_prototype.Clear(); |
+} |
+ |
void V8Proxy::clearForClose() |
{ |
if (!m_context.IsEmpty()) { |
v8::HandleScope handle_scope; |
ClearDocumentWrapper(); |
- m_context.Dispose(); |
- m_context.Clear(); |
+ DisposeContext(); |
} |
} |
@@ -1840,8 +1884,7 @@ |
// Separate the context from its global object. |
m_context->DetachGlobal(); |
- m_context.Dispose(); |
- m_context.Clear(); |
+ DisposeContext(); |
// Reinitialize the context so the global object points to |
// the new DOM window. |
@@ -2096,12 +2139,23 @@ |
#endif |
} |
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast( |
+ m_global->Get(v8::String::New("Object"))); |
+ m_object_prototype = v8::Persistent<v8::Value>::New( |
+ object->Get(v8::String::New("prototype"))); |
+ m_dom_constructor_cache = v8::Persistent<v8::Array>::New( |
+ v8::Array::New(V8ClassIndex::WRAPPER_TYPE_COUNT)); |
+#ifndef NDEBUG |
+ RegisterGlobalHandle(PROXY, this, m_object_prototype); |
+ RegisterGlobalHandle(PROXY, this, m_dom_constructor_cache); |
+#endif |
+ |
// Create a new JS window object and use it as the prototype for the |
// shadow global object. |
- v8::Persistent<v8::FunctionTemplate> window_descriptor = |
- GetTemplate(V8ClassIndex::DOMWINDOW); |
+ v8::Handle<v8::Function> window_constructor = |
+ GetConstructor(V8ClassIndex::DOMWINDOW); |
v8::Local<v8::Object> js_window = |
- SafeAllocation::NewInstance(window_descriptor->GetFunction()); |
+ SafeAllocation::NewInstance(window_constructor); |
if (js_window.IsEmpty()) |
return; |
@@ -2415,8 +2469,14 @@ |
desc_type = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION; |
} |
- v8::Persistent<v8::FunctionTemplate> desc = GetTemplate(desc_type); |
- v8::Local<v8::Function> function = desc->GetFunction(); |
+ v8::Local<v8::Function> function; |
+ V8Proxy* proxy = V8Proxy::retrieve(); |
+ if (proxy) { |
+ // Constructor is configured. |
+ function = proxy->GetConstructor(desc_type); |
+ } else { |
+ function = GetTemplate(desc_type)->GetFunction(); |
Mads Ager (chromium)
2008/12/06 19:03:36
When do we get in the situation that we cannot use
Feng Qian
2008/12/08 05:49:41
The problem is that it may not get proxy because t
|
+ } |
v8::Local<v8::Object> instance = SafeAllocation::NewInstance(function); |
if (!instance.IsEmpty()) { |
// Avoid setting the DOM wrapper for failed allocations. |