2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
31 #include "JSGlobalObject.h"
33 #include "Arguments.h"
34 #include "ArrayConstructor.h"
35 #include "ArrayPrototype.h"
36 #include "BooleanConstructor.h"
37 #include "BooleanPrototype.h"
38 #include "CodeBlock.h"
39 #include "CodeCache.h"
40 #include "DateConstructor.h"
41 #include "DatePrototype.h"
44 #include "ErrorConstructor.h"
45 #include "ErrorPrototype.h"
46 #include "FunctionConstructor.h"
47 #include "FunctionPrototype.h"
48 #include "GetterSetter.h"
49 #include "Interpreter.h"
50 #include "JSAPIWrapperObject.h"
51 #include "JSActivation.h"
52 #include "JSBoundFunction.h"
53 #include "JSCallbackConstructor.h"
54 #include "JSCallbackFunction.h"
55 #include "JSCallbackObject.h"
56 #include "JSFunction.h"
57 #include "JSGlobalObjectFunctions.h"
59 #include "JSNameScope.h"
60 #include "JSONObject.h"
61 #include "JSWithScope.h"
62 #include "LegacyProfiler.h"
64 #include "MathObject.h"
65 #include "NameConstructor.h"
66 #include "NameInstance.h"
67 #include "NamePrototype.h"
68 #include "NativeErrorConstructor.h"
69 #include "NativeErrorPrototype.h"
70 #include "NumberConstructor.h"
71 #include "NumberPrototype.h"
72 #include "ObjCCallbackFunction.h"
73 #include "ObjectConstructor.h"
74 #include "ObjectPrototype.h"
75 #include "Operations.h"
76 #include "ParserError.h"
77 #include "RegExpConstructor.h"
78 #include "RegExpMatchesArray.h"
79 #include "RegExpObject.h"
80 #include "RegExpPrototype.h"
81 #include "StrictEvalActivation.h"
82 #include "StringConstructor.h"
83 #include "StringPrototype.h"
85 #include "JSGlobalObject.lut.h"
89 const ClassInfo
JSGlobalObject::s_info
= { "GlobalObject", &Base::s_info
, 0, ExecState::globalObjectTable
, CREATE_METHOD_TABLE(JSGlobalObject
) };
91 const GlobalObjectMethodTable
JSGlobalObject::s_globalObjectMethodTable
= { &allowsAccessFrom
, &supportsProfiling
, &supportsRichSourceInfo
, &shouldInterruptScript
, &javaScriptExperimentsEnabled
93 , &shouldInterruptScriptBeforeTimeout
97 /* Source for JSGlobalObject.lut.h
98 @begin globalObjectTable
99 parseInt globalFuncParseInt DontEnum|Function 2
100 parseFloat globalFuncParseFloat DontEnum|Function 1
101 isNaN globalFuncIsNaN DontEnum|Function 1
102 isFinite globalFuncIsFinite DontEnum|Function 1
103 escape globalFuncEscape DontEnum|Function 1
104 unescape globalFuncUnescape DontEnum|Function 1
105 decodeURI globalFuncDecodeURI DontEnum|Function 1
106 decodeURIComponent globalFuncDecodeURIComponent DontEnum|Function 1
107 encodeURI globalFuncEncodeURI DontEnum|Function 1
108 encodeURIComponent globalFuncEncodeURIComponent DontEnum|Function 1
112 JSGlobalObject::JSGlobalObject(VM
& vm
, Structure
* structure
, const GlobalObjectMethodTable
* globalObjectMethodTable
)
113 : Base(vm
, structure
, 0)
114 , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(InitializedWatching
)))
115 , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(InitializedWatching
)))
116 , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits
<unsigned>::max() + 1.0)))
117 , m_evalEnabled(true)
118 , m_globalObjectMethodTable(globalObjectMethodTable
? globalObjectMethodTable
: &s_globalObjectMethodTable
)
122 JSGlobalObject::~JSGlobalObject()
125 m_debugger
->detach(this);
127 if (LegacyProfiler
* profiler
= vm().enabledProfiler())
128 profiler
->stopProfiling(this);
131 void JSGlobalObject::destroy(JSCell
* cell
)
133 static_cast<JSGlobalObject
*>(cell
)->JSGlobalObject::~JSGlobalObject();
136 void JSGlobalObject::setGlobalThis(VM
& vm
, JSObject
* globalThis
)
138 m_globalThis
.set(vm
, this, globalThis
);
141 void JSGlobalObject::init(JSObject
* thisValue
)
143 ASSERT(vm().apiLock().currentThreadIsHoldingLock());
145 setGlobalThis(vm(), thisValue
);
146 JSGlobalObject::globalExec()->init(0, 0, this, CallFrame::noCaller(), 0, 0);
153 void JSGlobalObject::put(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
, JSValue value
, PutPropertySlot
& slot
)
155 JSGlobalObject
* thisObject
= jsCast
<JSGlobalObject
*>(cell
);
156 ASSERT(!Heap::heap(value
) || Heap::heap(value
) == Heap::heap(thisObject
));
158 if (symbolTablePut(thisObject
, exec
, propertyName
, value
, slot
.isStrictMode()))
160 Base::put(thisObject
, exec
, propertyName
, value
, slot
);
163 void JSGlobalObject::putDirectVirtual(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, JSValue value
, unsigned attributes
)
165 JSGlobalObject
* thisObject
= jsCast
<JSGlobalObject
*>(object
);
166 ASSERT(!Heap::heap(value
) || Heap::heap(value
) == Heap::heap(thisObject
));
168 if (symbolTablePutWithAttributes(thisObject
, exec
->vm(), propertyName
, value
, attributes
))
171 JSValue valueBefore
= thisObject
->getDirect(exec
->vm(), propertyName
);
172 PutPropertySlot slot
;
173 Base::put(thisObject
, exec
, propertyName
, value
, slot
);
175 JSValue valueAfter
= thisObject
->getDirect(exec
->vm(), propertyName
);
177 JSObject::putDirectVirtual(thisObject
, exec
, propertyName
, valueAfter
, attributes
);
181 bool JSGlobalObject::defineOwnProperty(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertyDescriptor
& descriptor
, bool shouldThrow
)
183 JSGlobalObject
* thisObject
= jsCast
<JSGlobalObject
*>(object
);
185 // silently ignore attempts to add accessors aliasing vars.
186 if (descriptor
.isAccessorDescriptor() && symbolTableGet(thisObject
, propertyName
, slot
))
188 return Base::defineOwnProperty(thisObject
, exec
, propertyName
, descriptor
, shouldThrow
);
192 static inline JSObject
* lastInPrototypeChain(JSObject
* object
)
194 JSObject
* o
= object
;
195 while (o
->prototype().isObject())
196 o
= asObject(o
->prototype());
200 void JSGlobalObject::reset(JSValue prototype
)
202 ExecState
* exec
= JSGlobalObject::globalExec();
204 m_functionPrototype
.set(exec
->vm(), this, FunctionPrototype::create(exec
, this, FunctionPrototype::createStructure(exec
->vm(), this, jsNull()))); // The real prototype will be set once ObjectPrototype is created.
205 m_functionStructure
.set(exec
->vm(), this, JSFunction::createStructure(exec
->vm(), this, m_functionPrototype
.get()));
206 m_boundFunctionStructure
.set(exec
->vm(), this, JSBoundFunction::createStructure(exec
->vm(), this, m_functionPrototype
.get()));
207 m_namedFunctionStructure
.set(exec
->vm(), this, Structure::addPropertyTransition(exec
->vm(), m_functionStructure
.get(), exec
->vm().propertyNames
->name
, DontDelete
| ReadOnly
| DontEnum
, 0, m_functionNameOffset
));
208 m_internalFunctionStructure
.set(exec
->vm(), this, InternalFunction::createStructure(exec
->vm(), this, m_functionPrototype
.get()));
209 JSFunction
* callFunction
= 0;
210 JSFunction
* applyFunction
= 0;
211 m_functionPrototype
->addFunctionProperties(exec
, this, &callFunction
, &applyFunction
);
212 m_callFunction
.set(exec
->vm(), this, callFunction
);
213 m_applyFunction
.set(exec
->vm(), this, applyFunction
);
214 m_objectPrototype
.set(exec
->vm(), this, ObjectPrototype::create(exec
, this, ObjectPrototype::createStructure(exec
->vm(), this, jsNull())));
215 GetterSetter
* protoAccessor
= GetterSetter::create(exec
);
216 protoAccessor
->setGetter(exec
->vm(), JSFunction::create(exec
, this, 0, String(), globalFuncProtoGetter
));
217 protoAccessor
->setSetter(exec
->vm(), JSFunction::create(exec
, this, 0, String(), globalFuncProtoSetter
));
218 m_objectPrototype
->putDirectAccessor(exec
, exec
->propertyNames().underscoreProto
, protoAccessor
, Accessor
| DontEnum
);
219 m_functionPrototype
->structure()->setPrototypeWithoutTransition(exec
->vm(), m_objectPrototype
.get());
221 m_nameScopeStructure
.set(exec
->vm(), this, JSNameScope::createStructure(exec
->vm(), this, jsNull()));
222 m_activationStructure
.set(exec
->vm(), this, JSActivation::createStructure(exec
->vm(), this, jsNull()));
223 m_strictEvalActivationStructure
.set(exec
->vm(), this, StrictEvalActivation::createStructure(exec
->vm(), this, jsNull()));
224 m_withScopeStructure
.set(exec
->vm(), this, JSWithScope::createStructure(exec
->vm(), this, jsNull()));
226 m_nullPrototypeObjectStructure
.set(exec
->vm(), this, JSFinalObject::createStructure(vm(), this, jsNull(), JSFinalObject::defaultInlineCapacity()));
228 m_callbackFunctionStructure
.set(exec
->vm(), this, JSCallbackFunction::createStructure(exec
->vm(), this, m_functionPrototype
.get()));
229 m_argumentsStructure
.set(exec
->vm(), this, Arguments::createStructure(exec
->vm(), this, m_objectPrototype
.get()));
230 m_callbackConstructorStructure
.set(exec
->vm(), this, JSCallbackConstructor::createStructure(exec
->vm(), this, m_objectPrototype
.get()));
231 m_callbackObjectStructure
.set(exec
->vm(), this, JSCallbackObject
<JSDestructibleObject
>::createStructure(exec
->vm(), this, m_objectPrototype
.get()));
232 #if JSC_OBJC_API_ENABLED
233 m_objcCallbackFunctionStructure
.set(exec
->vm(), this, ObjCCallbackFunction::createStructure(exec
->vm(), this, m_functionPrototype
.get()));
234 m_objcWrapperObjectStructure
.set(exec
->vm(), this, JSCallbackObject
<JSAPIWrapperObject
>::createStructure(exec
->vm(), this, m_objectPrototype
.get()));
237 m_arrayPrototype
.set(exec
->vm(), this, ArrayPrototype::create(exec
, this, ArrayPrototype::createStructure(exec
->vm(), this, m_objectPrototype
.get())));
239 m_originalArrayStructureForIndexingShape
[UndecidedShape
>> IndexingShapeShift
].set(exec
->vm(), this, JSArray::createStructure(exec
->vm(), this, m_arrayPrototype
.get(), ArrayWithUndecided
));
240 m_originalArrayStructureForIndexingShape
[Int32Shape
>> IndexingShapeShift
].set(exec
->vm(), this, JSArray::createStructure(exec
->vm(), this, m_arrayPrototype
.get(), ArrayWithInt32
));
241 m_originalArrayStructureForIndexingShape
[DoubleShape
>> IndexingShapeShift
].set(exec
->vm(), this, JSArray::createStructure(exec
->vm(), this, m_arrayPrototype
.get(), ArrayWithDouble
));
242 m_originalArrayStructureForIndexingShape
[ContiguousShape
>> IndexingShapeShift
].set(exec
->vm(), this, JSArray::createStructure(exec
->vm(), this, m_arrayPrototype
.get(), ArrayWithContiguous
));
243 m_originalArrayStructureForIndexingShape
[ArrayStorageShape
>> IndexingShapeShift
].set(exec
->vm(), this, JSArray::createStructure(exec
->vm(), this, m_arrayPrototype
.get(), ArrayWithArrayStorage
));
244 m_originalArrayStructureForIndexingShape
[SlowPutArrayStorageShape
>> IndexingShapeShift
].set(exec
->vm(), this, JSArray::createStructure(exec
->vm(), this, m_arrayPrototype
.get(), ArrayWithSlowPutArrayStorage
));
245 for (unsigned i
= 0; i
< NumberOfIndexingShapes
; ++i
)
246 m_arrayStructureForIndexingShapeDuringAllocation
[i
] = m_originalArrayStructureForIndexingShape
[i
];
248 m_regExpMatchesArrayStructure
.set(exec
->vm(), this, RegExpMatchesArray::createStructure(exec
->vm(), this, m_arrayPrototype
.get()));
250 m_stringPrototype
.set(exec
->vm(), this, StringPrototype::create(exec
, this, StringPrototype::createStructure(exec
->vm(), this, m_objectPrototype
.get())));
251 m_stringObjectStructure
.set(exec
->vm(), this, StringObject::createStructure(exec
->vm(), this, m_stringPrototype
.get()));
253 m_booleanPrototype
.set(exec
->vm(), this, BooleanPrototype::create(exec
, this, BooleanPrototype::createStructure(exec
->vm(), this, m_objectPrototype
.get())));
254 m_booleanObjectStructure
.set(exec
->vm(), this, BooleanObject::createStructure(exec
->vm(), this, m_booleanPrototype
.get()));
256 m_numberPrototype
.set(exec
->vm(), this, NumberPrototype::create(exec
, this, NumberPrototype::createStructure(exec
->vm(), this, m_objectPrototype
.get())));
257 m_numberObjectStructure
.set(exec
->vm(), this, NumberObject::createStructure(exec
->vm(), this, m_numberPrototype
.get()));
259 m_datePrototype
.set(exec
->vm(), this, DatePrototype::create(exec
, this, DatePrototype::createStructure(exec
->vm(), this, m_objectPrototype
.get())));
260 m_dateStructure
.set(exec
->vm(), this, DateInstance::createStructure(exec
->vm(), this, m_datePrototype
.get()));
262 RegExp
* emptyRegex
= RegExp::create(exec
->vm(), "", NoFlags
);
264 m_regExpPrototype
.set(exec
->vm(), this, RegExpPrototype::create(exec
, this, RegExpPrototype::createStructure(exec
->vm(), this, m_objectPrototype
.get()), emptyRegex
));
265 m_regExpStructure
.set(exec
->vm(), this, RegExpObject::createStructure(exec
->vm(), this, m_regExpPrototype
.get()));
267 m_errorPrototype
.set(exec
->vm(), this, ErrorPrototype::create(exec
, this, ErrorPrototype::createStructure(exec
->vm(), this, m_objectPrototype
.get())));
268 m_errorStructure
.set(exec
->vm(), this, ErrorInstance::createStructure(exec
->vm(), this, m_errorPrototype
.get()));
272 JSCell
* objectConstructor
= ObjectConstructor::create(exec
, this, ObjectConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_objectPrototype
.get());
273 JSCell
* functionConstructor
= FunctionConstructor::create(exec
, this, FunctionConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_functionPrototype
.get());
274 JSCell
* arrayConstructor
= ArrayConstructor::create(exec
, this, ArrayConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_arrayPrototype
.get());
275 JSCell
* stringConstructor
= StringConstructor::create(exec
, this, StringConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_stringPrototype
.get());
276 JSCell
* booleanConstructor
= BooleanConstructor::create(exec
, this, BooleanConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_booleanPrototype
.get());
277 JSCell
* numberConstructor
= NumberConstructor::create(exec
, this, NumberConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_numberPrototype
.get());
278 JSCell
* dateConstructor
= DateConstructor::create(exec
, this, DateConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_datePrototype
.get());
280 m_regExpConstructor
.set(exec
->vm(), this, RegExpConstructor::create(exec
, this, RegExpConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_regExpPrototype
.get()));
282 m_errorConstructor
.set(exec
->vm(), this, ErrorConstructor::create(exec
, this, ErrorConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), m_errorPrototype
.get()));
284 Structure
* nativeErrorPrototypeStructure
= NativeErrorPrototype::createStructure(exec
->vm(), this, m_errorPrototype
.get());
285 Structure
* nativeErrorStructure
= NativeErrorConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get());
286 m_evalErrorConstructor
.set(exec
->vm(), this, NativeErrorConstructor::create(exec
, this, nativeErrorStructure
, nativeErrorPrototypeStructure
, ASCIILiteral("EvalError")));
287 m_rangeErrorConstructor
.set(exec
->vm(), this, NativeErrorConstructor::create(exec
, this, nativeErrorStructure
, nativeErrorPrototypeStructure
, ASCIILiteral("RangeError")));
288 m_referenceErrorConstructor
.set(exec
->vm(), this, NativeErrorConstructor::create(exec
, this, nativeErrorStructure
, nativeErrorPrototypeStructure
, ASCIILiteral("ReferenceError")));
289 m_syntaxErrorConstructor
.set(exec
->vm(), this, NativeErrorConstructor::create(exec
, this, nativeErrorStructure
, nativeErrorPrototypeStructure
, ASCIILiteral("SyntaxError")));
290 m_typeErrorConstructor
.set(exec
->vm(), this, NativeErrorConstructor::create(exec
, this, nativeErrorStructure
, nativeErrorPrototypeStructure
, ASCIILiteral("TypeError")));
291 m_URIErrorConstructor
.set(exec
->vm(), this, NativeErrorConstructor::create(exec
, this, nativeErrorStructure
, nativeErrorPrototypeStructure
, ASCIILiteral("URIError")));
293 m_objectPrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, objectConstructor
, DontEnum
);
294 m_functionPrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, functionConstructor
, DontEnum
);
295 m_arrayPrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, arrayConstructor
, DontEnum
);
296 m_booleanPrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, booleanConstructor
, DontEnum
);
297 m_stringPrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, stringConstructor
, DontEnum
);
298 m_numberPrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, numberConstructor
, DontEnum
);
299 m_datePrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, dateConstructor
, DontEnum
);
300 m_regExpPrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, m_regExpConstructor
.get(), DontEnum
);
301 m_errorPrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, m_errorConstructor
.get(), DontEnum
);
303 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().Object
, objectConstructor
, DontEnum
);
304 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().Function
, functionConstructor
, DontEnum
);
305 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().Array
, arrayConstructor
, DontEnum
);
306 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().Boolean
, booleanConstructor
, DontEnum
);
307 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().String
, stringConstructor
, DontEnum
);
308 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().Number
, numberConstructor
, DontEnum
);
309 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().Date
, dateConstructor
, DontEnum
);
310 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().RegExp
, m_regExpConstructor
.get(), DontEnum
);
311 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().Error
, m_errorConstructor
.get(), DontEnum
);
312 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().EvalError
, m_evalErrorConstructor
.get(), DontEnum
);
313 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().RangeError
, m_rangeErrorConstructor
.get(), DontEnum
);
314 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().ReferenceError
, m_referenceErrorConstructor
.get(), DontEnum
);
315 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().SyntaxError
, m_syntaxErrorConstructor
.get(), DontEnum
);
316 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().TypeError
, m_typeErrorConstructor
.get(), DontEnum
);
317 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().URIError
, m_URIErrorConstructor
.get(), DontEnum
);
319 m_evalFunction
.set(exec
->vm(), this, JSFunction::create(exec
, this, 1, exec
->propertyNames().eval
.string(), globalFuncEval
));
320 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().eval
, m_evalFunction
.get(), DontEnum
);
322 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().JSON
, JSONObject::create(exec
, this, JSONObject::createStructure(exec
->vm(), this, m_objectPrototype
.get())), DontEnum
);
323 putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().Math
, MathObject::create(exec
, this, MathObject::createStructure(exec
->vm(), this, m_objectPrototype
.get())), DontEnum
);
325 GlobalPropertyInfo staticGlobals
[] = {
326 GlobalPropertyInfo(exec
->propertyNames().NaN
, jsNaN(), DontEnum
| DontDelete
| ReadOnly
),
327 GlobalPropertyInfo(exec
->propertyNames().Infinity
, jsNumber(std::numeric_limits
<double>::infinity()), DontEnum
| DontDelete
| ReadOnly
),
328 GlobalPropertyInfo(exec
->propertyNames().undefinedKeyword
, jsUndefined(), DontEnum
| DontDelete
| ReadOnly
)
330 addStaticGlobals(staticGlobals
, WTF_ARRAY_LENGTH(staticGlobals
));
332 m_specialPointers
[Special::CallFunction
] = m_callFunction
.get();
333 m_specialPointers
[Special::ApplyFunction
] = m_applyFunction
.get();
334 m_specialPointers
[Special::ObjectConstructor
] = objectConstructor
;
335 m_specialPointers
[Special::ArrayConstructor
] = arrayConstructor
;
337 if (m_experimentsEnabled
) {
338 NamePrototype
* privateNamePrototype
= NamePrototype::create(exec
, NamePrototype::createStructure(exec
->vm(), this, m_objectPrototype
.get()));
339 m_privateNameStructure
.set(exec
->vm(), this, NameInstance::createStructure(exec
->vm(), this, privateNamePrototype
));
341 JSCell
* privateNameConstructor
= NameConstructor::create(exec
, this, NameConstructor::createStructure(exec
->vm(), this, m_functionPrototype
.get()), privateNamePrototype
);
342 privateNamePrototype
->putDirectWithoutTransition(exec
->vm(), exec
->propertyNames().constructor
, privateNameConstructor
, DontEnum
);
343 putDirectWithoutTransition(exec
->vm(), Identifier(exec
, "Name"), privateNameConstructor
, DontEnum
);
346 resetPrototype(exec
->vm(), prototype
);
349 // Private namespace for helpers for JSGlobalObject::haveABadTime()
352 class ObjectsWithBrokenIndexingFinder
: public MarkedBlock::VoidFunctor
{
354 ObjectsWithBrokenIndexingFinder(MarkedArgumentBuffer
&, JSGlobalObject
*);
355 void operator()(JSCell
*);
358 MarkedArgumentBuffer
& m_foundObjects
;
359 JSGlobalObject
* m_globalObject
;
362 ObjectsWithBrokenIndexingFinder::ObjectsWithBrokenIndexingFinder(
363 MarkedArgumentBuffer
& foundObjects
, JSGlobalObject
* globalObject
)
364 : m_foundObjects(foundObjects
)
365 , m_globalObject(globalObject
)
369 inline bool hasBrokenIndexing(JSObject
* object
)
371 // This will change if we have more indexing types.
372 IndexingType type
= object
->structure()->indexingType();
373 // This could be made obviously more efficient, but isn't made so right now, because
374 // we expect this to be an unlikely slow path anyway.
375 return hasUndecided(type
) || hasInt32(type
) || hasDouble(type
) || hasContiguous(type
) || hasFastArrayStorage(type
);
378 void ObjectsWithBrokenIndexingFinder::operator()(JSCell
* cell
)
380 if (!cell
->isObject())
383 JSObject
* object
= asObject(cell
);
385 // Run this filter first, since it's cheap, and ought to filter out a lot of objects.
386 if (!hasBrokenIndexing(object
))
389 // We only want to have a bad time in the affected global object, not in the entire
390 // VM. But we have to be careful, since there may be objects that claim to belong to
391 // a different global object that have prototypes from our global object.
392 bool foundGlobalObject
= false;
393 for (JSObject
* current
= object
; ;) {
394 if (current
->globalObject() == m_globalObject
) {
395 foundGlobalObject
= true;
399 JSValue prototypeValue
= current
->prototype();
400 if (prototypeValue
.isNull())
402 current
= asObject(prototypeValue
);
404 if (!foundGlobalObject
)
407 m_foundObjects
.append(object
);
410 } // end private namespace for helpers for JSGlobalObject::haveABadTime()
412 void JSGlobalObject::haveABadTime(VM
& vm
)
414 ASSERT(&vm
== &this->vm());
416 if (isHavingABadTime())
419 // Make sure that all allocations or indexed storage transitions that are inlining
420 // the assumption that it's safe to transition to a non-SlowPut array storage don't
422 m_havingABadTimeWatchpoint
->notifyWrite();
423 ASSERT(isHavingABadTime()); // The watchpoint is what tells us that we're having a bad time.
425 // Make sure that all JSArray allocations that load the appropriate structure from
426 // this object now load a structure that uses SlowPut.
427 for (unsigned i
= 0; i
< NumberOfIndexingShapes
; ++i
)
428 m_arrayStructureForIndexingShapeDuringAllocation
[i
].set(vm
, this, originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage
));
430 // Make sure that all objects that have indexed storage switch to the slow kind of
432 MarkedArgumentBuffer foundObjects
; // Use MarkedArgumentBuffer because switchToSlowPutArrayStorage() may GC.
433 ObjectsWithBrokenIndexingFinder
finder(foundObjects
, this);
434 vm
.heap
.objectSpace().forEachLiveCell(finder
);
435 while (!foundObjects
.isEmpty()) {
436 JSObject
* object
= asObject(foundObjects
.last());
437 foundObjects
.removeLast();
438 ASSERT(hasBrokenIndexing(object
));
439 object
->switchToSlowPutArrayStorage(vm
);
443 bool JSGlobalObject::arrayPrototypeChainIsSane()
445 return !hasIndexedProperties(m_arrayPrototype
->structure()->indexingType())
446 && m_arrayPrototype
->prototype() == m_objectPrototype
.get()
447 && !hasIndexedProperties(m_objectPrototype
->structure()->indexingType())
448 && m_objectPrototype
->prototype().isNull();
451 void JSGlobalObject::createThrowTypeError(ExecState
* exec
)
453 JSFunction
* thrower
= JSFunction::create(exec
, this, 0, String(), globalFuncThrowTypeError
);
454 GetterSetter
* getterSetter
= GetterSetter::create(exec
);
455 getterSetter
->setGetter(exec
->vm(), thrower
);
456 getterSetter
->setSetter(exec
->vm(), thrower
);
457 m_throwTypeErrorGetterSetter
.set(exec
->vm(), this, getterSetter
);
460 // Set prototype, and also insert the object prototype at the end of the chain.
461 void JSGlobalObject::resetPrototype(VM
& vm
, JSValue prototype
)
463 setPrototype(vm
, prototype
);
465 JSObject
* oldLastInPrototypeChain
= lastInPrototypeChain(this);
466 JSObject
* objectPrototype
= m_objectPrototype
.get();
467 if (oldLastInPrototypeChain
!= objectPrototype
)
468 oldLastInPrototypeChain
->setPrototype(vm
, objectPrototype
);
471 void JSGlobalObject::visitChildren(JSCell
* cell
, SlotVisitor
& visitor
)
473 JSGlobalObject
* thisObject
= jsCast
<JSGlobalObject
*>(cell
);
474 ASSERT_GC_OBJECT_INHERITS(thisObject
, &s_info
);
475 COMPILE_ASSERT(StructureFlags
& OverridesVisitChildren
, OverridesVisitChildrenWithoutSettingFlag
);
476 ASSERT(thisObject
->structure()->typeInfo().overridesVisitChildren());
477 Base::visitChildren(thisObject
, visitor
);
479 visitor
.append(&thisObject
->m_globalThis
);
481 visitor
.append(&thisObject
->m_regExpConstructor
);
482 visitor
.append(&thisObject
->m_errorConstructor
);
483 visitor
.append(&thisObject
->m_evalErrorConstructor
);
484 visitor
.append(&thisObject
->m_rangeErrorConstructor
);
485 visitor
.append(&thisObject
->m_referenceErrorConstructor
);
486 visitor
.append(&thisObject
->m_syntaxErrorConstructor
);
487 visitor
.append(&thisObject
->m_typeErrorConstructor
);
488 visitor
.append(&thisObject
->m_URIErrorConstructor
);
490 visitor
.append(&thisObject
->m_evalFunction
);
491 visitor
.append(&thisObject
->m_callFunction
);
492 visitor
.append(&thisObject
->m_applyFunction
);
493 visitor
.append(&thisObject
->m_throwTypeErrorGetterSetter
);
495 visitor
.append(&thisObject
->m_objectPrototype
);
496 visitor
.append(&thisObject
->m_functionPrototype
);
497 visitor
.append(&thisObject
->m_arrayPrototype
);
498 visitor
.append(&thisObject
->m_booleanPrototype
);
499 visitor
.append(&thisObject
->m_stringPrototype
);
500 visitor
.append(&thisObject
->m_numberPrototype
);
501 visitor
.append(&thisObject
->m_datePrototype
);
502 visitor
.append(&thisObject
->m_regExpPrototype
);
503 visitor
.append(&thisObject
->m_errorPrototype
);
505 visitor
.append(&thisObject
->m_withScopeStructure
);
506 visitor
.append(&thisObject
->m_strictEvalActivationStructure
);
507 visitor
.append(&thisObject
->m_activationStructure
);
508 visitor
.append(&thisObject
->m_nameScopeStructure
);
509 visitor
.append(&thisObject
->m_argumentsStructure
);
510 for (unsigned i
= 0; i
< NumberOfIndexingShapes
; ++i
)
511 visitor
.append(&thisObject
->m_originalArrayStructureForIndexingShape
[i
]);
512 for (unsigned i
= 0; i
< NumberOfIndexingShapes
; ++i
)
513 visitor
.append(&thisObject
->m_arrayStructureForIndexingShapeDuringAllocation
[i
]);
514 visitor
.append(&thisObject
->m_booleanObjectStructure
);
515 visitor
.append(&thisObject
->m_callbackConstructorStructure
);
516 visitor
.append(&thisObject
->m_callbackFunctionStructure
);
517 visitor
.append(&thisObject
->m_callbackObjectStructure
);
518 #if JSC_OBJC_API_ENABLED
519 visitor
.append(&thisObject
->m_objcCallbackFunctionStructure
);
520 visitor
.append(&thisObject
->m_objcWrapperObjectStructure
);
522 visitor
.append(&thisObject
->m_dateStructure
);
523 visitor
.append(&thisObject
->m_nullPrototypeObjectStructure
);
524 visitor
.append(&thisObject
->m_errorStructure
);
525 visitor
.append(&thisObject
->m_functionStructure
);
526 visitor
.append(&thisObject
->m_boundFunctionStructure
);
527 visitor
.append(&thisObject
->m_namedFunctionStructure
);
528 visitor
.append(&thisObject
->m_numberObjectStructure
);
529 visitor
.append(&thisObject
->m_privateNameStructure
);
530 visitor
.append(&thisObject
->m_regExpMatchesArrayStructure
);
531 visitor
.append(&thisObject
->m_regExpStructure
);
532 visitor
.append(&thisObject
->m_stringObjectStructure
);
533 visitor
.append(&thisObject
->m_internalFunctionStructure
);
536 JSObject
* JSGlobalObject::toThisObject(JSCell
* cell
, ExecState
*)
538 return jsCast
<JSGlobalObject
*>(cell
)->globalThis();
541 ExecState
* JSGlobalObject::globalExec()
543 return CallFrame::create(m_globalCallFrame
+ JSStack::CallFrameHeaderSize
);
546 void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo
* globals
, int count
)
550 for (int i
= 0; i
< count
; ++i
) {
551 GlobalPropertyInfo
& global
= globals
[i
];
552 ASSERT(global
.attributes
& DontDelete
);
554 int index
= symbolTable()->size();
555 SymbolTableEntry
newEntry(index
, global
.attributes
);
556 symbolTable()->add(global
.identifier
.impl(), newEntry
);
557 registerAt(index
).set(vm(), this, global
.value
);
561 bool JSGlobalObject::getOwnPropertySlot(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
& slot
)
563 JSGlobalObject
* thisObject
= jsCast
<JSGlobalObject
*>(cell
);
564 if (getStaticFunctionSlot
<Base
>(exec
, ExecState::globalObjectTable(exec
), thisObject
, propertyName
, slot
))
566 return symbolTableGet(thisObject
, propertyName
, slot
);
569 bool JSGlobalObject::getOwnPropertyDescriptor(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertyDescriptor
& descriptor
)
571 JSGlobalObject
* thisObject
= jsCast
<JSGlobalObject
*>(object
);
572 if (getStaticFunctionDescriptor
<Base
>(exec
, ExecState::globalObjectTable(exec
), thisObject
, propertyName
, descriptor
))
574 return symbolTableGet(thisObject
, propertyName
, descriptor
);
577 void JSGlobalObject::clearRareData(JSCell
* cell
)
579 jsCast
<JSGlobalObject
*>(cell
)->m_rareData
.clear();
582 DynamicGlobalObjectScope::DynamicGlobalObjectScope(VM
& vm
, JSGlobalObject
* dynamicGlobalObject
)
583 : m_dynamicGlobalObjectSlot(vm
.dynamicGlobalObject
)
584 , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot
)
586 if (!m_dynamicGlobalObjectSlot
) {
587 #if ENABLE(ASSEMBLER)
588 if (ExecutableAllocator::underMemoryPressure())
589 vm
.heap
.deleteAllCompiledCode();
592 m_dynamicGlobalObjectSlot
= dynamicGlobalObject
;
594 // Reset the date cache between JS invocations to force the VM
595 // to observe time zone changes.
598 // Clear the exception stack between entries
599 vm
.clearExceptionStack();
602 void slowValidateCell(JSGlobalObject
* globalObject
)
604 RELEASE_ASSERT(globalObject
->isGlobalObject());
605 ASSERT_GC_OBJECT_INHERITS(globalObject
, &JSGlobalObject::s_info
);
608 UnlinkedProgramCodeBlock
* JSGlobalObject::createProgramCodeBlock(CallFrame
* callFrame
, ProgramExecutable
* executable
, JSObject
** exception
)
611 JSParserStrictness strictness
= executable
->isStrictMode() ? JSParseStrict
: JSParseNormal
;
612 DebuggerMode debuggerMode
= hasDebugger() ? DebuggerOn
: DebuggerOff
;
613 ProfilerMode profilerMode
= hasProfiler() ? ProfilerOn
: ProfilerOff
;
614 UnlinkedProgramCodeBlock
* unlinkedCode
= vm().codeCache()->getProgramCodeBlock(vm(), executable
, executable
->source(), strictness
, debuggerMode
, profilerMode
, error
);
617 debugger()->sourceParsed(callFrame
, executable
->source().provider(), error
.m_line
, error
.m_message
);
619 if (error
.m_type
!= ParserError::ErrorNone
) {
620 *exception
= error
.toErrorObject(this, executable
->source());
627 UnlinkedEvalCodeBlock
* JSGlobalObject::createEvalCodeBlock(CodeCache
* cache
, CallFrame
* callFrame
, JSScope
* scope
, EvalExecutable
* executable
, JSObject
** exception
)
630 JSParserStrictness strictness
= executable
->isStrictMode() ? JSParseStrict
: JSParseNormal
;
631 DebuggerMode debuggerMode
= hasDebugger() ? DebuggerOn
: DebuggerOff
;
632 ProfilerMode profilerMode
= hasProfiler() ? ProfilerOn
: ProfilerOff
;
633 UnlinkedEvalCodeBlock
* unlinkedCode
= cache
->getEvalCodeBlock(vm(), scope
, executable
, executable
->source(), strictness
, debuggerMode
, profilerMode
, error
);
636 debugger()->sourceParsed(callFrame
, executable
->source().provider(), error
.m_line
, error
.m_message
);
638 if (error
.m_type
!= ParserError::ErrorNone
) {
639 *exception
= error
.toErrorObject(this, executable
->source());