1 | /* |
2 | * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. |
3 | * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca) |
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 | |
73 | namespace JSC { |
74 | |
75 | ASSERT_CLASS_FITS_IN_CELL(JSGlobalObject); |
76 | |
77 | // Default number of ticks before a timeout check should be done. |
78 | static const int initialTickCountThreshold = 255; |
79 | |
80 | // Preferred number of milliseconds between each timeout check |
81 | static const int preferredScriptCheckTimeInterval = 1000; |
82 | |
83 | static inline void markIfNeeded(MarkStack& markStack, JSValue v) |
84 | { |
85 | if (v) |
86 | markStack.append(value: v); |
87 | } |
88 | |
89 | static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s) |
90 | { |
91 | if (s) |
92 | markIfNeeded(markStack, v: s->storedPrototype()); |
93 | } |
94 | |
95 | JSGlobalObject::~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(), title: 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<GlobalCodeBlock*>::const_iterator end = codeBlocks().end(); |
116 | for (HashSet<GlobalCodeBlock*>::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 | d()->destructor(d()); |
125 | } |
126 | |
127 | void JSGlobalObject::init(JSObject* thisValue) |
128 | { |
129 | ASSERT(JSLock::currentThreadIsHoldingLock()); |
130 | |
131 | structure()->disableSpecificFunctionTracking(); |
132 | |
133 | d()->globalData = Heap::heap(c: this)->globalData(); |
134 | d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), this, thisValue); |
135 | |
136 | JSGlobalObject::globalExec()->init(codeBlock: 0, vPC: 0, scopeChain: d()->globalScopeChain.node(), callerFrame: CallFrame::noCaller(), returnValueRegister: 0, argc: 0, callee: 0); |
137 | |
138 | if (JSGlobalObject*& headObject = head()) { |
139 | d()->prev = headObject; |
140 | d()->next = headObject->d()->next; |
141 | headObject->d()->next->d()->prev = this; |
142 | headObject->d()->next = this; |
143 | } else |
144 | headObject = d()->next = d()->prev = this; |
145 | |
146 | d()->recursion = 0; |
147 | d()->debugger = 0; |
148 | |
149 | d()->profileGroup = 0; |
150 | |
151 | reset(prototype: prototype()); |
152 | } |
153 | |
154 | void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) |
155 | { |
156 | ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); |
157 | |
158 | if (symbolTablePut(propertyName, value)) |
159 | return; |
160 | JSVariableObject::put(exec, propertyName, value, slot); |
161 | } |
162 | |
163 | void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) |
164 | { |
165 | ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); |
166 | |
167 | if (symbolTablePutWithAttributes(propertyName, value, attributes)) |
168 | return; |
169 | |
170 | JSValue valueBefore = getDirect(propertyName); |
171 | PutPropertySlot slot; |
172 | JSVariableObject::put(exec, propertyName, value, slot); |
173 | if (!valueBefore) { |
174 | JSValue valueAfter = getDirect(propertyName); |
175 | if (valueAfter) |
176 | JSObject::putWithAttributes(exec, propertyName, value: valueAfter, attributes); |
177 | } |
178 | } |
179 | |
180 | void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes) |
181 | { |
182 | PropertySlot slot; |
183 | if (!symbolTableGet(propertyName, slot)) |
184 | JSVariableObject::defineGetter(exec, propertyName, getterFunction: getterFunc, attributes); |
185 | } |
186 | |
187 | void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes) |
188 | { |
189 | PropertySlot slot; |
190 | if (!symbolTableGet(propertyName, slot)) |
191 | JSVariableObject::defineSetter(exec, propertyName, setterFunction: setterFunc, attributes); |
192 | } |
193 | |
194 | static inline JSObject* lastInPrototypeChain(JSObject* object) |
195 | { |
196 | JSObject* o = object; |
197 | while (o->prototype().isObject()) |
198 | o = asObject(value: o->prototype()); |
199 | return o; |
200 | } |
201 | |
202 | void JSGlobalObject::reset(JSValue prototype) |
203 | { |
204 | ExecState* exec = JSGlobalObject::globalExec(); |
205 | |
206 | // Prototypes |
207 | |
208 | d()->functionPrototype = new (exec) FunctionPrototype(exec, FunctionPrototype::createStructure(proto: jsNull())); // The real prototype will be set once ObjectPrototype is created. |
209 | d()->prototypeFunctionStructure = PrototypeFunction::createStructure(proto: d()->functionPrototype); |
210 | NativeFunctionWrapper* callFunction = 0; |
211 | NativeFunctionWrapper* applyFunction = 0; |
212 | d()->functionPrototype->addFunctionProperties(exec, prototypeFunctionStructure: d()->prototypeFunctionStructure.get(), callFunction: &callFunction, applyFunction: &applyFunction); |
213 | d()->callFunction = callFunction; |
214 | d()->applyFunction = applyFunction; |
215 | d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructure(prototype: jsNull()), d()->prototypeFunctionStructure.get()); |
216 | d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype); |
217 | |
218 | d()->emptyObjectStructure = d()->objectPrototype->inheritorID(); |
219 | |
220 | d()->functionStructure = JSFunction::createStructure(prototype: d()->functionPrototype); |
221 | d()->callbackFunctionStructure = JSCallbackFunction::createStructure(proto: d()->functionPrototype); |
222 | d()->argumentsStructure = Arguments::createStructure(prototype: d()->objectPrototype); |
223 | d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(proto: d()->objectPrototype); |
224 | d()->callbackObjectStructure = JSCallbackObject<JSObject>::createStructure(proto: d()->objectPrototype); |
225 | |
226 | d()->arrayPrototype = new (exec) ArrayPrototype(ArrayPrototype::createStructure(prototype: d()->objectPrototype)); |
227 | d()->arrayStructure = JSArray::createStructure(prototype: d()->arrayPrototype); |
228 | d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(prototype: d()->arrayPrototype); |
229 | |
230 | d()->stringPrototype = new (exec) StringPrototype(exec, StringPrototype::createStructure(prototype: d()->objectPrototype)); |
231 | d()->stringObjectStructure = StringObject::createStructure(prototype: d()->stringPrototype); |
232 | |
233 | d()->booleanPrototype = new (exec) BooleanPrototype(exec, BooleanPrototype::createStructure(prototype: d()->objectPrototype), d()->prototypeFunctionStructure.get()); |
234 | d()->booleanObjectStructure = BooleanObject::createStructure(prototype: d()->booleanPrototype); |
235 | |
236 | d()->numberPrototype = new (exec) NumberPrototype(exec, NumberPrototype::createStructure(prototype: d()->objectPrototype), d()->prototypeFunctionStructure.get()); |
237 | d()->numberObjectStructure = NumberObject::createStructure(prototype: d()->numberPrototype); |
238 | |
239 | d()->datePrototype = new (exec) DatePrototype(exec, DatePrototype::createStructure(prototype: d()->objectPrototype)); |
240 | d()->dateStructure = DateInstance::createStructure(prototype: d()->datePrototype); |
241 | |
242 | d()->regExpPrototype = new (exec) RegExpPrototype(exec, RegExpPrototype::createStructure(prototype: d()->objectPrototype), d()->prototypeFunctionStructure.get()); |
243 | d()->regExpStructure = RegExpObject::createStructure(prototype: d()->regExpPrototype); |
244 | |
245 | d()->methodCallDummy = constructEmptyObject(exec); |
246 | |
247 | ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(prototype: d()->objectPrototype), d()->prototypeFunctionStructure.get()); |
248 | d()->errorStructure = ErrorInstance::createStructure(prototype: errorPrototype); |
249 | |
250 | RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(prototype: errorPrototype); |
251 | |
252 | NativeErrorPrototype* evalErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "EvalError" , "EvalError" ); |
253 | NativeErrorPrototype* rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "RangeError" , "RangeError" ); |
254 | NativeErrorPrototype* referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "ReferenceError" , "ReferenceError" ); |
255 | NativeErrorPrototype* syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "SyntaxError" , "SyntaxError" ); |
256 | NativeErrorPrototype* typeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "TypeError" , "TypeError" ); |
257 | NativeErrorPrototype* URIErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "URIError" , "URIError" ); |
258 | |
259 | // Constructors |
260 | |
261 | JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(proto: d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get()); |
262 | JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(proto: d()->functionPrototype), d()->functionPrototype); |
263 | JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(proto: d()->functionPrototype), d()->arrayPrototype, d()->prototypeFunctionStructure.get()); |
264 | JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(proto: d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype); |
265 | JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(proto: d()->functionPrototype), d()->booleanPrototype); |
266 | JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(proto: d()->functionPrototype), d()->numberPrototype); |
267 | JSCell* dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(proto: d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype); |
268 | |
269 | d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructure(prototype: d()->functionPrototype), d()->regExpPrototype); |
270 | |
271 | d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructure(proto: d()->functionPrototype), errorPrototype); |
272 | |
273 | RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(proto: d()->functionPrototype); |
274 | |
275 | d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, evalErrorPrototype); |
276 | d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, rangeErrorPrototype); |
277 | d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, referenceErrorPrototype); |
278 | d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, syntaxErrorPrototype); |
279 | d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype); |
280 | d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype); |
281 | |
282 | d()->objectPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: objectConstructor, attributes: DontEnum); |
283 | d()->functionPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: functionConstructor, attributes: DontEnum); |
284 | d()->arrayPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: arrayConstructor, attributes: DontEnum); |
285 | d()->booleanPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: booleanConstructor, attributes: DontEnum); |
286 | d()->stringPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: stringConstructor, attributes: DontEnum); |
287 | d()->numberPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: numberConstructor, attributes: DontEnum); |
288 | d()->datePrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: dateConstructor, attributes: DontEnum); |
289 | d()->regExpPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: d()->regExpConstructor, attributes: DontEnum); |
290 | errorPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: d()->errorConstructor, attributes: DontEnum); |
291 | |
292 | evalErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->evalErrorConstructor, attributes: DontEnum); |
293 | rangeErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->rangeErrorConstructor, attributes: DontEnum); |
294 | referenceErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->referenceErrorConstructor, attributes: DontEnum); |
295 | syntaxErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->syntaxErrorConstructor, attributes: DontEnum); |
296 | typeErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->typeErrorConstructor, attributes: DontEnum); |
297 | URIErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->URIErrorConstructor, attributes: DontEnum); |
298 | |
299 | // Set global constructors |
300 | |
301 | // FIXME: These properties could be handled by a static hash table. |
302 | |
303 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Object" ), value: objectConstructor, attributes: DontEnum); |
304 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Function" ), value: functionConstructor, attributes: DontEnum); |
305 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Array" ), value: arrayConstructor, attributes: DontEnum); |
306 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Boolean" ), value: booleanConstructor, attributes: DontEnum); |
307 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "String" ), value: stringConstructor, attributes: DontEnum); |
308 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Number" ), value: numberConstructor, attributes: DontEnum); |
309 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Date" ), value: dateConstructor, attributes: DontEnum); |
310 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "RegExp" ), value: d()->regExpConstructor, attributes: DontEnum); |
311 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Error" ), value: d()->errorConstructor, attributes: DontEnum); |
312 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "EvalError" ), value: d()->evalErrorConstructor, attributes: DontEnum); |
313 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "RangeError" ), value: d()->rangeErrorConstructor, attributes: DontEnum); |
314 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "ReferenceError" ), value: d()->referenceErrorConstructor, attributes: DontEnum); |
315 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "SyntaxError" ), value: d()->syntaxErrorConstructor, attributes: DontEnum); |
316 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "TypeError" ), value: d()->typeErrorConstructor, attributes: DontEnum); |
317 | putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "URIError" ), value: d()->URIErrorConstructor, attributes: DontEnum); |
318 | |
319 | // Set global values. |
320 | GlobalPropertyInfo staticGlobals[] = { |
321 | GlobalPropertyInfo(Identifier(exec, "Math" ), new (exec) MathObject(exec, MathObject::createStructure(prototype: d()->objectPrototype)), DontEnum | DontDelete), |
322 | GlobalPropertyInfo(Identifier(exec, "NaN" ), jsNaN(exec), DontEnum | DontDelete), |
323 | GlobalPropertyInfo(Identifier(exec, "Infinity" ), jsNumber(exec, d: Inf), DontEnum | DontDelete), |
324 | GlobalPropertyInfo(Identifier(exec, "undefined" ), jsUndefined(), DontEnum | DontDelete), |
325 | GlobalPropertyInfo(Identifier(exec, "JSON" ), new (exec) JSONObject(JSONObject::createStructure(prototype: d()->objectPrototype)), DontEnum | DontDelete) |
326 | }; |
327 | |
328 | addStaticGlobals(globals: staticGlobals, count: sizeof(staticGlobals) / sizeof(GlobalPropertyInfo)); |
329 | |
330 | // Set global functions. |
331 | |
332 | d()->evalFunction = new (exec) GlobalEvalFunction(exec, GlobalEvalFunction::createStructure(prototype: d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this); |
333 | putDirectFunctionWithoutTransition(exec, function: d()->evalFunction, attr: DontEnum); |
334 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt" ), globalFuncParseInt), attr: DontEnum); |
335 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat" ), globalFuncParseFloat), attr: DontEnum); |
336 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN" ), globalFuncIsNaN), attr: DontEnum); |
337 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite" ), globalFuncIsFinite), attr: DontEnum); |
338 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape" ), globalFuncEscape), attr: DontEnum); |
339 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape" ), globalFuncUnescape), attr: DontEnum); |
340 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI" ), globalFuncDecodeURI), attr: DontEnum); |
341 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent" ), globalFuncDecodeURIComponent), attr: DontEnum); |
342 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI" ), globalFuncEncodeURI), attr: DontEnum); |
343 | putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent" ), globalFuncEncodeURIComponent), attr: DontEnum); |
344 | #ifndef NDEBUG |
345 | #ifndef QT_BUILD_SCRIPT_LIB |
346 | putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint" ), globalFuncJSCPrint), DontEnum); |
347 | #endif |
348 | #endif |
349 | |
350 | resetPrototype(prototype); |
351 | } |
352 | |
353 | // Set prototype, and also insert the object prototype at the end of the chain. |
354 | void JSGlobalObject::resetPrototype(JSValue prototype) |
355 | { |
356 | setPrototype(prototype); |
357 | |
358 | JSObject* oldLastInPrototypeChain = lastInPrototypeChain(object: this); |
359 | JSObject* objectPrototype = d()->objectPrototype; |
360 | if (oldLastInPrototypeChain != objectPrototype) |
361 | oldLastInPrototypeChain->setPrototype(objectPrototype); |
362 | } |
363 | |
364 | void JSGlobalObject::markChildren(MarkStack& markStack) |
365 | { |
366 | JSVariableObject::markChildren(markStack); |
367 | |
368 | HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end(); |
369 | for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) |
370 | (*it)->markAggregate(markStack); |
371 | |
372 | RegisterFile& registerFile = globalData()->interpreter->registerFile(); |
373 | if (registerFile.globalObject() == this) |
374 | registerFile.markGlobals(markStack, heap: &globalData()->heap); |
375 | |
376 | markIfNeeded(markStack, v: d()->regExpConstructor); |
377 | markIfNeeded(markStack, v: d()->errorConstructor); |
378 | markIfNeeded(markStack, v: d()->evalErrorConstructor); |
379 | markIfNeeded(markStack, v: d()->rangeErrorConstructor); |
380 | markIfNeeded(markStack, v: d()->referenceErrorConstructor); |
381 | markIfNeeded(markStack, v: d()->syntaxErrorConstructor); |
382 | markIfNeeded(markStack, v: d()->typeErrorConstructor); |
383 | markIfNeeded(markStack, v: d()->URIErrorConstructor); |
384 | |
385 | markIfNeeded(markStack, v: d()->evalFunction); |
386 | markIfNeeded(markStack, v: d()->callFunction); |
387 | markIfNeeded(markStack, v: d()->applyFunction); |
388 | |
389 | markIfNeeded(markStack, v: d()->objectPrototype); |
390 | markIfNeeded(markStack, v: d()->functionPrototype); |
391 | markIfNeeded(markStack, v: d()->arrayPrototype); |
392 | markIfNeeded(markStack, v: d()->booleanPrototype); |
393 | markIfNeeded(markStack, v: d()->stringPrototype); |
394 | markIfNeeded(markStack, v: d()->numberPrototype); |
395 | markIfNeeded(markStack, v: d()->datePrototype); |
396 | markIfNeeded(markStack, v: d()->regExpPrototype); |
397 | |
398 | markIfNeeded(markStack, v: d()->methodCallDummy); |
399 | |
400 | markIfNeeded(markStack, s: d()->errorStructure); |
401 | markIfNeeded(markStack, s: d()->argumentsStructure); |
402 | markIfNeeded(markStack, s: d()->arrayStructure); |
403 | markIfNeeded(markStack, s: d()->booleanObjectStructure); |
404 | markIfNeeded(markStack, s: d()->callbackConstructorStructure); |
405 | markIfNeeded(markStack, s: d()->callbackFunctionStructure); |
406 | markIfNeeded(markStack, s: d()->callbackObjectStructure); |
407 | markIfNeeded(markStack, s: d()->dateStructure); |
408 | markIfNeeded(markStack, s: d()->emptyObjectStructure); |
409 | markIfNeeded(markStack, s: d()->errorStructure); |
410 | markIfNeeded(markStack, s: d()->functionStructure); |
411 | markIfNeeded(markStack, s: d()->numberObjectStructure); |
412 | markIfNeeded(markStack, s: d()->prototypeFunctionStructure); |
413 | markIfNeeded(markStack, s: d()->regExpMatchesArrayStructure); |
414 | markIfNeeded(markStack, s: d()->regExpStructure); |
415 | markIfNeeded(markStack, s: d()->stringObjectStructure); |
416 | |
417 | // No need to mark the other structures, because their prototypes are all |
418 | // guaranteed to be referenced elsewhere. |
419 | |
420 | Register* registerArray = d()->registerArray.get(); |
421 | if (!registerArray) |
422 | return; |
423 | |
424 | size_t size = d()->registerArraySize; |
425 | markStack.appendValues(values: reinterpret_cast<JSValue*>(registerArray), count: size); |
426 | } |
427 | |
428 | ExecState* JSGlobalObject::globalExec() |
429 | { |
430 | return CallFrame::create(callFrameBase: d()->globalCallFrame + RegisterFile::CallFrameHeaderSize); |
431 | } |
432 | |
433 | bool JSGlobalObject::isDynamicScope() const |
434 | { |
435 | return true; |
436 | } |
437 | |
438 | void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile) |
439 | { |
440 | ASSERT(!d()->registerArray); |
441 | ASSERT(!d()->registerArraySize); |
442 | |
443 | int numGlobals = registerFile.numGlobals(); |
444 | if (!numGlobals) { |
445 | d()->registers = 0; |
446 | return; |
447 | } |
448 | |
449 | Register* registerArray = copyRegisterArray(src: registerFile.lastGlobal(), count: numGlobals); |
450 | setRegisters(registers: registerArray + numGlobals, registerArray, count: numGlobals); |
451 | } |
452 | |
453 | void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile) |
454 | { |
455 | JSGlobalObject* lastGlobalObject = registerFile.globalObject(); |
456 | if (lastGlobalObject && lastGlobalObject != this) |
457 | lastGlobalObject->copyGlobalsFrom(registerFile); |
458 | |
459 | registerFile.setGlobalObject(this); |
460 | registerFile.setNumGlobals(symbolTable().size()); |
461 | |
462 | if (d()->registerArray) { |
463 | memcpy(dest: registerFile.start() - d()->registerArraySize, src: d()->registerArray.get(), n: d()->registerArraySize * sizeof(Register)); |
464 | setRegisters(registers: registerFile.start(), registerArray: 0, count: 0); |
465 | } |
466 | } |
467 | |
468 | void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData) |
469 | { |
470 | return globalData->heap.allocate(size); |
471 | } |
472 | |
473 | void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData) |
474 | { |
475 | delete static_cast<JSGlobalObjectData*>(jsGlobalObjectData); |
476 | } |
477 | |
478 | } // namespace JSC |
479 | |