source: webkit/trunk/JavaScriptCore/runtime/JSGlobalObject.cpp@ 45609

Last change on this file since 45609 was 44550, checked in by [email protected], 16 years ago

Bug 26249: Support JSON.stringify
<https://bugs.webkit.org/show_bug.cgi?id=26249>

Reviewed by Sam Weinig.

Implement JSON.stringify. This patch handles all the semantics of the ES5
JSON.stringify function, including replacer functions and arrays and both
string and numeric gap arguments.

Currently uses a clamped recursive algorithm basically identical to the spec
description but with a few minor tweaks for performance and corrected semantics
discussed in the es-discuss mailing list.

  • Property svn:eol-style set to native
File size: 22.6 KB
Line 
1/*
2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich ([email protected])
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "JSGlobalObject.h"
32
33#include "JSCallbackConstructor.h"
34#include "JSCallbackFunction.h"
35#include "JSCallbackObject.h"
36
37#include "Arguments.h"
38#include "ArrayConstructor.h"
39#include "ArrayPrototype.h"
40#include "BooleanConstructor.h"
41#include "BooleanPrototype.h"
42#include "CodeBlock.h"
43#include "DateConstructor.h"
44#include "DatePrototype.h"
45#include "ErrorConstructor.h"
46#include "ErrorPrototype.h"
47#include "FunctionConstructor.h"
48#include "FunctionPrototype.h"
49#include "GlobalEvalFunction.h"
50#include "JSFunction.h"
51#include "JSGlobalObjectFunctions.h"
52#include "JSLock.h"
53#include "JSONObject.h"
54#include "Interpreter.h"
55#include "MathObject.h"
56#include "NativeErrorConstructor.h"
57#include "NativeErrorPrototype.h"
58#include "NumberConstructor.h"
59#include "NumberPrototype.h"
60#include "ObjectConstructor.h"
61#include "ObjectPrototype.h"
62#include "Profiler.h"
63#include "PrototypeFunction.h"
64#include "RegExpConstructor.h"
65#include "RegExpMatchesArray.h"
66#include "RegExpObject.h"
67#include "RegExpPrototype.h"
68#include "ScopeChainMark.h"
69#include "StringConstructor.h"
70#include "StringPrototype.h"
71#include "Debugger.h"
72
73namespace JSC {
74
75ASSERT_CLASS_FITS_IN_CELL(JSGlobalObject);
76
77// Default number of ticks before a timeout check should be done.
78static const int initialTickCountThreshold = 255;
79
80// Preferred number of milliseconds between each timeout check
81static const int preferredScriptCheckTimeInterval = 1000;
82
83static inline void markIfNeeded(JSValue v)
84{
85 if (v && !v.marked())
86 v.mark();
87}
88
89static inline void markIfNeeded(const RefPtr<Structure>& s)
90{
91 if (s)
92 s->mark();
93}
94
95JSGlobalObject::~JSGlobalObject()
96{
97 ASSERT(JSLock::currentThreadIsHoldingLock());
98
99 if (d()->debugger)
100 d()->debugger->detach(this);
101
102 Profiler** profiler = Profiler::enabledProfilerReference();
103 if (UNLIKELY(*profiler != 0)) {
104 (*profiler)->stopProfiling(globalExec(), UString());
105 }
106
107 d()->next->d()->prev = d()->prev;
108 d()->prev->d()->next = d()->next;
109 JSGlobalObject*& headObject = head();
110 if (headObject == this)
111 headObject = d()->next;
112 if (headObject == this)
113 headObject = 0;
114
115 HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
116 for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
117 (*it)->clearGlobalObject();
118
119 RegisterFile& registerFile = globalData()->interpreter->registerFile();
120 if (registerFile.globalObject() == this) {
121 registerFile.setGlobalObject(0);
122 registerFile.setNumGlobals(0);
123 }
124 delete d();
125}
126
127void JSGlobalObject::init(JSObject* thisValue)
128{
129 ASSERT(JSLock::currentThreadIsHoldingLock());
130
131 d()->globalData = Heap::heap(this)->globalData();
132 d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), thisValue);
133
134 JSGlobalObject::globalExec()->init(0, 0, d()->globalScopeChain.node(), CallFrame::noCaller(), 0, 0, 0);
135
136 if (JSGlobalObject*& headObject = head()) {
137 d()->prev = headObject;
138 d()->next = headObject->d()->next;
139 headObject->d()->next->d()->prev = this;
140 headObject->d()->next = this;
141 } else
142 headObject = d()->next = d()->prev = this;
143
144 d()->recursion = 0;
145 d()->debugger = 0;
146
147 d()->profileGroup = 0;
148
149 reset(prototype());
150}
151
152void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
153{
154 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
155
156 if (symbolTablePut(propertyName, value))
157 return;
158 JSVariableObject::put(exec, propertyName, value, slot);
159}
160
161void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
162{
163 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
164
165 if (symbolTablePutWithAttributes(propertyName, value, attributes))
166 return;
167
168 JSValue valueBefore = getDirect(propertyName);
169 PutPropertySlot slot;
170 JSVariableObject::put(exec, propertyName, value, slot);
171 if (!valueBefore) {
172 JSValue valueAfter = getDirect(propertyName);
173 if (valueAfter)
174 JSObject::putWithAttributes(exec, propertyName, valueAfter, attributes);
175 }
176}
177
178void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc)
179{
180 PropertySlot slot;
181 if (!symbolTableGet(propertyName, slot))
182 JSVariableObject::defineGetter(exec, propertyName, getterFunc);
183}
184
185void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc)
186{
187 PropertySlot slot;
188 if (!symbolTableGet(propertyName, slot))
189 JSVariableObject::defineSetter(exec, propertyName, setterFunc);
190}
191
192static inline JSObject* lastInPrototypeChain(JSObject* object)
193{
194 JSObject* o = object;
195 while (o->prototype().isObject())
196 o = asObject(o->prototype());
197 return o;
198}
199
200void JSGlobalObject::reset(JSValue prototype)
201{
202 ExecState* exec = JSGlobalObject::globalExec();
203
204 // Prototypes
205
206 d()->functionPrototype = new (exec) FunctionPrototype(exec, FunctionPrototype::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created.
207 d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype);
208 NativeFunctionWrapper* callFunction = 0;
209 NativeFunctionWrapper* applyFunction = 0;
210 d()->functionPrototype->addFunctionProperties(exec, d()->prototypeFunctionStructure.get(), &callFunction, &applyFunction);
211 d()->callFunction = callFunction;
212 d()->applyFunction = applyFunction;
213 d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructure(jsNull()), d()->prototypeFunctionStructure.get());
214 d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype);
215
216 d()->emptyObjectStructure = d()->objectPrototype->inheritorID();
217
218 d()->functionStructure = JSFunction::createStructure(d()->functionPrototype);
219 d()->callbackFunctionStructure = JSCallbackFunction::createStructure(d()->functionPrototype);
220 d()->argumentsStructure = Arguments::createStructure(d()->objectPrototype);
221 d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(d()->objectPrototype);
222 d()->callbackObjectStructure = JSCallbackObject<JSObject>::createStructure(d()->objectPrototype);
223
224 d()->arrayPrototype = new (exec) ArrayPrototype(ArrayPrototype::createStructure(d()->objectPrototype));
225 d()->arrayStructure = JSArray::createStructure(d()->arrayPrototype);
226 d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(d()->arrayPrototype);
227
228 d()->stringPrototype = new (exec) StringPrototype(exec, StringPrototype::createStructure(d()->objectPrototype));
229 d()->stringObjectStructure = StringObject::createStructure(d()->stringPrototype);
230
231 d()->booleanPrototype = new (exec) BooleanPrototype(exec, BooleanPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
232 d()->booleanObjectStructure = BooleanObject::createStructure(d()->booleanPrototype);
233
234 d()->numberPrototype = new (exec) NumberPrototype(exec, NumberPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
235 d()->numberObjectStructure = NumberObject::createStructure(d()->numberPrototype);
236
237 d()->datePrototype = new (exec) DatePrototype(exec, DatePrototype::createStructure(d()->objectPrototype));
238 d()->dateStructure = DateInstance::createStructure(d()->datePrototype);
239
240 d()->regExpPrototype = new (exec) RegExpPrototype(exec, RegExpPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
241 d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype);
242
243 d()->methodCallDummy = constructEmptyObject(exec);
244
245 ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
246 d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
247
248 RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
249
250 NativeErrorPrototype* evalErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "EvalError", "EvalError");
251 NativeErrorPrototype* rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "RangeError", "RangeError");
252 NativeErrorPrototype* referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "ReferenceError", "ReferenceError");
253 NativeErrorPrototype* syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "SyntaxError", "SyntaxError");
254 NativeErrorPrototype* typeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "TypeError", "TypeError");
255 NativeErrorPrototype* URIErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "URIError", "URIError");
256
257 // Constructors
258
259 JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype);
260 JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
261 JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);
262 JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
263 JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
264 JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
265 JSCell* dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
266
267 d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructure(d()->functionPrototype), d()->regExpPrototype);
268
269 d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructure(d()->functionPrototype), errorPrototype);
270
271 RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype);
272
273 d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, evalErrorPrototype);
274 d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, rangeErrorPrototype);
275 d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, referenceErrorPrototype);
276 d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, syntaxErrorPrototype);
277 d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype);
278 d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype);
279
280 d()->objectPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
281 d()->functionPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
282 d()->arrayPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum);
283 d()->booleanPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum);
284 d()->stringPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum);
285 d()->numberPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum);
286 d()->datePrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum);
287 d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
288 errorPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
289
290 evalErrorPrototype->putDirect(exec->propertyNames().constructor, d()->evalErrorConstructor, DontEnum);
291 rangeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->rangeErrorConstructor, DontEnum);
292 referenceErrorPrototype->putDirect(exec->propertyNames().constructor, d()->referenceErrorConstructor, DontEnum);
293 syntaxErrorPrototype->putDirect(exec->propertyNames().constructor, d()->syntaxErrorConstructor, DontEnum);
294 typeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->typeErrorConstructor, DontEnum);
295 URIErrorPrototype->putDirect(exec->propertyNames().constructor, d()->URIErrorConstructor, DontEnum);
296
297 // Set global constructors
298
299 // FIXME: These properties could be handled by a static hash table.
300
301 putDirectFunctionWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum);
302 putDirectFunctionWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum);
303 putDirectFunctionWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum);
304 putDirectFunctionWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
305 putDirectFunctionWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum);
306 putDirectFunctionWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum);
307 putDirectFunctionWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum);
308 putDirectFunctionWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
309 putDirectFunctionWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
310 putDirectFunctionWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor);
311 putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor);
312 putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor);
313 putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor);
314 putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor);
315 putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor);
316
317 // Set global values.
318 GlobalPropertyInfo staticGlobals[] = {
319 GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, MathObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete),
320 GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(exec), DontEnum | DontDelete),
321 GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(exec, Inf), DontEnum | DontDelete),
322 GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete),
323 GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(JSONObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete)
324 };
325
326 addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
327
328 // Set global functions.
329
330 d()->evalFunction = new (exec) GlobalEvalFunction(exec, GlobalEvalFunction::createStructure(d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this);
331 putDirectFunctionWithoutTransition(exec, d()->evalFunction, DontEnum);
332 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
333 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
334 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
335 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
336 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
337 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
338 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
339 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
340 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
341 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
342#ifndef NDEBUG
343 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
344#endif
345
346 resetPrototype(prototype);
347}
348
349// Set prototype, and also insert the object prototype at the end of the chain.
350void JSGlobalObject::resetPrototype(JSValue prototype)
351{
352 setPrototype(prototype);
353
354 JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
355 JSObject* objectPrototype = d()->objectPrototype;
356 if (oldLastInPrototypeChain != objectPrototype)
357 oldLastInPrototypeChain->setPrototype(objectPrototype);
358}
359
360void JSGlobalObject::mark()
361{
362 JSVariableObject::mark();
363
364 HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
365 for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
366 (*it)->mark();
367
368 RegisterFile& registerFile = globalData()->interpreter->registerFile();
369 if (registerFile.globalObject() == this)
370 registerFile.markGlobals(&globalData()->heap);
371
372 markIfNeeded(d()->regExpConstructor);
373 markIfNeeded(d()->errorConstructor);
374 markIfNeeded(d()->evalErrorConstructor);
375 markIfNeeded(d()->rangeErrorConstructor);
376 markIfNeeded(d()->referenceErrorConstructor);
377 markIfNeeded(d()->syntaxErrorConstructor);
378 markIfNeeded(d()->typeErrorConstructor);
379 markIfNeeded(d()->URIErrorConstructor);
380
381 markIfNeeded(d()->evalFunction);
382 markIfNeeded(d()->callFunction);
383 markIfNeeded(d()->applyFunction);
384
385 markIfNeeded(d()->objectPrototype);
386 markIfNeeded(d()->functionPrototype);
387 markIfNeeded(d()->arrayPrototype);
388 markIfNeeded(d()->booleanPrototype);
389 markIfNeeded(d()->stringPrototype);
390 markIfNeeded(d()->numberPrototype);
391 markIfNeeded(d()->datePrototype);
392 markIfNeeded(d()->regExpPrototype);
393
394 markIfNeeded(d()->methodCallDummy);
395
396 markIfNeeded(d()->errorStructure);
397
398 // No need to mark the other structures, because their prototypes are all
399 // guaranteed to be referenced elsewhere.
400
401 Register* registerArray = d()->registerArray.get();
402 if (!registerArray)
403 return;
404
405 size_t size = d()->registerArraySize;
406 for (size_t i = 0; i < size; ++i) {
407 Register& r = registerArray[i];
408 if (!r.marked())
409 r.mark();
410 }
411}
412
413ExecState* JSGlobalObject::globalExec()
414{
415 return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
416}
417
418bool JSGlobalObject::isDynamicScope() const
419{
420 return true;
421}
422
423void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile)
424{
425 ASSERT(!d()->registerArray);
426 ASSERT(!d()->registerArraySize);
427
428 int numGlobals = registerFile.numGlobals();
429 if (!numGlobals) {
430 d()->registers = 0;
431 return;
432 }
433
434 Register* registerArray = copyRegisterArray(registerFile.lastGlobal(), numGlobals);
435 setRegisters(registerArray + numGlobals, registerArray, numGlobals);
436}
437
438void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile)
439{
440 JSGlobalObject* lastGlobalObject = registerFile.globalObject();
441 if (lastGlobalObject && lastGlobalObject != this)
442 lastGlobalObject->copyGlobalsFrom(registerFile);
443
444 registerFile.setGlobalObject(this);
445 registerFile.setNumGlobals(symbolTable().size());
446
447 if (d()->registerArray) {
448 memcpy(registerFile.start() - d()->registerArraySize, d()->registerArray.get(), d()->registerArraySize * sizeof(Register));
449 setRegisters(registerFile.start(), 0, 0);
450 }
451}
452
453void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData)
454{
455#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
456 return globalData->heap.inlineAllocate(size);
457#else
458 return globalData->heap.allocate(size);
459#endif
460}
461
462} // namespace JSC
Note: See TracBrowser for help on using the repository browser.