[V8] Get rid of function-level static FunctionTemplates in generated bindings code
[WebKit-https.git] / Source / WebCore / bindings / v8 / V8PerIsolateData.cpp
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "V8PerIsolateData.h"
28
29 #include "ScriptGCEvent.h"
30 #include "ScriptProfiler.h"
31 #include "V8Binding.h"
32 #include <wtf/MemoryInstrumentationHashMap.h>
33 #include <wtf/MemoryInstrumentationVector.h>
34
35 namespace WTF {
36
37 // WrapperTypeInfo are statically allocated, don't count them.
38 template<> struct SequenceMemoryInstrumentationTraits<WebCore::WrapperTypeInfo*> {
39     template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
40 };
41
42 }
43
44 namespace WebCore {
45
46 V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate)
47     : m_isolate(isolate)
48     , m_stringCache(adoptPtr(new StringCache()))
49     , m_integerCache(adoptPtr(new IntegerCache()))
50     , m_domDataStore(0)
51     , m_hiddenPropertyName(adoptPtr(new V8HiddenPropertyName()))
52     , m_constructorMode(ConstructorMode::CreateNewObject)
53     , m_recursionLevel(0)
54 #ifndef NDEBUG
55     , m_internalScriptRecursionLevel(0)
56 #endif
57     , m_gcEventData(adoptPtr(new GCEventData()))
58     , m_shouldCollectGarbageSoon(false)
59 {
60     m_v8Null.set(v8::Null(isolate));
61 }
62
63 V8PerIsolateData::~V8PerIsolateData()
64 {
65 }
66
67 V8PerIsolateData* V8PerIsolateData::create(v8::Isolate* isolate)
68 {
69     ASSERT(isolate);
70     ASSERT(!isolate->GetData());
71     V8PerIsolateData* data = new V8PerIsolateData(isolate);
72     isolate->SetData(data);
73     return data;
74 }
75
76 void V8PerIsolateData::ensureInitialized(v8::Isolate* isolate) 
77 {
78     ASSERT(isolate);
79     if (!isolate->GetData()) 
80         create(isolate);
81 }
82
83 v8::Persistent<v8::Value> V8PerIsolateData::ensureLiveRoot()
84 {
85     if (m_liveRoot.isEmpty())
86         m_liveRoot.set(v8::Null());
87     return m_liveRoot.get();
88 }
89
90 void V8PerIsolateData::dispose(v8::Isolate* isolate)
91 {
92     void* data = isolate->GetData();
93     delete static_cast<V8PerIsolateData*>(data);
94     isolate->SetData(0);
95 }
96
97 v8::Handle<v8::FunctionTemplate> V8PerIsolateData::toStringTemplate()
98 {
99     if (m_toStringTemplate.isEmpty())
100         m_toStringTemplate.set(v8::FunctionTemplate::New(constructorOfToString));
101     return v8::Local<v8::FunctionTemplate>::New(m_toStringTemplate.get());
102 }
103
104 void V8PerIsolateData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
105 {
106     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Binding);
107     info.addMember(m_rawTemplates, "rawTemplates");
108     info.addMember(m_templates, "templates");
109     info.addMember(m_stringCache, "stringCache");
110     info.addMember(m_integerCache, "integerCache");
111     info.addMember(m_domDataList, "domDataList");
112     info.addMember(m_domDataStore, "domDataStore");
113     info.addMember(m_hiddenPropertyName, "hiddenPropertyName");
114     info.addMember(m_gcEventData, "gcEventData");
115
116     info.addPrivateBuffer(ScriptProfiler::profilerSnapshotsSize(), WebCoreMemoryTypes::InspectorProfilerAgent, "HeapSnapshots", "snapshots");
117
118     info.ignoreMember(m_toStringTemplate);
119     info.ignoreMember(m_lazyEventListenerToStringTemplate);
120     info.ignoreMember(m_v8Null);
121     info.ignoreMember(m_liveRoot);
122     info.ignoreMember(m_auxiliaryContext);
123 }
124
125 v8::Persistent<v8::FunctionTemplate> V8PerIsolateData::privateTemplate(WrapperWorldType, void* privatePointer, v8::InvocationCallback callback, v8::Handle<v8::Value> data, v8::Handle<v8::Signature> signature, int length)
126 {
127     v8::Persistent<v8::FunctionTemplate> privateTemplate;
128     V8PerIsolateData::TemplateMap::iterator result = m_templates.find(privatePointer);
129     if (result != m_templates.end())
130         return result->value;
131     v8::Persistent<v8::FunctionTemplate> newPrivateTemplate = v8::Persistent<v8::FunctionTemplate>::New(m_isolate, v8::FunctionTemplate::New(callback, data, signature, length));
132     m_templates.add(privatePointer, newPrivateTemplate);
133     return newPrivateTemplate;
134 }
135
136 #if ENABLE(INSPECTOR)
137 void V8PerIsolateData::visitExternalStrings(ExternalStringVisitor* visitor)
138 {
139     v8::HandleScope handleScope;
140     class VisitorImpl : public v8::ExternalResourceVisitor {
141     public:
142         VisitorImpl(ExternalStringVisitor* visitor) : m_visitor(visitor) { }
143         virtual ~VisitorImpl() { }
144         virtual void VisitExternalString(v8::Handle<v8::String> string)
145         {
146             WebCoreStringResourceBase* resource = WebCoreStringResourceBase::toWebCoreStringResourceBase(string);
147             if (resource)
148                 resource->visitStrings(m_visitor);
149         }
150     private:
151         ExternalStringVisitor* m_visitor;
152     } v8Visitor(visitor);
153     v8::V8::VisitExternalResources(&v8Visitor);
154 }
155 #endif
156
157 v8::Handle<v8::Value> V8PerIsolateData::constructorOfToString(const v8::Arguments& args)
158 {
159     // The DOM constructors' toString functions grab the current toString
160     // for Functions by taking the toString function of itself and then
161     // calling it with the constructor as its receiver. This means that
162     // changes to the Function prototype chain or toString function are
163     // reflected when printing DOM constructors. The only wart is that
164     // changes to a DOM constructor's toString's toString will cause the
165     // toString of the DOM constructor itself to change. This is extremely
166     // obscure and unlikely to be a problem.
167     v8::Handle<v8::Value> value = args.Callee()->Get(v8::String::NewSymbol("toString"));
168     if (!value->IsFunction()) 
169         return v8::String::Empty(args.GetIsolate());
170     return v8::Handle<v8::Function>::Cast(value)->Call(args.This(), 0, 0);
171 }
172
173 } // namespace WebCore