]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/JSGlobalObject.h
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / runtime / JSGlobalObject.h
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
f9bf01c6 3 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
9dae56ea
A
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#ifndef JSGlobalObject_h
23#define JSGlobalObject_h
24
f9bf01c6 25#include "JSArray.h"
9dae56ea
A
26#include "JSGlobalData.h"
27#include "JSVariableObject.h"
4e4e5a6f 28#include "JSWeakObjectMapRefInternal.h"
9dae56ea
A
29#include "NumberPrototype.h"
30#include "StringPrototype.h"
14957cd0 31#include "StructureChain.h"
9dae56ea
A
32#include <wtf/HashSet.h>
33#include <wtf/OwnPtr.h>
4e4e5a6f 34#include <wtf/RandomNumber.h>
9dae56ea
A
35
36namespace JSC {
37
38 class ArrayPrototype;
39 class BooleanPrototype;
40 class DatePrototype;
41 class Debugger;
42 class ErrorConstructor;
43 class FunctionPrototype;
f9bf01c6 44 class GlobalCodeBlock;
9dae56ea
A
45 class NativeErrorConstructor;
46 class ProgramCodeBlock;
47 class RegExpConstructor;
48 class RegExpPrototype;
49 class RegisterFile;
50
51 struct ActivationStackNode;
52 struct HashTable;
53
54 typedef Vector<ExecState*, 16> ExecStateStack;
f9bf01c6 55
9dae56ea
A
56 class JSGlobalObject : public JSVariableObject {
57 protected:
4e4e5a6f 58 typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
9dae56ea 59
14957cd0
A
60 RefPtr<JSGlobalData> m_globalData;
61
62 size_t m_registerArraySize;
63 Register m_globalCallFrame[RegisterFile::CallFrameHeaderSize];
64
65 WriteBarrier<ScopeChainNode> m_globalScopeChain;
66 WriteBarrier<JSObject> m_methodCallDummy;
67
68 WriteBarrier<RegExpConstructor> m_regExpConstructor;
69 WriteBarrier<ErrorConstructor> m_errorConstructor;
70 WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor;
71 WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor;
72 WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor;
73 WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor;
74 WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
75 WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor;
76
77 WriteBarrier<JSFunction> m_evalFunction;
78 WriteBarrier<JSFunction> m_callFunction;
79 WriteBarrier<JSFunction> m_applyFunction;
80
81 WriteBarrier<ObjectPrototype> m_objectPrototype;
82 WriteBarrier<FunctionPrototype> m_functionPrototype;
83 WriteBarrier<ArrayPrototype> m_arrayPrototype;
84 WriteBarrier<BooleanPrototype> m_booleanPrototype;
85 WriteBarrier<StringPrototype> m_stringPrototype;
86 WriteBarrier<NumberPrototype> m_numberPrototype;
87 WriteBarrier<DatePrototype> m_datePrototype;
88 WriteBarrier<RegExpPrototype> m_regExpPrototype;
89
90 WriteBarrier<Structure> m_argumentsStructure;
91 WriteBarrier<Structure> m_arrayStructure;
92 WriteBarrier<Structure> m_booleanObjectStructure;
93 WriteBarrier<Structure> m_callbackConstructorStructure;
94 WriteBarrier<Structure> m_callbackFunctionStructure;
95 WriteBarrier<Structure> m_callbackObjectStructure;
96 WriteBarrier<Structure> m_dateStructure;
97 WriteBarrier<Structure> m_emptyObjectStructure;
98 WriteBarrier<Structure> m_nullPrototypeObjectStructure;
99 WriteBarrier<Structure> m_errorStructure;
100 WriteBarrier<Structure> m_functionStructure;
101 WriteBarrier<Structure> m_numberObjectStructure;
102 WriteBarrier<Structure> m_regExpMatchesArrayStructure;
103 WriteBarrier<Structure> m_regExpStructure;
104 WriteBarrier<Structure> m_stringObjectStructure;
105 WriteBarrier<Structure> m_internalFunctionStructure;
106
107 unsigned m_profileGroup;
108 Debugger* m_debugger;
109
110 WeakMapSet m_weakMaps;
111 Weak<JSGlobalObject> m_weakMapsFinalizer;
112 class WeakMapsFinalizer : public WeakHandleOwner {
113 public:
114 virtual void finalize(Handle<Unknown>, void* context);
9dae56ea 115 };
14957cd0
A
116 static WeakMapsFinalizer* weakMapsFinalizer();
117
118 WeakRandom m_weakRandom;
119
120 SymbolTable m_symbolTable;
121
122 bool m_isEvalEnabled;
9dae56ea
A
123
124 public:
125 void* operator new(size_t, JSGlobalData*);
126
14957cd0
A
127 explicit JSGlobalObject(JSGlobalData& globalData, Structure* structure)
128 : JSVariableObject(globalData, structure, &m_symbolTable, 0)
129 , m_registerArraySize(0)
130 , m_globalScopeChain()
131 , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
132 , m_isEvalEnabled(true)
9dae56ea 133 {
14957cd0
A
134 COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
135 putThisToAnonymousValue(0);
9dae56ea
A
136 init(this);
137 }
138
14957cd0
A
139 static JS_EXPORTDATA const ClassInfo s_info;
140
9dae56ea 141 protected:
14957cd0
A
142 JSGlobalObject(JSGlobalData& globalData, Structure* structure, JSObject* thisValue)
143 : JSVariableObject(globalData, structure, &m_symbolTable, 0)
144 , m_registerArraySize(0)
145 , m_globalScopeChain()
146 , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
147 , m_isEvalEnabled(true)
9dae56ea 148 {
14957cd0
A
149 COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
150 putThisToAnonymousValue(0);
9dae56ea
A
151 init(thisValue);
152 }
153
154 public:
155 virtual ~JSGlobalObject();
156
14957cd0 157 virtual void visitChildren(SlotVisitor&);
9dae56ea
A
158
159 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
f9bf01c6 160 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
ba379fdc
A
161 virtual bool hasOwnPropertyForWrite(ExecState*, const Identifier&);
162 virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
163 virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes);
9dae56ea 164
f9bf01c6
A
165 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes);
166 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes);
9dae56ea 167
14957cd0
A
168 // We use this in the code generator as we perform symbol table
169 // lookups prior to initializing the properties
170 bool symbolTableHasProperty(const Identifier& propertyName);
9dae56ea
A
171
172 // The following accessors return pristine values, even if a script
173 // replaces the global object's associated property.
174
14957cd0
A
175 RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
176
177 ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }
178 NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); }
179 NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
180 NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); }
181 NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); }
182 NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); }
183 NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); }
184
185 JSFunction* evalFunction() const { return m_evalFunction.get(); }
186 JSFunction* callFunction() const { return m_callFunction.get(); }
187 JSFunction* applyFunction() const { return m_applyFunction.get(); }
188
189 ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
190 FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
191 ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
192 BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); }
193 StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
194 NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); }
195 DatePrototype* datePrototype() const { return m_datePrototype.get(); }
196 RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
197
198 JSObject* methodCallDummy() const { return m_methodCallDummy.get(); }
199
200 Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
201 Structure* arrayStructure() const { return m_arrayStructure.get(); }
202 Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
203 Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
204 Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
205 Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); }
206 Structure* dateStructure() const { return m_dateStructure.get(); }
207 Structure* emptyObjectStructure() const { return m_emptyObjectStructure.get(); }
208 Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); }
209 Structure* errorStructure() const { return m_errorStructure.get(); }
210 Structure* functionStructure() const { return m_functionStructure.get(); }
211 Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
212 Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
213 Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
214 Structure* regExpStructure() const { return m_regExpStructure.get(); }
215 Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
216
217 void setProfileGroup(unsigned value) { m_profileGroup = value; }
218 unsigned profileGroup() const { return m_profileGroup; }
219
220 Debugger* debugger() const { return m_debugger; }
221 void setDebugger(Debugger* debugger) { m_debugger = debugger; }
222
9dae56ea 223 virtual bool supportsProfiling() const { return false; }
14957cd0
A
224 virtual bool supportsRichSourceInfo() const { return true; }
225
226 ScopeChainNode* globalScopeChain() { return m_globalScopeChain.get(); }
9dae56ea
A
227
228 virtual bool isGlobalObject() const { return true; }
229
230 virtual ExecState* globalExec();
231
232 virtual bool shouldInterruptScriptBeforeTimeout() const { return false; }
233 virtual bool shouldInterruptScript() const { return true; }
234
235 virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
236
4e4e5a6f 237 virtual bool isDynamicScope(bool& requiresDynamicChecks) const;
9dae56ea 238
14957cd0
A
239 void disableEval();
240 bool isEvalEnabled() { return m_isEvalEnabled; }
9dae56ea
A
241
242 void copyGlobalsFrom(RegisterFile&);
243 void copyGlobalsTo(RegisterFile&);
14957cd0
A
244 void resizeRegisters(int oldSize, int newSize);
245
246 void resetPrototype(JSGlobalData&, JSValue prototype);
9dae56ea 247
14957cd0 248 JSGlobalData& globalData() const { return *m_globalData.get(); }
9dae56ea 249
14957cd0 250 static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
9dae56ea 251 {
14957cd0 252 return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
9dae56ea
A
253 }
254
4e4e5a6f
A
255 void registerWeakMap(OpaqueJSWeakObjectMap* map)
256 {
14957cd0
A
257 if (!m_weakMapsFinalizer)
258 m_weakMapsFinalizer.set(globalData(), this, weakMapsFinalizer());
259 m_weakMaps.add(map);
4e4e5a6f
A
260 }
261
262 void deregisterWeakMap(OpaqueJSWeakObjectMap* map)
263 {
14957cd0 264 m_weakMaps.remove(map);
4e4e5a6f
A
265 }
266
14957cd0 267 double weakRandomNumber() { return m_weakRandom.get(); }
9dae56ea 268 protected:
f9bf01c6 269
14957cd0
A
270 static const unsigned AnonymousSlotCount = JSVariableObject::AnonymousSlotCount + 1;
271 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
f9bf01c6 272
9dae56ea 273 struct GlobalPropertyInfo {
ba379fdc 274 GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
9dae56ea
A
275 : identifier(i)
276 , value(v)
277 , attributes(a)
278 {
279 }
280
281 const Identifier identifier;
ba379fdc 282 JSValue value;
9dae56ea
A
283 unsigned attributes;
284 };
285 void addStaticGlobals(GlobalPropertyInfo*, int count);
286
287 private:
288 // FIXME: Fold reset into init.
289 void init(JSObject* thisValue);
ba379fdc 290 void reset(JSValue prototype);
9dae56ea 291
14957cd0 292 void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count);
9dae56ea
A
293
294 void* operator new(size_t); // can only be allocated with JSGlobalData
295 };
296
ba379fdc 297 JSGlobalObject* asGlobalObject(JSValue);
9dae56ea 298
ba379fdc 299 inline JSGlobalObject* asGlobalObject(JSValue value)
9dae56ea
A
300 {
301 ASSERT(asObject(value)->isGlobalObject());
302 return static_cast<JSGlobalObject*>(asObject(value));
303 }
304
14957cd0 305 inline void JSGlobalObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count)
9dae56ea
A
306 {
307 JSVariableObject::setRegisters(registers, registerArray);
14957cd0 308 m_registerArraySize = count;
f9bf01c6
A
309 }
310
ba379fdc 311 inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, const Identifier& propertyName)
9dae56ea 312 {
ba379fdc
A
313 PropertySlot slot;
314 if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
9dae56ea 315 return true;
ba379fdc 316 bool slotIsWriteable;
9dae56ea
A
317 return symbolTableGet(propertyName, slot, slotIsWriteable);
318 }
319
14957cd0
A
320 inline bool JSGlobalObject::symbolTableHasProperty(const Identifier& propertyName)
321 {
322 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
323 return !entry.isNull();
324 }
325
ba379fdc 326 inline JSValue Structure::prototypeForLookup(ExecState* exec) const
9dae56ea
A
327 {
328 if (typeInfo().type() == ObjectType)
14957cd0 329 return m_prototype.get();
9dae56ea 330
ba379fdc
A
331 ASSERT(typeInfo().type() == StringType);
332 return exec->lexicalGlobalObject()->stringPrototype();
9dae56ea
A
333 }
334
335 inline StructureChain* Structure::prototypeChain(ExecState* exec) const
336 {
337 // We cache our prototype chain so our clients can share it.
338 if (!isValid(exec, m_cachedPrototypeChain.get())) {
ba379fdc 339 JSValue prototype = prototypeForLookup(exec);
14957cd0 340 m_cachedPrototypeChain.set(exec->globalData(), this, StructureChain::create(exec->globalData(), prototype.isNull() ? 0 : asObject(prototype)->structure()));
9dae56ea
A
341 }
342 return m_cachedPrototypeChain.get();
343 }
344
345 inline bool Structure::isValid(ExecState* exec, StructureChain* cachedPrototypeChain) const
346 {
347 if (!cachedPrototypeChain)
348 return false;
349
ba379fdc 350 JSValue prototype = prototypeForLookup(exec);
14957cd0 351 WriteBarrier<Structure>* cachedStructure = cachedPrototypeChain->head();
9dae56ea 352 while(*cachedStructure && !prototype.isNull()) {
14957cd0 353 if (asObject(prototype)->structure() != cachedStructure->get())
9dae56ea
A
354 return false;
355 ++cachedStructure;
356 prototype = asObject(prototype)->prototype();
357 }
358 return prototype.isNull() && !*cachedStructure;
359 }
360
361 inline JSGlobalObject* ExecState::dynamicGlobalObject()
362 {
363 if (this == lexicalGlobalObject()->globalExec())
364 return lexicalGlobalObject();
365
366 // For any ExecState that's not a globalExec, the
367 // dynamic global object must be set since code is running
368 ASSERT(globalData().dynamicGlobalObject);
369 return globalData().dynamicGlobalObject;
370 }
371
14957cd0 372 inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject)
f9bf01c6 373 {
14957cd0 374 return constructEmptyObject(exec, globalObject->emptyObjectStructure());
f9bf01c6 375 }
14957cd0
A
376
377 inline JSObject* constructEmptyObject(ExecState* exec)
f9bf01c6 378 {
14957cd0 379 return constructEmptyObject(exec, exec->lexicalGlobalObject());
f9bf01c6
A
380 }
381
14957cd0 382 inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject)
f9bf01c6 383 {
14957cd0 384 return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure());
f9bf01c6
A
385 }
386
14957cd0
A
387 inline JSArray* constructEmptyArray(ExecState* exec)
388 {
389 return constructEmptyArray(exec, exec->lexicalGlobalObject());
390 }
391
392 inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject, unsigned initialLength)
f9bf01c6 393 {
14957cd0 394 return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), initialLength, CreateInitialized);
f9bf01c6
A
395 }
396
397 inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
398 {
14957cd0 399 return constructEmptyArray(exec, exec->lexicalGlobalObject(), initialLength);
f9bf01c6
A
400 }
401
14957cd0 402 inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, JSValue singleItemValue)
f9bf01c6
A
403 {
404 MarkedArgumentBuffer values;
405 values.append(singleItemValue);
14957cd0
A
406 return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), values);
407 }
408
409 inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
410 {
411 return constructArray(exec, exec->lexicalGlobalObject(), singleItemValue);
412 }
413
414 inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const ArgList& values)
415 {
416 return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), values);
f9bf01c6
A
417 }
418
419 inline JSArray* constructArray(ExecState* exec, const ArgList& values)
420 {
14957cd0 421 return constructArray(exec, exec->lexicalGlobalObject(), values);
f9bf01c6
A
422 }
423
14957cd0
A
424 class DynamicGlobalObjectScope {
425 WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope);
9dae56ea 426 public:
14957cd0 427 DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*);
9dae56ea
A
428
429 ~DynamicGlobalObjectScope()
430 {
431 m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject;
432 }
433
434 private:
435 JSGlobalObject*& m_dynamicGlobalObjectSlot;
436 JSGlobalObject* m_savedDynamicGlobalObject;
437 };
438
439} // namespace JSC
440
441#endif // JSGlobalObject_h