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 "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" 42#include "Debugger.h" 43#include "Error.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" 58#include "JSLock.h" 59#include "JSNameScope.h" 60#include "JSONObject.h" 61#include "JSWithScope.h" 62#include "LegacyProfiler.h" 63#include "Lookup.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" 84 85#include "JSGlobalObject.lut.h" 86 87namespace JSC { 88 89const ClassInfo JSGlobalObject::s_info = { "GlobalObject", &Base::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(JSGlobalObject) }; 90 91const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptExperimentsEnabled }; 92 93/* Source for JSGlobalObject.lut.h 94@begin globalObjectTable 95 parseInt globalFuncParseInt DontEnum|Function 2 96 parseFloat globalFuncParseFloat DontEnum|Function 1 97 isNaN globalFuncIsNaN DontEnum|Function 1 98 isFinite globalFuncIsFinite DontEnum|Function 1 99 escape globalFuncEscape DontEnum|Function 1 100 unescape globalFuncUnescape DontEnum|Function 1 101 decodeURI globalFuncDecodeURI DontEnum|Function 1 102 decodeURIComponent globalFuncDecodeURIComponent DontEnum|Function 1 103 encodeURI globalFuncEncodeURI DontEnum|Function 1 104 encodeURIComponent globalFuncEncodeURIComponent DontEnum|Function 1 105@end 106*/ 107 108JSGlobalObject::JSGlobalObject(VM& vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable) 109 : Base(vm, structure, 0) 110 , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(InitializedWatching))) 111 , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(InitializedWatching))) 112 , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))) 113 , m_evalEnabled(true) 114 , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable) 115{ 116} 117 118JSGlobalObject::~JSGlobalObject() 119{ 120 if (m_debugger) 121 m_debugger->detach(this); 122 123 if (LegacyProfiler* profiler = vm().enabledProfiler()) 124 profiler->stopProfiling(this); 125} 126 127void JSGlobalObject::destroy(JSCell* cell) 128{ 129 static_cast<JSGlobalObject*>(cell)->JSGlobalObject::~JSGlobalObject(); 130} 131 132void JSGlobalObject::setGlobalThis(VM& vm, JSObject* globalThis) 133{ 134 m_globalThis.set(vm, this, globalThis); 135} 136 137void JSGlobalObject::init(JSObject* thisValue) 138{ 139 ASSERT(vm().apiLock().currentThreadIsHoldingLock()); 140 141 setGlobalThis(vm(), thisValue); 142 JSGlobalObject::globalExec()->init(0, 0, this, CallFrame::noCaller(), 0, 0); 143 144 m_debugger = 0; 145 146 reset(prototype()); 147} 148 149void JSGlobalObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) 150{ 151 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell); 152 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject)); 153 154 if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode())) 155 return; 156 Base::put(thisObject, exec, propertyName, value, slot); 157} 158 159void JSGlobalObject::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes) 160{ 161 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object); 162 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject)); 163 164 if (symbolTablePutWithAttributes(thisObject, exec->vm(), propertyName, value, attributes)) 165 return; 166 167 JSValue valueBefore = thisObject->getDirect(exec->vm(), propertyName); 168 PutPropertySlot slot; 169 Base::put(thisObject, exec, propertyName, value, slot); 170 if (!valueBefore) { 171 JSValue valueAfter = thisObject->getDirect(exec->vm(), propertyName); 172 if (valueAfter) 173 JSObject::putDirectVirtual(thisObject, exec, propertyName, valueAfter, attributes); 174 } 175} 176 177bool JSGlobalObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool shouldThrow) 178{ 179 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object); 180 PropertySlot slot; 181 // silently ignore attempts to add accessors aliasing vars. 182 if (descriptor.isAccessorDescriptor() && symbolTableGet(thisObject, propertyName, slot)) 183 return false; 184 return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow); 185} 186 187 188static inline JSObject* lastInPrototypeChain(JSObject* object) 189{ 190 JSObject* o = object; 191 while (o->prototype().isObject()) 192 o = asObject(o->prototype()); 193 return o; 194} 195 196void JSGlobalObject::reset(JSValue prototype) 197{ 198 ExecState* exec = JSGlobalObject::globalExec(); 199 200 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. 201 m_functionStructure.set(exec->vm(), this, JSFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); 202 m_boundFunctionStructure.set(exec->vm(), this, JSBoundFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); 203 m_namedFunctionStructure.set(exec->vm(), this, Structure::addPropertyTransition(exec->vm(), m_functionStructure.get(), exec->vm().propertyNames->name, DontDelete | ReadOnly | DontEnum, 0, m_functionNameOffset)); 204 m_internalFunctionStructure.set(exec->vm(), this, InternalFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); 205 JSFunction* callFunction = 0; 206 JSFunction* applyFunction = 0; 207 m_functionPrototype->addFunctionProperties(exec, this, &callFunction, &applyFunction); 208 m_callFunction.set(exec->vm(), this, callFunction); 209 m_applyFunction.set(exec->vm(), this, applyFunction); 210 m_objectPrototype.set(exec->vm(), this, ObjectPrototype::create(exec, this, ObjectPrototype::createStructure(exec->vm(), this, jsNull()))); 211 GetterSetter* protoAccessor = GetterSetter::create(exec); 212 protoAccessor->setGetter(exec->vm(), JSFunction::create(exec, this, 0, String(), globalFuncProtoGetter)); 213 protoAccessor->setSetter(exec->vm(), JSFunction::create(exec, this, 0, String(), globalFuncProtoSetter)); 214 m_objectPrototype->putDirectAccessor(exec, exec->propertyNames().underscoreProto, protoAccessor, Accessor | DontEnum); 215 m_functionPrototype->structure()->setPrototypeWithoutTransition(exec->vm(), m_objectPrototype.get()); 216 217 m_nameScopeStructure.set(exec->vm(), this, JSNameScope::createStructure(exec->vm(), this, jsNull())); 218 m_activationStructure.set(exec->vm(), this, JSActivation::createStructure(exec->vm(), this, jsNull())); 219 m_strictEvalActivationStructure.set(exec->vm(), this, StrictEvalActivation::createStructure(exec->vm(), this, jsNull())); 220 m_withScopeStructure.set(exec->vm(), this, JSWithScope::createStructure(exec->vm(), this, jsNull())); 221 222 m_nullPrototypeObjectStructure.set(exec->vm(), this, JSFinalObject::createStructure(vm(), this, jsNull(), JSFinalObject::defaultInlineCapacity())); 223 224 m_callbackFunctionStructure.set(exec->vm(), this, JSCallbackFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); 225 m_argumentsStructure.set(exec->vm(), this, Arguments::createStructure(exec->vm(), this, m_objectPrototype.get())); 226 m_callbackConstructorStructure.set(exec->vm(), this, JSCallbackConstructor::createStructure(exec->vm(), this, m_objectPrototype.get())); 227 m_callbackObjectStructure.set(exec->vm(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->vm(), this, m_objectPrototype.get())); 228#if JSC_OBJC_API_ENABLED 229 m_objcCallbackFunctionStructure.set(exec->vm(), this, ObjCCallbackFunction::createStructure(exec->vm(), this, m_functionPrototype.get())); 230 m_objcWrapperObjectStructure.set(exec->vm(), this, JSCallbackObject<JSAPIWrapperObject>::createStructure(exec->vm(), this, m_objectPrototype.get())); 231#endif 232 233 m_arrayPrototype.set(exec->vm(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); 234 235 m_originalArrayStructureForIndexingShape[UndecidedShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithUndecided)); 236 m_originalArrayStructureForIndexingShape[Int32Shape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithInt32)); 237 m_originalArrayStructureForIndexingShape[DoubleShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithDouble)); 238 m_originalArrayStructureForIndexingShape[ContiguousShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithContiguous)); 239 m_originalArrayStructureForIndexingShape[ArrayStorageShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithArrayStorage)); 240 m_originalArrayStructureForIndexingShape[SlowPutArrayStorageShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage)); 241 for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) 242 m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i]; 243 244 m_regExpMatchesArrayStructure.set(exec->vm(), this, RegExpMatchesArray::createStructure(exec->vm(), this, m_arrayPrototype.get())); 245 246 m_stringPrototype.set(exec->vm(), this, StringPrototype::create(exec, this, StringPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); 247 m_stringObjectStructure.set(exec->vm(), this, StringObject::createStructure(exec->vm(), this, m_stringPrototype.get())); 248 249 m_booleanPrototype.set(exec->vm(), this, BooleanPrototype::create(exec, this, BooleanPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); 250 m_booleanObjectStructure.set(exec->vm(), this, BooleanObject::createStructure(exec->vm(), this, m_booleanPrototype.get())); 251 252 m_numberPrototype.set(exec->vm(), this, NumberPrototype::create(exec, this, NumberPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); 253 m_numberObjectStructure.set(exec->vm(), this, NumberObject::createStructure(exec->vm(), this, m_numberPrototype.get())); 254 255 m_datePrototype.set(exec->vm(), this, DatePrototype::create(exec, this, DatePrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); 256 m_dateStructure.set(exec->vm(), this, DateInstance::createStructure(exec->vm(), this, m_datePrototype.get())); 257 258 RegExp* emptyRegex = RegExp::create(exec->vm(), "", NoFlags); 259 260 m_regExpPrototype.set(exec->vm(), this, RegExpPrototype::create(exec, this, RegExpPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()), emptyRegex)); 261 m_regExpStructure.set(exec->vm(), this, RegExpObject::createStructure(exec->vm(), this, m_regExpPrototype.get())); 262 263 m_errorPrototype.set(exec->vm(), this, ErrorPrototype::create(exec, this, ErrorPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); 264 m_errorStructure.set(exec->vm(), this, ErrorInstance::createStructure(exec->vm(), this, m_errorPrototype.get())); 265 266 // Constructors 267 268 JSCell* objectConstructor = ObjectConstructor::create(exec, this, ObjectConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_objectPrototype.get()); 269 JSCell* functionConstructor = FunctionConstructor::create(exec, this, FunctionConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_functionPrototype.get()); 270 JSCell* arrayConstructor = ArrayConstructor::create(exec, this, ArrayConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_arrayPrototype.get()); 271 JSCell* stringConstructor = StringConstructor::create(exec, this, StringConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_stringPrototype.get()); 272 JSCell* booleanConstructor = BooleanConstructor::create(exec, this, BooleanConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_booleanPrototype.get()); 273 JSCell* numberConstructor = NumberConstructor::create(exec, this, NumberConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_numberPrototype.get()); 274 JSCell* dateConstructor = DateConstructor::create(exec, this, DateConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_datePrototype.get()); 275 276 m_regExpConstructor.set(exec->vm(), this, RegExpConstructor::create(exec, this, RegExpConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_regExpPrototype.get())); 277 278 m_errorConstructor.set(exec->vm(), this, ErrorConstructor::create(exec, this, ErrorConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_errorPrototype.get())); 279 280 Structure* nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->vm(), this, m_errorPrototype.get()); 281 Structure* nativeErrorStructure = NativeErrorConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()); 282 m_evalErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("EvalError"))); 283 m_rangeErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("RangeError"))); 284 m_referenceErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("ReferenceError"))); 285 m_syntaxErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("SyntaxError"))); 286 m_typeErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("TypeError"))); 287 m_URIErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("URIError"))); 288 289 m_objectPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, objectConstructor, DontEnum); 290 m_functionPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, functionConstructor, DontEnum); 291 m_arrayPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, arrayConstructor, DontEnum); 292 m_booleanPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, booleanConstructor, DontEnum); 293 m_stringPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, stringConstructor, DontEnum); 294 m_numberPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, numberConstructor, DontEnum); 295 m_datePrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, dateConstructor, DontEnum); 296 m_regExpPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, m_regExpConstructor.get(), DontEnum); 297 m_errorPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, m_errorConstructor.get(), DontEnum); 298 299 putDirectWithoutTransition(exec->vm(), exec->propertyNames().Object, objectConstructor, DontEnum); 300 putDirectWithoutTransition(exec->vm(), exec->propertyNames().Function, functionConstructor, DontEnum); 301 putDirectWithoutTransition(exec->vm(), exec->propertyNames().Array, arrayConstructor, DontEnum); 302 putDirectWithoutTransition(exec->vm(), exec->propertyNames().Boolean, booleanConstructor, DontEnum); 303 putDirectWithoutTransition(exec->vm(), exec->propertyNames().String, stringConstructor, DontEnum); 304 putDirectWithoutTransition(exec->vm(), exec->propertyNames().Number, numberConstructor, DontEnum); 305 putDirectWithoutTransition(exec->vm(), exec->propertyNames().Date, dateConstructor, DontEnum); 306 putDirectWithoutTransition(exec->vm(), exec->propertyNames().RegExp, m_regExpConstructor.get(), DontEnum); 307 putDirectWithoutTransition(exec->vm(), exec->propertyNames().Error, m_errorConstructor.get(), DontEnum); 308 putDirectWithoutTransition(exec->vm(), exec->propertyNames().EvalError, m_evalErrorConstructor.get(), DontEnum); 309 putDirectWithoutTransition(exec->vm(), exec->propertyNames().RangeError, m_rangeErrorConstructor.get(), DontEnum); 310 putDirectWithoutTransition(exec->vm(), exec->propertyNames().ReferenceError, m_referenceErrorConstructor.get(), DontEnum); 311 putDirectWithoutTransition(exec->vm(), exec->propertyNames().SyntaxError, m_syntaxErrorConstructor.get(), DontEnum); 312 putDirectWithoutTransition(exec->vm(), exec->propertyNames().TypeError, m_typeErrorConstructor.get(), DontEnum); 313 putDirectWithoutTransition(exec->vm(), exec->propertyNames().URIError, m_URIErrorConstructor.get(), DontEnum); 314 315 m_evalFunction.set(exec->vm(), this, JSFunction::create(exec, this, 1, exec->propertyNames().eval.string(), globalFuncEval)); 316 putDirectWithoutTransition(exec->vm(), exec->propertyNames().eval, m_evalFunction.get(), DontEnum); 317 318 putDirectWithoutTransition(exec->vm(), exec->propertyNames().JSON, JSONObject::create(exec, this, JSONObject::createStructure(exec->vm(), this, m_objectPrototype.get())), DontEnum); 319 putDirectWithoutTransition(exec->vm(), exec->propertyNames().Math, MathObject::create(exec, this, MathObject::createStructure(exec->vm(), this, m_objectPrototype.get())), DontEnum); 320 321 GlobalPropertyInfo staticGlobals[] = { 322 GlobalPropertyInfo(exec->propertyNames().NaN, jsNaN(), DontEnum | DontDelete | ReadOnly), 323 GlobalPropertyInfo(exec->propertyNames().Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly), 324 GlobalPropertyInfo(exec->propertyNames().undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly) 325 }; 326 addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals)); 327 328 m_specialPointers[Special::CallFunction] = m_callFunction.get(); 329 m_specialPointers[Special::ApplyFunction] = m_applyFunction.get(); 330 m_specialPointers[Special::ObjectConstructor] = objectConstructor; 331 m_specialPointers[Special::ArrayConstructor] = arrayConstructor; 332 333 if (m_experimentsEnabled) { 334 NamePrototype* privateNamePrototype = NamePrototype::create(exec, NamePrototype::createStructure(exec->vm(), this, m_objectPrototype.get())); 335 m_privateNameStructure.set(exec->vm(), this, NameInstance::createStructure(exec->vm(), this, privateNamePrototype)); 336 337 JSCell* privateNameConstructor = NameConstructor::create(exec, this, NameConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), privateNamePrototype); 338 privateNamePrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, privateNameConstructor, DontEnum); 339 putDirectWithoutTransition(exec->vm(), Identifier(exec, "Name"), privateNameConstructor, DontEnum); 340 } 341 342 resetPrototype(exec->vm(), prototype); 343} 344 345// Private namespace for helpers for JSGlobalObject::haveABadTime() 346namespace { 347 348class ObjectsWithBrokenIndexingFinder : public MarkedBlock::VoidFunctor { 349public: 350 ObjectsWithBrokenIndexingFinder(MarkedArgumentBuffer&, JSGlobalObject*); 351 void operator()(JSCell*); 352 353private: 354 MarkedArgumentBuffer& m_foundObjects; 355 JSGlobalObject* m_globalObject; 356}; 357 358ObjectsWithBrokenIndexingFinder::ObjectsWithBrokenIndexingFinder( 359 MarkedArgumentBuffer& foundObjects, JSGlobalObject* globalObject) 360 : m_foundObjects(foundObjects) 361 , m_globalObject(globalObject) 362{ 363} 364 365inline bool hasBrokenIndexing(JSObject* object) 366{ 367 // This will change if we have more indexing types. 368 IndexingType type = object->structure()->indexingType(); 369 // This could be made obviously more efficient, but isn't made so right now, because 370 // we expect this to be an unlikely slow path anyway. 371 return hasUndecided(type) || hasInt32(type) || hasDouble(type) || hasContiguous(type) || hasFastArrayStorage(type); 372} 373 374void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell) 375{ 376 if (!cell->isObject()) 377 return; 378 379 JSObject* object = asObject(cell); 380 381 // Run this filter first, since it's cheap, and ought to filter out a lot of objects. 382 if (!hasBrokenIndexing(object)) 383 return; 384 385 // We only want to have a bad time in the affected global object, not in the entire 386 // VM. But we have to be careful, since there may be objects that claim to belong to 387 // a different global object that have prototypes from our global object. 388 bool foundGlobalObject = false; 389 for (JSObject* current = object; ;) { 390 if (current->globalObject() == m_globalObject) { 391 foundGlobalObject = true; 392 break; 393 } 394 395 JSValue prototypeValue = current->prototype(); 396 if (prototypeValue.isNull()) 397 break; 398 current = asObject(prototypeValue); 399 } 400 if (!foundGlobalObject) 401 return; 402 403 m_foundObjects.append(object); 404} 405 406} // end private namespace for helpers for JSGlobalObject::haveABadTime() 407 408void JSGlobalObject::haveABadTime(VM& vm) 409{ 410 ASSERT(&vm == &this->vm()); 411 412 if (isHavingABadTime()) 413 return; 414 415 // Make sure that all allocations or indexed storage transitions that are inlining 416 // the assumption that it's safe to transition to a non-SlowPut array storage don't 417 // do so anymore. 418 m_havingABadTimeWatchpoint->notifyWrite(); 419 ASSERT(isHavingABadTime()); // The watchpoint is what tells us that we're having a bad time. 420 421 // Make sure that all JSArray allocations that load the appropriate structure from 422 // this object now load a structure that uses SlowPut. 423 for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) 424 m_arrayStructureForIndexingShapeDuringAllocation[i].set(vm, this, originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage)); 425 426 // Make sure that all objects that have indexed storage switch to the slow kind of 427 // indexed storage. 428 MarkedArgumentBuffer foundObjects; // Use MarkedArgumentBuffer because switchToSlowPutArrayStorage() may GC. 429 ObjectsWithBrokenIndexingFinder finder(foundObjects, this); 430 vm.heap.objectSpace().forEachLiveCell(finder); 431 while (!foundObjects.isEmpty()) { 432 JSObject* object = asObject(foundObjects.last()); 433 foundObjects.removeLast(); 434 ASSERT(hasBrokenIndexing(object)); 435 object->switchToSlowPutArrayStorage(vm); 436 } 437} 438 439bool JSGlobalObject::arrayPrototypeChainIsSane() 440{ 441 return !hasIndexedProperties(m_arrayPrototype->structure()->indexingType()) 442 && m_arrayPrototype->prototype() == m_objectPrototype.get() 443 && !hasIndexedProperties(m_objectPrototype->structure()->indexingType()) 444 && m_objectPrototype->prototype().isNull(); 445} 446 447void JSGlobalObject::createThrowTypeError(ExecState* exec) 448{ 449 JSFunction* thrower = JSFunction::create(exec, this, 0, String(), globalFuncThrowTypeError); 450 GetterSetter* getterSetter = GetterSetter::create(exec); 451 getterSetter->setGetter(exec->vm(), thrower); 452 getterSetter->setSetter(exec->vm(), thrower); 453 m_throwTypeErrorGetterSetter.set(exec->vm(), this, getterSetter); 454} 455 456// Set prototype, and also insert the object prototype at the end of the chain. 457void JSGlobalObject::resetPrototype(VM& vm, JSValue prototype) 458{ 459 setPrototype(vm, prototype); 460 461 JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this); 462 JSObject* objectPrototype = m_objectPrototype.get(); 463 if (oldLastInPrototypeChain != objectPrototype) 464 oldLastInPrototypeChain->setPrototype(vm, objectPrototype); 465} 466 467void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) 468{ 469 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell); 470 ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); 471 COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); 472 ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); 473 Base::visitChildren(thisObject, visitor); 474 475 visitor.append(&thisObject->m_globalThis); 476 477 visitor.append(&thisObject->m_regExpConstructor); 478 visitor.append(&thisObject->m_errorConstructor); 479 visitor.append(&thisObject->m_evalErrorConstructor); 480 visitor.append(&thisObject->m_rangeErrorConstructor); 481 visitor.append(&thisObject->m_referenceErrorConstructor); 482 visitor.append(&thisObject->m_syntaxErrorConstructor); 483 visitor.append(&thisObject->m_typeErrorConstructor); 484 visitor.append(&thisObject->m_URIErrorConstructor); 485 486 visitor.append(&thisObject->m_evalFunction); 487 visitor.append(&thisObject->m_callFunction); 488 visitor.append(&thisObject->m_applyFunction); 489 visitor.append(&thisObject->m_throwTypeErrorGetterSetter); 490 491 visitor.append(&thisObject->m_objectPrototype); 492 visitor.append(&thisObject->m_functionPrototype); 493 visitor.append(&thisObject->m_arrayPrototype); 494 visitor.append(&thisObject->m_booleanPrototype); 495 visitor.append(&thisObject->m_stringPrototype); 496 visitor.append(&thisObject->m_numberPrototype); 497 visitor.append(&thisObject->m_datePrototype); 498 visitor.append(&thisObject->m_regExpPrototype); 499 visitor.append(&thisObject->m_errorPrototype); 500 501 visitor.append(&thisObject->m_withScopeStructure); 502 visitor.append(&thisObject->m_strictEvalActivationStructure); 503 visitor.append(&thisObject->m_activationStructure); 504 visitor.append(&thisObject->m_nameScopeStructure); 505 visitor.append(&thisObject->m_argumentsStructure); 506 for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) 507 visitor.append(&thisObject->m_originalArrayStructureForIndexingShape[i]); 508 for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) 509 visitor.append(&thisObject->m_arrayStructureForIndexingShapeDuringAllocation[i]); 510 visitor.append(&thisObject->m_booleanObjectStructure); 511 visitor.append(&thisObject->m_callbackConstructorStructure); 512 visitor.append(&thisObject->m_callbackFunctionStructure); 513 visitor.append(&thisObject->m_callbackObjectStructure); 514#if JSC_OBJC_API_ENABLED 515 visitor.append(&thisObject->m_objcCallbackFunctionStructure); 516 visitor.append(&thisObject->m_objcWrapperObjectStructure); 517#endif 518 visitor.append(&thisObject->m_dateStructure); 519 visitor.append(&thisObject->m_nullPrototypeObjectStructure); 520 visitor.append(&thisObject->m_errorStructure); 521 visitor.append(&thisObject->m_functionStructure); 522 visitor.append(&thisObject->m_boundFunctionStructure); 523 visitor.append(&thisObject->m_namedFunctionStructure); 524 visitor.append(&thisObject->m_numberObjectStructure); 525 visitor.append(&thisObject->m_privateNameStructure); 526 visitor.append(&thisObject->m_regExpMatchesArrayStructure); 527 visitor.append(&thisObject->m_regExpStructure); 528 visitor.append(&thisObject->m_stringObjectStructure); 529 visitor.append(&thisObject->m_internalFunctionStructure); 530} 531 532JSObject* JSGlobalObject::toThisObject(JSCell* cell, ExecState*) 533{ 534 return jsCast<JSGlobalObject*>(cell)->globalThis(); 535} 536 537ExecState* JSGlobalObject::globalExec() 538{ 539 return CallFrame::create(m_globalCallFrame + JSStack::CallFrameHeaderSize); 540} 541 542void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count) 543{ 544 addRegisters(count); 545 546 for (int i = 0; i < count; ++i) { 547 GlobalPropertyInfo& global = globals[i]; 548 ASSERT(global.attributes & DontDelete); 549 550 int index = symbolTable()->size(); 551 SymbolTableEntry newEntry(index, global.attributes); 552 symbolTable()->add(global.identifier.impl(), newEntry); 553 registerAt(index).set(vm(), this, global.value); 554 } 555} 556 557bool JSGlobalObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) 558{ 559 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell); 560 if (getStaticFunctionSlot<Base>(exec, ExecState::globalObjectTable(exec), thisObject, propertyName, slot)) 561 return true; 562 return symbolTableGet(thisObject, propertyName, slot); 563} 564 565bool JSGlobalObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) 566{ 567 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object); 568 if (getStaticFunctionDescriptor<Base>(exec, ExecState::globalObjectTable(exec), thisObject, propertyName, descriptor)) 569 return true; 570 return symbolTableGet(thisObject, propertyName, descriptor); 571} 572 573void JSGlobalObject::clearRareData(JSCell* cell) 574{ 575 jsCast<JSGlobalObject*>(cell)->m_rareData.clear(); 576} 577 578DynamicGlobalObjectScope::DynamicGlobalObjectScope(VM& vm, JSGlobalObject* dynamicGlobalObject) 579 : m_dynamicGlobalObjectSlot(vm.dynamicGlobalObject) 580 , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot) 581{ 582 if (!m_dynamicGlobalObjectSlot) { 583#if ENABLE(ASSEMBLER) 584 if (ExecutableAllocator::underMemoryPressure()) 585 vm.heap.deleteAllCompiledCode(); 586#endif 587 588 m_dynamicGlobalObjectSlot = dynamicGlobalObject; 589 590 // Reset the date cache between JS invocations to force the VM 591 // to observe time zone changes. 592 vm.resetDateCache(); 593 } 594 // Clear the exception stack between entries 595 vm.clearExceptionStack(); 596} 597 598void slowValidateCell(JSGlobalObject* globalObject) 599{ 600 RELEASE_ASSERT(globalObject->isGlobalObject()); 601 ASSERT_GC_OBJECT_INHERITS(globalObject, &JSGlobalObject::s_info); 602} 603 604UnlinkedProgramCodeBlock* JSGlobalObject::createProgramCodeBlock(CallFrame* callFrame, ProgramExecutable* executable, JSObject** exception) 605{ 606 ParserError error; 607 JSParserStrictness strictness = executable->isStrictMode() ? JSParseStrict : JSParseNormal; 608 DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff; 609 ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff; 610 UnlinkedProgramCodeBlock* unlinkedCode = vm().codeCache()->getProgramCodeBlock(vm(), executable, executable->source(), strictness, debuggerMode, profilerMode, error); 611 612 if (hasDebugger()) 613 debugger()->sourceParsed(callFrame, executable->source().provider(), error.m_line, error.m_message); 614 615 if (error.m_type != ParserError::ErrorNone) { 616 *exception = error.toErrorObject(this, executable->source()); 617 return 0; 618 } 619 620 return unlinkedCode; 621} 622 623UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CodeCache* cache, CallFrame* callFrame, JSScope* scope, EvalExecutable* executable, JSObject** exception) 624{ 625 ParserError error; 626 JSParserStrictness strictness = executable->isStrictMode() ? JSParseStrict : JSParseNormal; 627 DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff; 628 ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff; 629 UnlinkedEvalCodeBlock* unlinkedCode = cache->getEvalCodeBlock(vm(), scope, executable, executable->source(), strictness, debuggerMode, profilerMode, error); 630 631 if (hasDebugger()) 632 debugger()->sourceParsed(callFrame, executable->source().provider(), error.m_line, error.m_message); 633 634 if (error.m_type != ParserError::ErrorNone) { 635 *exception = error.toErrorObject(this, executable->source()); 636 return 0; 637 } 638 639 return unlinkedCode; 640} 641 642} // namespace JSC 643