1/* 2 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 3 * Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22#ifndef JSGlobalObject_h 23#define JSGlobalObject_h 24 25#include "ArrayAllocationProfile.h" 26#include "ConstantMode.h" 27#include "JSArray.h" 28#include "JSArrayBufferPrototype.h" 29#include "JSClassRef.h" 30#include "JSProxy.h" 31#include "JSSegmentedVariableObject.h" 32#include "JSWeakObjectMapRefInternal.h" 33#include "NumberPrototype.h" 34#include "SpecialPointer.h" 35#include "StringPrototype.h" 36#include "StructureChain.h" 37#include "StructureRareDataInlines.h" 38#include "VM.h" 39#include "Watchpoint.h" 40#include <JavaScriptCore/JSBase.h> 41#include <array> 42#include <wtf/HashSet.h> 43#include <wtf/OwnPtr.h> 44#include <wtf/PassRefPtr.h> 45#include <wtf/RandomNumber.h> 46 47struct OpaqueJSClass; 48struct OpaqueJSClassContextData; 49 50namespace Inspector { 51class JSGlobalObjectInspectorController; 52} 53 54namespace JSC { 55 56class ArrayPrototype; 57class BooleanPrototype; 58class ConsoleClient; 59class Debugger; 60class ErrorConstructor; 61class ErrorPrototype; 62class EvalCodeBlock; 63class EvalExecutable; 64class FunctionCodeBlock; 65class FunctionExecutable; 66class FunctionPrototype; 67class GetterSetter; 68class GlobalCodeBlock; 69class InputCursor; 70class JSGlobalObjectDebuggable; 71class JSPromiseConstructor; 72class JSPromisePrototype; 73class JSStack; 74class LLIntOffsetsExtractor; 75class Microtask; 76class NativeErrorConstructor; 77class ObjectConstructor; 78class ProgramCodeBlock; 79class ProgramExecutable; 80class RegExpConstructor; 81class RegExpPrototype; 82class SourceCode; 83struct ActivationStackNode; 84struct HashTable; 85 86#define DEFINE_STANDARD_BUILTIN(macro, upperName, lowerName) macro(upperName, lowerName, lowerName, JS ## upperName, upperName) 87 88#define FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \ 89 macro(Set, set, set, JSSet, Set) \ 90 macro(Map, map, map, JSMap, Map) \ 91 macro(Date, date, date, DateInstance, Date) \ 92 macro(String, string, stringObject, StringObject, String) \ 93 macro(Boolean, boolean, booleanObject, BooleanObject, Boolean) \ 94 macro(Number, number, numberObject, NumberObject, Number) \ 95 macro(Error, error, error, ErrorInstance, Error) \ 96 macro(JSArrayBuffer, arrayBuffer, arrayBuffer, JSArrayBuffer, ArrayBuffer) \ 97 DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \ 98 99#define FOR_EACH_SIMPLE_BUILTIN_TYPE(macro) \ 100 FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \ 101 DEFINE_STANDARD_BUILTIN(macro, ArrayIterator, arrayIterator) \ 102 DEFINE_STANDARD_BUILTIN(macro, ArgumentsIterator, argumentsIterator) \ 103 DEFINE_STANDARD_BUILTIN(macro, MapIterator, mapIterator) \ 104 DEFINE_STANDARD_BUILTIN(macro, SetIterator, setIterator) \ 105 106 107#define DECLARE_SIMPLE_BUILTIN_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ 108 class JS ## capitalName; \ 109 class capitalName ## Prototype; \ 110 class capitalName ## Constructor; 111 112FOR_EACH_SIMPLE_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE) 113 114#undef DECLARE_SIMPLE_BUILTIN_TYPE 115 116typedef Vector<ExecState*, 16> ExecStateStack; 117 118struct GlobalObjectMethodTable { 119 typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*); 120 AllowsAccessFromFunctionPtr allowsAccessFrom; 121 122 typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*); 123 SupportsProfilingFunctionPtr supportsProfiling; 124 125 typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*); 126 SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo; 127 128 typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*); 129 ShouldInterruptScriptFunctionPtr shouldInterruptScript; 130 131 typedef bool (*JavaScriptExperimentsEnabledFunctionPtr)(const JSGlobalObject*); 132 JavaScriptExperimentsEnabledFunctionPtr javaScriptExperimentsEnabled; 133 134 typedef void (*QueueTaskToEventLoopFunctionPtr)(const JSGlobalObject*, PassRefPtr<Microtask>); 135 QueueTaskToEventLoopFunctionPtr queueTaskToEventLoop; 136 137 typedef bool (*ShouldInterruptScriptBeforeTimeoutPtr)(const JSGlobalObject*); 138 ShouldInterruptScriptBeforeTimeoutPtr shouldInterruptScriptBeforeTimeout; 139}; 140 141class JSGlobalObject : public JSSegmentedVariableObject { 142private: 143 typedef HashSet<RefPtr<OpaqueJSWeakObjectMap>> WeakMapSet; 144 typedef HashMap<OpaqueJSClass*, std::unique_ptr<OpaqueJSClassContextData>> OpaqueJSClassDataMap; 145 146 struct JSGlobalObjectRareData { 147 JSGlobalObjectRareData() 148 : profileGroup(0) 149 { 150 } 151 152 WeakMapSet weakMaps; 153 unsigned profileGroup; 154 155 OpaqueJSClassDataMap opaqueJSClassData; 156 }; 157 158protected: 159 Register m_globalCallFrame[JSStack::CallFrameHeaderSize]; 160 161 WriteBarrier<JSObject> m_globalThis; 162 163 WriteBarrier<RegExpConstructor> m_regExpConstructor; 164 WriteBarrier<ErrorConstructor> m_errorConstructor; 165 WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor; 166 WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor; 167 WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor; 168 WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor; 169 WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor; 170 WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor; 171#if ENABLE(PROMISES) 172 WriteBarrier<JSPromiseConstructor> m_promiseConstructor; 173#endif 174 WriteBarrier<ObjectConstructor> m_objectConstructor; 175 176 WriteBarrier<JSFunction> m_evalFunction; 177 WriteBarrier<JSFunction> m_callFunction; 178 WriteBarrier<JSFunction> m_applyFunction; 179 WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter; 180 181 WriteBarrier<ObjectPrototype> m_objectPrototype; 182 WriteBarrier<FunctionPrototype> m_functionPrototype; 183 WriteBarrier<ArrayPrototype> m_arrayPrototype; 184 WriteBarrier<RegExpPrototype> m_regExpPrototype; 185#if ENABLE(PROMISES) 186 WriteBarrier<JSPromisePrototype> m_promisePrototype; 187#endif 188 189 WriteBarrier<Structure> m_withScopeStructure; 190 WriteBarrier<Structure> m_strictEvalActivationStructure; 191 WriteBarrier<Structure> m_activationStructure; 192 WriteBarrier<Structure> m_nameScopeStructure; 193 WriteBarrier<Structure> m_argumentsStructure; 194 195 // Lists the actual structures used for having these particular indexing shapes. 196 WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes]; 197 // Lists the structures we should use during allocation for these particular indexing shapes. 198 WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes]; 199 200 WriteBarrier<Structure> m_callbackConstructorStructure; 201 WriteBarrier<Structure> m_callbackFunctionStructure; 202 WriteBarrier<Structure> m_callbackObjectStructure; 203#if JSC_OBJC_API_ENABLED 204 WriteBarrier<Structure> m_objcCallbackFunctionStructure; 205 WriteBarrier<Structure> m_objcWrapperObjectStructure; 206#endif 207 WriteBarrier<Structure> m_nullPrototypeObjectStructure; 208 WriteBarrier<Structure> m_functionStructure; 209 WriteBarrier<Structure> m_boundFunctionStructure; 210 WriteBarrier<Structure> m_namedFunctionStructure; 211 PropertyOffset m_functionNameOffset; 212 WriteBarrier<Structure> m_privateNameStructure; 213 WriteBarrier<Structure> m_regExpMatchesArrayStructure; 214 WriteBarrier<Structure> m_regExpStructure; 215 WriteBarrier<Structure> m_consoleStructure; 216 WriteBarrier<Structure> m_internalFunctionStructure; 217 218 WriteBarrier<Structure> m_iteratorResultStructure; 219 220#if ENABLE(PROMISES) 221 WriteBarrier<Structure> m_promiseStructure; 222#endif // ENABLE(PROMISES) 223 224#define DEFINE_STORAGE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ 225 WriteBarrier<capitalName ## Prototype> m_ ## lowerName ## Prototype; \ 226 WriteBarrier<Structure> m_ ## properName ## Structure; 227 228 FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE) 229 230#undef DEFINE_STORAGE_FOR_SIMPLE_TYPE 231 232 struct TypedArrayData { 233 WriteBarrier<JSObject> prototype; 234 WriteBarrier<Structure> structure; 235 }; 236 237 std::array<TypedArrayData, NUMBER_OF_TYPED_ARRAY_TYPES> m_typedArrays; 238 239 void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT. 240 241 String m_name; 242 243 Debugger* m_debugger; 244 245 VM& m_vm; 246 247#if ENABLE(WEB_REPLAY) 248 RefPtr<InputCursor> m_inputCursor; 249#endif 250 251#if ENABLE(REMOTE_INSPECTOR) 252 std::unique_ptr<Inspector::JSGlobalObjectInspectorController> m_inspectorController; 253 std::unique_ptr<JSGlobalObjectDebuggable> m_inspectorDebuggable; 254#endif 255 256 RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint; 257 RefPtr<WatchpointSet> m_havingABadTimeWatchpoint; 258 RefPtr<WatchpointSet> m_varInjectionWatchpoint; 259 260 OwnPtr<JSGlobalObjectRareData> m_rareData; 261 262 WeakRandom m_weakRandom; 263 264 bool m_evalEnabled; 265 String m_evalDisabledErrorMessage; 266 bool m_experimentsEnabled; 267 ConsoleClient* m_consoleClient; 268 269 static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable; 270 const GlobalObjectMethodTable* m_globalObjectMethodTable; 271 272 void createRareDataIfNeeded() 273 { 274 if (m_rareData) 275 return; 276 m_rareData = adoptPtr(new JSGlobalObjectRareData); 277 } 278 279public: 280 typedef JSSegmentedVariableObject Base; 281 282 static JSGlobalObject* create(VM& vm, Structure* structure) 283 { 284 JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure); 285 globalObject->finishCreation(vm); 286 vm.heap.addFinalizer(globalObject, destroy); 287 return globalObject; 288 } 289 290 DECLARE_EXPORT_INFO; 291 292 bool hasDebugger() const { return m_debugger; } 293 bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); } 294 295protected: 296 JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0); 297 298 void finishCreation(VM& vm) 299 { 300 Base::finishCreation(vm); 301 structure()->setGlobalObject(vm, this); 302 m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); 303 init(); 304 setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, prototype(), PureForwardingProxyType), this)); 305 } 306 307 void finishCreation(VM& vm, JSObject* thisValue) 308 { 309 Base::finishCreation(vm); 310 structure()->setGlobalObject(vm, this); 311 m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); 312 init(); 313 setGlobalThis(vm, thisValue); 314 } 315 316 struct NewGlobalVar { 317 int registerNumber; 318 VariableWatchpointSet* set; 319 }; 320 NewGlobalVar addGlobalVar(const Identifier&, ConstantMode); 321 322public: 323 JS_EXPORT_PRIVATE ~JSGlobalObject(); 324 JS_EXPORT_PRIVATE static void destroy(JSCell*); 325 // We don't need a destructor because we use a finalizer instead. 326 static const bool needsDestruction = false; 327 328 JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); 329 330 JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 331 bool hasOwnPropertyForWrite(ExecState*, PropertyName); 332 JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); 333 334 JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes); 335 JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes); 336 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); 337 338 // We use this in the code generator as we perform symbol table 339 // lookups prior to initializing the properties 340 bool symbolTableHasProperty(PropertyName); 341 342 void addVar(ExecState* exec, const Identifier& propertyName) 343 { 344 if (!hasProperty(exec, propertyName)) 345 addGlobalVar(propertyName, IsVariable); 346 } 347 void addConst(ExecState* exec, const Identifier& propertyName) 348 { 349 if (!hasProperty(exec, propertyName)) 350 addGlobalVar(propertyName, IsConstant); 351 } 352 void addFunction(ExecState*, const Identifier&, JSValue); 353 354 // The following accessors return pristine values, even if a script 355 // replaces the global object's associated property. 356 357 RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); } 358 359 ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); } 360 ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); } 361 NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); } 362 NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); } 363 NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); } 364 NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); } 365 NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); } 366 NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); } 367#if ENABLE(PROMISES) 368 JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); } 369#endif 370 371 JSFunction* evalFunction() const { return m_evalFunction.get(); } 372 JSFunction* callFunction() const { return m_callFunction.get(); } 373 JSFunction* applyFunction() const { return m_applyFunction.get(); } 374 GetterSetter* throwTypeErrorGetterSetter(VM& vm) 375 { 376 if (!m_throwTypeErrorGetterSetter) 377 createThrowTypeError(vm); 378 return m_throwTypeErrorGetterSetter.get(); 379 } 380 381 ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); } 382 FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); } 383 ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); } 384 BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); } 385 StringPrototype* stringPrototype() const { return m_stringPrototype.get(); } 386 NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); } 387 DatePrototype* datePrototype() const { return m_datePrototype.get(); } 388 RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); } 389 ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); } 390#if ENABLE(PROMISES) 391 JSPromisePrototype* promisePrototype() const { return m_promisePrototype.get(); } 392#endif 393 394 Structure* withScopeStructure() const { return m_withScopeStructure.get(); } 395 Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); } 396 Structure* activationStructure() const { return m_activationStructure.get(); } 397 Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); } 398 Structure* argumentsStructure() const { return m_argumentsStructure.get(); } 399 Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const 400 { 401 ASSERT(indexingType & IsArray); 402 return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); 403 } 404 Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const 405 { 406 ASSERT(indexingType & IsArray); 407 return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); 408 } 409 Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const 410 { 411 return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile)); 412 } 413 414 bool isOriginalArrayStructure(Structure* structure) 415 { 416 return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure; 417 } 418 419 Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } 420 Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); } 421 Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); } 422 Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); } 423#if JSC_OBJC_API_ENABLED 424 Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(); } 425 Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(); } 426#endif 427 Structure* dateStructure() const { return m_dateStructure.get(); } 428 Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); } 429 Structure* errorStructure() const { return m_errorStructure.get(); } 430 Structure* functionStructure() const { return m_functionStructure.get(); } 431 Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); } 432 Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); } 433 PropertyOffset functionNameOffset() const { return m_functionNameOffset; } 434 Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); } 435 Structure* privateNameStructure() const { return m_privateNameStructure.get(); } 436 Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); } 437 Structure* mapStructure() const { return m_mapStructure.get(); } 438 Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } 439 Structure* regExpStructure() const { return m_regExpStructure.get(); } 440 Structure* setStructure() const { return m_setStructure.get(); } 441 Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); } 442 Structure* iteratorResultStructure() const { return m_iteratorResultStructure.get(); } 443 static ptrdiff_t iteratorResultStructureOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_iteratorResultStructure); } 444 445#if ENABLE(PROMISES) 446 Structure* promiseStructure() const { return m_promiseStructure.get(); } 447#endif // ENABLE(PROMISES) 448 449 JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool); 450 JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const; 451 452#if ENABLE(WEB_REPLAY) 453 JS_EXPORT_PRIVATE void setInputCursor(PassRefPtr<InputCursor>); 454 InputCursor& inputCursor() const { return *m_inputCursor; } 455#endif 456 457#if ENABLE(REMOTE_INSPECTOR) 458 Inspector::JSGlobalObjectInspectorController& inspectorController() const { return *m_inspectorController.get(); } 459 JSGlobalObjectDebuggable& inspectorDebuggable() { return *m_inspectorDebuggable.get(); } 460#endif 461 462 JS_EXPORT_PRIVATE void setConsoleClient(ConsoleClient* consoleClient) { m_consoleClient = consoleClient; } 463 ConsoleClient* consoleClient() const { return m_consoleClient; } 464 465 void setName(const String&); 466 const String& name() const { return m_name; } 467 468 JSArrayBufferPrototype* arrayBufferPrototype() const { return m_arrayBufferPrototype.get(); } 469 470#define DEFINE_ACCESSORS_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ 471 Structure* properName ## Structure() { return m_ ## properName ## Structure.get(); } 472 473 FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE) 474 475#undef DEFINE_ACCESSORS_FOR_SIMPLE_TYPE 476 477 Structure* typedArrayStructure(TypedArrayType type) const 478 { 479 return m_typedArrays[toIndex(type)].structure.get(); 480 } 481 bool isOriginalTypedArrayStructure(Structure* structure) 482 { 483 TypedArrayType type = structure->classInfo()->typedArrayStorageType; 484 if (type == NotTypedArray) 485 return false; 486 return typedArrayStructure(type) == structure; 487 } 488 489 void* actualPointerFor(Special::Pointer pointer) 490 { 491 ASSERT(pointer < Special::TableSize); 492 return m_specialPointers[pointer]; 493 } 494 495 WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); } 496 WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); } 497 WatchpointSet* varInjectionWatchpoint() { return m_varInjectionWatchpoint.get(); } 498 499 bool isHavingABadTime() const 500 { 501 return m_havingABadTimeWatchpoint->hasBeenInvalidated(); 502 } 503 504 void haveABadTime(VM&); 505 506 bool objectPrototypeIsSane(); 507 bool arrayPrototypeChainIsSane(); 508 bool stringPrototypeChainIsSane(); 509 510 void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; } 511 unsigned profileGroup() const 512 { 513 if (!m_rareData) 514 return 0; 515 return m_rareData->profileGroup; 516 } 517 518 Debugger* debugger() const { return m_debugger; } 519 void setDebugger(Debugger* debugger) { m_debugger = debugger; } 520 521 const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; } 522 523 static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; } 524 static bool supportsProfiling(const JSGlobalObject*) { return false; } 525 static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; } 526 527 JS_EXPORT_PRIVATE ExecState* globalExec(); 528 529 static bool shouldInterruptScript(const JSGlobalObject*) { return true; } 530 static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; } 531 static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return false; } 532 533 void queueMicrotask(PassRefPtr<Microtask>); 534 535 bool evalEnabled() const { return m_evalEnabled; } 536 const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; } 537 void setEvalEnabled(bool enabled, const String& errorMessage = String()) 538 { 539 m_evalEnabled = enabled; 540 m_evalDisabledErrorMessage = errorMessage; 541 } 542 543 void resetPrototype(VM&, JSValue prototype); 544 545 VM& vm() const { return m_vm; } 546 JSObject* globalThis() const; 547 548 static Structure* createStructure(VM& vm, JSValue prototype) 549 { 550 return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info()); 551 } 552 553 void registerWeakMap(OpaqueJSWeakObjectMap* map) 554 { 555 createRareDataIfNeeded(); 556 m_rareData->weakMaps.add(map); 557 } 558 559 void unregisterWeakMap(OpaqueJSWeakObjectMap* map) 560 { 561 if (m_rareData) 562 m_rareData->weakMaps.remove(map); 563 } 564 565 OpaqueJSClassDataMap& opaqueJSClassData() 566 { 567 createRareDataIfNeeded(); 568 return m_rareData->opaqueJSClassData; 569 } 570 571 double weakRandomNumber() { return m_weakRandom.get(); } 572 unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } 573 574 UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); 575 UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*); 576 577protected: 578 579 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; 580 581 struct GlobalPropertyInfo { 582 GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) 583 : identifier(i) 584 , value(v) 585 , attributes(a) 586 { 587 } 588 589 const Identifier identifier; 590 JSValue value; 591 unsigned attributes; 592 }; 593 JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count); 594 595 JS_EXPORT_PRIVATE static JSC::JSValue toThis(JSC::JSCell*, JSC::ExecState*, ECMAMode); 596 597private: 598 friend class LLIntOffsetsExtractor; 599 600 JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis); 601 602 // FIXME: Fold reset into init. 603 JS_EXPORT_PRIVATE void init(); 604 void reset(JSValue prototype); 605 606 void createThrowTypeError(VM&); 607 608 JS_EXPORT_PRIVATE static void clearRareData(JSCell*); 609}; 610 611JSGlobalObject* asGlobalObject(JSValue); 612 613inline JSGlobalObject* asGlobalObject(JSValue value) 614{ 615 ASSERT(asObject(value)->isGlobalObject()); 616 return jsCast<JSGlobalObject*>(asObject(value)); 617} 618 619inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName) 620{ 621 PropertySlot slot(this); 622 if (Base::getOwnPropertySlot(this, exec, propertyName, slot)) 623 return true; 624 bool slotIsWriteable; 625 return symbolTableGet(this, propertyName, slot, slotIsWriteable); 626} 627 628inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName) 629{ 630 SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid()); 631 return !entry.isNull(); 632} 633 634inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0) 635{ 636 return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength)); 637} 638 639inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0) 640{ 641 return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength); 642} 643 644inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values) 645{ 646 return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values)); 647} 648 649inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values) 650{ 651 return constructArray(exec, profile, exec->lexicalGlobalObject(), values); 652} 653 654inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) 655{ 656 return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); 657} 658 659inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) 660{ 661 return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length); 662} 663 664inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) 665{ 666 return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArrayNegativeIndexed(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); 667} 668 669inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) 670{ 671 return constructArrayNegativeIndexed(exec, profile, exec->lexicalGlobalObject(), values, length); 672} 673 674inline JSObject* JSScope::globalThis() 675{ 676 return globalObject()->globalThis(); 677} 678 679inline JSObject* JSGlobalObject::globalThis() const 680{ 681 return m_globalThis.get(); 682} 683 684} // namespace JSC 685 686#endif // JSGlobalObject_h 687