JavaScriptCore:
[WebKit-https.git] / JavaScriptCore / runtime / JSGlobalData.cpp
1 /*
2  * Copyright (C) 2008 Apple 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "JSGlobalData.h"
31
32 #include "ArgList.h"
33 #include "Collector.h"
34 #include "CommonIdentifiers.h"
35 #include "FunctionConstructor.h"
36 #include "Interpreter.h"
37 #include "JSActivation.h"
38 #include "JSClassRef.h"
39 #include "JSLock.h"
40 #include "JSNotAnObject.h"
41 #include "JSStaticScopeObject.h"
42 #include "Parser.h"
43 #include "Lexer.h"
44 #include "Lookup.h"
45 #include "Nodes.h"
46
47 #if ENABLE(JSC_MULTIPLE_THREADS)
48 #include <wtf/Threading.h>
49 #endif
50
51 #if PLATFORM(MAC)
52 #include "ProfilerServer.h"
53 #endif
54
55 using namespace WTF;
56
57 namespace JSC {
58
59 extern const HashTable arrayTable;
60 extern const HashTable dateTable;
61 extern const HashTable mathTable;
62 extern const HashTable numberTable;
63 extern const HashTable regExpTable;
64 extern const HashTable regExpConstructorTable;
65 extern const HashTable stringTable;
66
67 JSGlobalData::JSGlobalData(bool isShared)
68     : initializingLazyNumericCompareFunction(false)
69     , interpreter(new Interpreter)
70     , exception(noValue())
71     , arrayTable(new HashTable(JSC::arrayTable))
72     , dateTable(new HashTable(JSC::dateTable))
73     , mathTable(new HashTable(JSC::mathTable))
74     , numberTable(new HashTable(JSC::numberTable))
75     , regExpTable(new HashTable(JSC::regExpTable))
76     , regExpConstructorTable(new HashTable(JSC::regExpConstructorTable))
77     , stringTable(new HashTable(JSC::stringTable))
78     , activationStructure(JSActivation::createStructure(jsNull()))
79     , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
80     , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
81     , stringStructure(JSString::createStructure(jsNull()))
82     , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
83     , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
84 #if !USE(ALTERNATE_JSIMMEDIATE)
85     , numberStructure(JSNumberCell::createStructure(jsNull()))
86 #endif
87     , identifierTable(createIdentifierTable())
88     , propertyNames(new CommonIdentifiers(this))
89     , emptyList(new ArgList)
90     , newParserObjects(0)
91     , parserObjectExtraRefCounts(0)
92     , lexer(new Lexer(this))
93     , parser(new Parser)
94     , head(0)
95     , dynamicGlobalObject(0)
96     , isSharedInstance(isShared)
97     , clientData(0)
98     , scopeNodeBeingReparsed(0)
99     , heap(this)
100 {
101 #if PLATFORM(MAC)
102     startProfilerServerIfNeeded();
103 #endif
104     interpreter->initialize(this);
105 }
106
107 JSGlobalData::~JSGlobalData()
108 {
109     // By the time this is destroyed, heap.destroy() must already have been called.
110
111     delete interpreter;
112 #ifndef NDEBUG
113     // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
114     interpreter = 0;
115 #endif
116
117     arrayTable->deleteTable();
118     dateTable->deleteTable();
119     mathTable->deleteTable();
120     numberTable->deleteTable();
121     regExpTable->deleteTable();
122     regExpConstructorTable->deleteTable();
123     stringTable->deleteTable();
124     delete arrayTable;
125     delete dateTable;
126     delete mathTable;
127     delete numberTable;
128     delete regExpTable;
129     delete regExpConstructorTable;
130     delete stringTable;
131
132     delete parser;
133     delete lexer;
134
135     deleteAllValues(opaqueJSClassData);
136
137     delete emptyList;
138
139     delete propertyNames;
140     deleteIdentifierTable(identifierTable);
141
142     delete newParserObjects;
143     delete parserObjectExtraRefCounts;
144     
145     delete clientData;
146 }
147
148 PassRefPtr<JSGlobalData> JSGlobalData::create()
149 {
150     return adoptRef(new JSGlobalData);
151 }
152
153 PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
154 {
155 #ifndef NDEBUG
156     Structure::startIgnoringLeaks();
157     RefPtr<JSGlobalData> data = create();
158     Structure::stopIgnoringLeaks();
159     return data.release();
160 #else
161     return create();
162 #endif
163 }
164
165 bool JSGlobalData::sharedInstanceExists()
166 {
167     return sharedInstanceInternal();
168 }
169
170 JSGlobalData& JSGlobalData::sharedInstance()
171 {
172     JSGlobalData*& instance = sharedInstanceInternal();
173     if (!instance) {
174         instance = new JSGlobalData(true);
175 #if ENABLE(JSC_MULTIPLE_THREADS)
176         instance->makeUsableFromMultipleThreads();
177 #endif
178     }
179     return *instance;
180 }
181
182 JSGlobalData*& JSGlobalData::sharedInstanceInternal()
183 {
184     ASSERT(JSLock::currentThreadIsHoldingLock());
185     static JSGlobalData* sharedInstance;
186     return sharedInstance;
187 }
188
189 // FIXME: We can also detect forms like v1 < v2 ? -1 : 0, reverse comparison, etc.
190 const Vector<Instruction>& JSGlobalData::numericCompareFunction(ExecState* exec)
191 {
192     if (!lazyNumericCompareFunction.size() && !initializingLazyNumericCompareFunction) {
193         initializingLazyNumericCompareFunction = true;
194         RefPtr<ProgramNode> programNode = parser->parse<ProgramNode>(exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
195         RefPtr<FunctionBodyNode> functionBody = extractFunctionBody(programNode.get());
196         lazyNumericCompareFunction = functionBody->bytecode(exec->scopeChain()).instructions();
197         initializingLazyNumericCompareFunction = false;
198     }
199
200     return lazyNumericCompareFunction;
201 }
202
203 JSGlobalData::ClientData::~ClientData()
204 {
205 }
206
207 } // namespace JSC