source: webkit/trunk/JavaScriptCore/kjs/JSGlobalObject.h@ 36693

Last change on this file since 36693 was 36675, checked in by Darin Adler, 17 years ago

JavaScriptCore:

2008-09-19 Darin Adler <Darin Adler>

Reviewed by Sam Weinig.

  • JavaScriptCore.exp: Exported constructEmptyObject for use in WebCore.
  • kjs/JSGlobalObject.h: Changed the protected constructor to take a structure instead of a prototype.
  • kjs/JSVariableObject.h: Removed constructor that takes a prototype.

WebCore:

2008-09-19 Darin Adler <Darin Adler>

Reviewed by Sam Weinig.

+ Fixed all cases where we were using a shared structure for multiple

C++ classes in WebCore. This still has to be done in JavaScriptCore.

+ Got rid of cacheGlobalObject.

+ Improved use of PassRefPtr in bindings code.

+ Removed a couple cases where we were potentially allocating prototypes

inside a JSObject's construction process -- this can lead to trouble if
we do a garbage collection while an object is only partly constructed.

  • bindings/js/JSAudioConstructor.cpp: (WebCore::JSAudioConstructor::JSAudioConstructor): Create a structure explicitly so we don't implicitly share the structure with other objects that use the object prototype.
  • bindings/js/JSDOMBinding.cpp: (WebCore::getCachedDOMConstructor): Added. To be used for constructors so we don't need cacheGlobalObject any more. (WebCore::cacheDOMConstructor): Ditto.
  • bindings/js/JSDOMBinding.h: Removed DOMObject constructor that takes a prototype. Added functions and a function template for getting cached DOM constructors. Removed cacheGlobalObject function template.
  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::JSDOMWindowBase): Take a PassRefPtr<DOMWindow> since we're taking ownership.
  • bindings/js/JSDOMWindowBase.h: Changed constructor to take PassRefPtr, since we're taking ownership. Added constructor map.
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::mark): Mark the constructors in the map.
  • bindings/js/JSDOMWindowShell.cpp: (WebCore::JSDOMWindowShell::JSDOMWindowShell): Take a PassRefPtr<DOMWindow> since we're taking ownership. Use the new setWindow function to create the JSDOMWindow; this is now done in only that one place. (WebCore::JSDOMWindowShell::setWindow): Added. Creates the JSDOMWindow based on the passed-in DOMWindow. Code was moved here and changed to allocate unique structures for both the window prototype and the window.
  • bindings/js/JSDOMWindowShell.h: Ditto.
  • bindings/js/JSEventTargetBase.h: Changed class template argument so it doesn't have the same name (JSEventTarget) as an actual class. Removed unhelpful use of private/friend in JSEventTargetBase. Removed comments referring to defunct macros. Changed JSEventTargetBasePrototype to get the prototype with the new rather than its own copy of cacheGlobalObject (I missed this during pass 1). Changed JSEventTargetBasePrototype so it doesn't have so many template arguments.
  • bindings/js/JSEventTargetNode.cpp: Added s_info; needed for the new scheme for caching structures and prototypes. (WebCore::JSEventTargetNode::JSEventTargetNode): Use PassRefPtr. (WebCore::JSEventTargetNode::createPrototype): Added.
  • bindings/js/JSEventTargetNode.h: Updated for above changes.
  • bindings/js/JSHTMLAllCollection.h: (WebCore::JSHTMLAllCollection::JSHTMLAllCollection): Use PassRefPtr.
  • bindings/js/JSHTMLCollectionCustom.cpp: (WebCore::getNamedItems): Pass ExecState instead of prototype.
  • bindings/js/JSHTMLFormElementCustom.cpp: (WebCore::JSHTMLFormElement::nameGetter): Ditto.
  • bindings/js/JSHTMLInputElementBase.cpp: (WebCore::JSHTMLInputElementBase::JSHTMLInputElementBase): Use PassRefPtr.
  • bindings/js/JSHTMLInputElementBase.h: Ditto.
  • bindings/js/JSHTMLOptionElementConstructor.cpp: (WebCore::JSHTMLOptionElementConstructor::JSHTMLOptionElementConstructor): Create a unique structure instead of sharing.
  • bindings/js/JSImageConstructor.cpp: (WebCore::JSImageConstructor::JSImageConstructor): Ditto.
  • bindings/js/JSInspectedObjectWrapper.cpp: (WebCore::JSInspectedObjectWrapper::wrap): Removed overload that takes a prototype rather than a structure. Made the use of inheritorID() here explicit.
  • bindings/js/JSInspectedObjectWrapper.h: Ditto.
  • bindings/js/JSInspectorCallbackWrapper.cpp: (WebCore::JSInspectorCallbackWrapper::wrap): Ditto.
  • bindings/js/JSInspectorCallbackWrapper.h: Ditto.
  • bindings/js/JSNamedNodesCollection.cpp: (WebCore::JSNamedNodesCollection::JSNamedNodesCollection): Changed to take an ExecState argument instead of a prototype. Create a unique StructureID instead of sharing.
  • bindings/js/JSNamedNodesCollection.h: Ditto.
  • bindings/js/JSQuarantinedObjectWrapper.cpp: Removed overloaded constructor that takes a prototype instead of a structure.
  • bindings/js/JSQuarantinedObjectWrapper.h: Ditto.
  • bindings/js/JSRGBColor.cpp: (WebCore::JSRGBColor::JSRGBColor): Take ExecState instead of a prototype; create a unique structure. (WebCore::getJSRGBColor): Ditto.
  • bindings/js/JSRGBColor.h: Ditto.
  • bindings/js/JSSQLResultSetRowListCustom.cpp: (WebCore::JSSQLResultSetRowList::item): Use constructEmptyObject instead of explicit coding the idiom for making a new object.
  • bindings/js/JSXMLHttpRequestConstructor.cpp: (WebCore::JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor): Create a unique structure instead of the shared one.
  • bindings/js/JSXSLTProcessorConstructor.cpp: (WebCore::JSXSLTProcessorConstructor::JSXSLTProcessorConstructor): Ditto.
  • bindings/js/ScriptController.cpp: (WebCore::ScriptController::clearWindowShell): Let the window shell's setWindow function create the JSDOMWindow instead of doing it here.
  • bindings/scripts/CodeGeneratorJS.pm: Changed to use PassRefPtr for the structure and the wrapped object when creating wrappers. Simplified some of the special cases for DOMWindow so they are different only in ways the need to be. Eliminated the JSDOMWindow::createPrototype and JSDOMWindowPrototype::self functions. Moved responsibility for creating the structure and parent prototype out of the prototype constructor into the createPrototype function. Removed the unused "DoNotCache" flag for objects other than DOMWindow. Use getDOMConstructor instead of cacheGlobalObject for constructors. Make each constructor have a unique structure ID.
  • bridge/objc/objc_runtime.h: Added createPrototype and changed the name of the info member to s_info so we can use the standard DOM binding macros to handl the prototype.
  • bridge/objc/objc_runtime.mm: Fixed namespacing a bit. (JSC::Bindings::ObjcFallbackObjectImp::ObjcFallbackObjectImp): Create a unique structure using getDOMStructure.
  • bridge/runtime_array.cpp: Fixed namespacing a bit. (JSC::RuntimeArray::RuntimeArray): Create a unique structure using getDOMStructure.
  • bridge/runtime_array.h: Added createPrototype so getDOMStructure will work.
  • bridge/runtime_object.cpp: (JSC::RuntimeObjectImp::RuntimeObjectImp): Create a unique structure using getDOMStructure.
  • bridge/runtime_object.h: Added createPrototype so getDOMStructure will work.
  • history/CachedPage.cpp: (WebCore::CachedPage::restore): Let the window shell's setWindow function create the JSDOMWindow instead of doing it here.
  • page/DOMWindow.idl: Removed DoNotCache, which is no longer used.
  • Property svn:eol-style set to native
File size: 12.2 KB
Line 
1/*
2 * Copyright (C) 2007 Eric Seidel <[email protected]>
3 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
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
25#include "JSGlobalData.h"
26#include "JSVariableObject.h"
27#include "NumberPrototype.h"
28#include "StringPrototype.h"
29#include <wtf/HashSet.h>
30#include <wtf/OwnPtr.h>
31
32namespace JSC {
33
34 class ArrayPrototype;
35 class BooleanPrototype;
36 class DatePrototype;
37 class Debugger;
38 class ErrorConstructor;
39 class ErrorPrototype;
40 class EvalError;
41 class EvalErrorPrototype;
42 class FunctionPrototype;
43 class GlobalEvalFunction;
44 class JSGlobalObject;
45 class NativeErrorConstructor;
46 class NativeErrorPrototype;
47 class NumberPrototype;
48 class ObjectPrototype;
49 class ProgramCodeBlock;
50 class RangeError;
51 class RangeErrorPrototype;
52 class ReferenceError;
53 class ReferenceError;
54 class ReferenceErrorPrototype;
55 class RegExpConstructor;
56 class RegExpPrototype;
57 class RegisterFile;
58 class RuntimeMethod;
59 class ScopeChain;
60 class StringPrototype;
61 class SyntaxErrorPrototype;
62 class TypeError;
63 class TypeErrorPrototype;
64 class UriError;
65 class UriErrorPrototype;
66
67 struct ActivationStackNode;
68 struct HashTable;
69
70 typedef Vector<ExecState*, 16> ExecStateStack;
71
72 class JSGlobalObject : public JSVariableObject {
73 protected:
74 using JSVariableObject::JSVariableObjectData;
75
76 struct JSGlobalObjectData : public JSVariableObjectData {
77 JSGlobalObjectData(JSGlobalObject* globalObject, JSObject* thisValue)
78 : JSVariableObjectData(&symbolTable, 0)
79 , globalScopeChain(globalObject, thisValue)
80 {
81 }
82
83 virtual ~JSGlobalObjectData()
84 {
85 }
86
87 JSGlobalObject* next;
88 JSGlobalObject* prev;
89
90 Debugger* debugger;
91
92 ScopeChain globalScopeChain;
93 OwnPtr<ExecState> globalExec;
94
95 int recursion;
96
97 RegExpConstructor* regExpConstructor;
98 ErrorConstructor* errorConstructor;
99 NativeErrorConstructor* evalErrorConstructor;
100 NativeErrorConstructor* rangeErrorConstructor;
101 NativeErrorConstructor* referenceErrorConstructor;
102 NativeErrorConstructor* syntaxErrorConstructor;
103 NativeErrorConstructor* typeErrorConstructor;
104 NativeErrorConstructor* URIErrorConstructor;
105
106 GlobalEvalFunction* evalFunction;
107
108 ObjectPrototype* objectPrototype;
109 FunctionPrototype* functionPrototype;
110 ArrayPrototype* arrayPrototype;
111 BooleanPrototype* booleanPrototype;
112 StringPrototype* stringPrototype;
113 NumberPrototype* numberPrototype;
114 DatePrototype* datePrototype;
115 RegExpPrototype* regExpPrototype;
116 ErrorPrototype* errorPrototype;
117 NativeErrorPrototype* evalErrorPrototype;
118 NativeErrorPrototype* rangeErrorPrototype;
119 NativeErrorPrototype* referenceErrorPrototype;
120 NativeErrorPrototype* syntaxErrorPrototype;
121 NativeErrorPrototype* typeErrorPrototype;
122 NativeErrorPrototype* URIErrorPrototype;
123
124 SymbolTable symbolTable;
125 unsigned profileGroup;
126
127 RefPtr<JSGlobalData> globalData;
128
129 HashSet<ProgramCodeBlock*> codeBlocks;
130
131 OwnPtr<HashSet<JSObject*> > arrayVisitedElements; // Global data shared by array prototype functions.
132 };
133
134 public:
135 void* operator new(size_t, JSGlobalData*);
136
137 JSGlobalObject(JSGlobalData* globalData)
138 : JSVariableObject(globalData->nullProtoStructureID, new JSGlobalObjectData(this, this))
139 {
140 init(this);
141 }
142
143 protected:
144 JSGlobalObject(PassRefPtr<StructureID> structure, JSGlobalObjectData* data, JSObject* globalThisValue)
145 : JSVariableObject(structure, data)
146 {
147 init(globalThisValue);
148 }
149
150 public:
151 virtual ~JSGlobalObject();
152
153 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
154 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
155 virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
156 virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
157
158 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc);
159 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
160
161 // Linked list of all global objects that use the same JSGlobalData.
162 JSGlobalObject*& head() { return d()->globalData->head; }
163 JSGlobalObject* next() { return d()->next; }
164
165 // The following accessors return pristine values, even if a script
166 // replaces the global object's associated property.
167
168 RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor; }
169
170 ErrorConstructor* errorConstructor() const { return d()->errorConstructor; }
171 NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor; }
172 NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor; }
173 NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor; }
174 NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor; }
175 NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor; }
176 NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor; }
177
178 GlobalEvalFunction* evalFunction() const { return d()->evalFunction; }
179
180 ObjectPrototype* objectPrototype() const { return d()->objectPrototype; }
181 FunctionPrototype* functionPrototype() const { return d()->functionPrototype; }
182 ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype; }
183 BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype; }
184 StringPrototype* stringPrototype() const { return d()->stringPrototype; }
185 NumberPrototype* numberPrototype() const { return d()->numberPrototype; }
186 DatePrototype* datePrototype() const { return d()->datePrototype; }
187 RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
188 ErrorPrototype* errorPrototype() const { return d()->errorPrototype; }
189 NativeErrorPrototype* evalErrorPrototype() const { return d()->evalErrorPrototype; }
190 NativeErrorPrototype* rangeErrorPrototype() const { return d()->rangeErrorPrototype; }
191 NativeErrorPrototype* referenceErrorPrototype() const { return d()->referenceErrorPrototype; }
192 NativeErrorPrototype* syntaxErrorPrototype() const { return d()->syntaxErrorPrototype; }
193 NativeErrorPrototype* typeErrorPrototype() const { return d()->typeErrorPrototype; }
194 NativeErrorPrototype* URIErrorPrototype() const { return d()->URIErrorPrototype; }
195
196 void setProfileGroup(unsigned value) { d()->profileGroup = value; }
197 unsigned profileGroup() const { return d()->profileGroup; }
198
199 void setTimeoutTime(unsigned timeoutTime);
200 void startTimeoutCheck();
201 void stopTimeoutCheck();
202
203 Debugger* debugger() const { return d()->debugger; }
204 void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
205
206 int recursion() { return d()->recursion; }
207 void incRecursion() { ++d()->recursion; }
208 void decRecursion() { --d()->recursion; }
209
210 ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
211
212 virtual void mark();
213
214 virtual bool isGlobalObject() const { return true; }
215 virtual JSGlobalObject* toGlobalObject(ExecState*) const;
216
217 virtual ExecState* globalExec();
218
219 virtual bool shouldInterruptScript() const { return true; }
220
221 virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
222
223 virtual bool isDynamicScope() const;
224
225 HashSet<JSObject*>& arrayVisitedElements() { if (!d()->arrayVisitedElements) d()->arrayVisitedElements.set(new HashSet<JSObject*>); return *d()->arrayVisitedElements; }
226
227 HashSet<ProgramCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
228
229 void copyGlobalsFrom(RegisterFile&);
230 void copyGlobalsTo(RegisterFile&);
231
232 void resetPrototype(JSValue* prototype);
233
234 JSGlobalData* globalData() { return d()->globalData.get(); }
235 JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
236
237 protected:
238 struct GlobalPropertyInfo {
239 GlobalPropertyInfo(const Identifier& i, JSValue* v, unsigned a)
240 : identifier(i)
241 , value(v)
242 , attributes(a)
243 {
244 }
245
246 const Identifier identifier;
247 JSValue* value;
248 unsigned attributes;
249 };
250 void addStaticGlobals(GlobalPropertyInfo*, int count);
251
252 private:
253 // FIXME: Fold these functions into the constructor.
254 void init(JSObject* thisValue);
255 void reset(JSValue* prototype);
256
257 void* operator new(size_t); // can only be allocated with JSGlobalData
258 };
259
260 inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
261 {
262 size_t registerArraySize = d()->registerArraySize;
263 Register* registerArray = new Register[registerArraySize + count];
264 if (d()->registerArray)
265 memcpy(registerArray + count, d()->registerArray.get(), registerArraySize * sizeof(Register));
266 setRegisterArray(registerArray, registerArraySize + count);
267
268 for (int i = 0, index = -static_cast<int>(registerArraySize) - 1; i < count; ++i, --index) {
269 GlobalPropertyInfo& global = globals[i];
270 ASSERT(global.attributes & DontDelete);
271 SymbolTableEntry newEntry(index, global.attributes);
272 symbolTable().add(global.identifier.ustring().rep(), newEntry);
273 registerAt(index) = global.value;
274 }
275 }
276
277 inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
278 {
279 if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
280 return true;
281 return symbolTableGet(propertyName, slot);
282 }
283
284 inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
285 {
286 if (JSVariableObject::getOwnPropertySlotForWrite(exec, propertyName, slot, slotIsWriteable))
287 return true;
288 return symbolTableGet(propertyName, slot, slotIsWriteable);
289 }
290
291 inline JSGlobalObject* ScopeChainNode::globalObject() const
292 {
293 JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(bottom());
294 ASSERT(globalObject->isGlobalObject());
295 return globalObject;
296 }
297
298 inline JSValue* StructureID::prototypeForLookup(ExecState* exec)
299 {
300 if (m_type == ObjectType)
301 return m_prototype;
302
303 if (m_type == StringType)
304 return exec->lexicalGlobalObject()->stringPrototype();
305
306 ASSERT(m_type == NumberType);
307 return exec->lexicalGlobalObject()->numberPrototype();
308 }
309
310} // namespace JSC
311
312#endif // JSGlobalObject_h
Note: See TracBrowser for help on using the repository browser.