GlobalObject.h (43748B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef vm_GlobalObject_h 8 #define vm_GlobalObject_h 9 10 #include "js/GlobalObject.h" 11 12 #include "mozilla/Assertions.h" 13 #include "mozilla/EnumeratedArray.h" 14 15 #include <stdint.h> 16 #include <type_traits> 17 18 #include "jsexn.h" 19 #include "jsfriendapi.h" 20 #include "jspubtd.h" 21 #include "jstypes.h" 22 #include "NamespaceImports.h" 23 24 #ifdef JS_HAS_INTL_API 25 # include "builtin/intl/GlobalIntlData.h" 26 #endif 27 #include "gc/AllocKind.h" 28 #include "js/CallArgs.h" 29 #include "js/Class.h" 30 #include "js/ErrorReport.h" 31 #include "js/PropertyDescriptor.h" 32 #include "js/RootingAPI.h" 33 #include "js/TypeDecls.h" 34 #include "js/Value.h" 35 #include "vm/ArrayObject.h" 36 #include "vm/JSAtomState.h" 37 #include "vm/JSContext.h" 38 #include "vm/JSFunction.h" 39 #include "vm/JSObject.h" 40 #include "vm/NativeObject.h" 41 #include "vm/Realm.h" 42 #include "vm/RegExpShared.h" 43 #include "vm/Shape.h" 44 #include "vm/StringType.h" 45 46 struct JSFunctionSpec; 47 class JSJitInfo; 48 struct JSPrincipals; 49 struct JSPropertySpec; 50 51 namespace JS { 52 class JS_PUBLIC_API RealmOptions; 53 }; 54 55 namespace js { 56 57 class ArgumentsObject; 58 class GlobalScope; 59 class GlobalLexicalEnvironmentObject; 60 class MapObject; 61 class PlainObject; 62 class PropertyIteratorObject; 63 class RegExpStatics; 64 class SetObject; 65 66 // Fixed slot capacities for PlainObjects. The global has a cached Shape for 67 // PlainObject with default prototype for each of these values. 68 enum class PlainObjectSlotsKind { 69 Slots0, 70 Slots2, 71 Slots4, 72 Slots6, 73 Slots8, 74 Slots12, 75 Slots16, 76 Limit 77 }; 78 79 static PlainObjectSlotsKind PlainObjectSlotsKindFromAllocKind( 80 gc::AllocKind kind) { 81 switch (kind) { 82 case gc::AllocKind::OBJECT0: 83 return PlainObjectSlotsKind::Slots0; 84 case gc::AllocKind::OBJECT2: 85 return PlainObjectSlotsKind::Slots2; 86 case gc::AllocKind::OBJECT4: 87 return PlainObjectSlotsKind::Slots4; 88 case gc::AllocKind::OBJECT6: 89 return PlainObjectSlotsKind::Slots6; 90 case gc::AllocKind::OBJECT8: 91 return PlainObjectSlotsKind::Slots8; 92 case gc::AllocKind::OBJECT12: 93 return PlainObjectSlotsKind::Slots12; 94 case gc::AllocKind::OBJECT16: 95 return PlainObjectSlotsKind::Slots16; 96 default: 97 break; 98 } 99 MOZ_CRASH("Invalid kind"); 100 } 101 102 // Data attached to a GlobalObject. This is freed when clearing the Realm's 103 // global_ only because this way we don't need to add a finalizer to all 104 // GlobalObject JSClasses. 105 class GlobalObjectData { 106 friend class js::GlobalObject; 107 108 GlobalObjectData(const GlobalObjectData&) = delete; 109 void operator=(const GlobalObjectData&) = delete; 110 111 public: 112 explicit GlobalObjectData(Zone* zone); 113 114 ~GlobalObjectData(); 115 116 // The original values for built-in constructors (with their prototype 117 // objects) based on JSProtoKey. 118 // 119 // This is necessary to implement spec language speaking in terms of "the 120 // original Array prototype object", or "as if by the expression new Array()" 121 // referring to the original Array constructor. The actual (writable and even 122 // deletable) Object, Array, &c. properties are not stored here. 123 struct ConstructorWithProto { 124 GCPtr<JSObject*> constructor; 125 GCPtr<JSObject*> prototype; 126 }; 127 using CtorArray = mozilla::EnumeratedArray<JSProtoKey, ConstructorWithProto, 128 size_t(JSProto_LIMIT)>; 129 CtorArray builtinConstructors; 130 131 // Built-in prototypes for this global. Note that this is different from the 132 // set of built-in constructors/prototypes based on JSProtoKey. 133 enum class ProtoKind { 134 ArrayIteratorProto, 135 StringIteratorProto, 136 RegExpStringIteratorProto, 137 GeneratorObjectProto, 138 AsyncIteratorProto, 139 AsyncFromSyncIteratorProto, 140 AsyncGeneratorProto, 141 MapIteratorProto, 142 SetIteratorProto, 143 WrapForValidIteratorProto, 144 IteratorHelperProto, 145 AsyncIteratorHelperProto, 146 SegmentsProto, 147 SegmentIteratorProto, 148 #ifdef NIGHTLY_BUILD 149 IteratorRangeProto, 150 #endif 151 Limit 152 }; 153 using ProtoArray = mozilla::EnumeratedArray<ProtoKind, GCPtr<JSObject*>, 154 size_t(ProtoKind::Limit)>; 155 ProtoArray builtinProtos; 156 157 GCPtr<GlobalScope*> emptyGlobalScope; 158 159 // The lexical environment for global let/const/class bindings. 160 GCPtr<GlobalLexicalEnvironmentObject*> lexicalEnvironment; 161 162 // The WindowProxy associated with this global. 163 GCPtr<JSObject*> windowProxy; 164 165 // Functions and other top-level values for self-hosted code. The "computed" 166 // holder is used as the target of `SetIntrinsic` calls, but the same property 167 // may also be cached on the normal intrinsics holder for `GetIntrinsic`. 168 GCPtr<NativeObject*> intrinsicsHolder; 169 GCPtr<NativeObject*> computedIntrinsicsHolder; 170 171 // List of source URLs for this realm. This is used by the debugger. 172 GCPtr<ArrayObject*> sourceURLsHolder; 173 174 // Realm-specific object that can be used as key in WeakMaps. 175 GCPtr<PlainObject*> realmKeyObject; 176 177 // The unique %ThrowTypeError% function for this global. 178 GCPtr<JSFunction*> throwTypeError; 179 180 // The unique %eval% function (for indirect eval) for this global. 181 GCPtr<JSFunction*> eval; 182 183 // Empty iterator object used for for-in with null/undefined. 184 GCPtr<PropertyIteratorObject*> emptyIterator; 185 186 // Cached shape for new arrays with Array.prototype as prototype. 187 GCPtr<SharedShape*> arrayShapeWithDefaultProto; 188 189 // Shape for PlainObject with %Object.prototype% as proto, for each object 190 // AllocKind. 191 using PlainObjectShapeArray = 192 mozilla::EnumeratedArray<PlainObjectSlotsKind, GCPtr<SharedShape*>, 193 size_t(PlainObjectSlotsKind::Limit)>; 194 PlainObjectShapeArray plainObjectShapesWithDefaultProto; 195 196 // Shape for JSFunction with %Function.prototype% as proto, for both 197 // non-extended and extended functions. 198 GCPtr<SharedShape*> functionShapeWithDefaultProto; 199 GCPtr<SharedShape*> extendedFunctionShapeWithDefaultProto; 200 201 // Shape for BoundFunctionObject with %Function.prototype% as proto. 202 GCPtr<SharedShape*> boundFunctionShapeWithDefaultProto; 203 204 // Shape for RegExpObject with %RegExp.prototype% as proto. 205 GCPtr<SharedShape*> regExpShapeWithDefaultProto; 206 207 // Global state for regular expressions. 208 RegExpRealm regExpRealm; 209 210 #ifdef JS_HAS_INTL_API 211 // Cache Intl formatters. 212 intl::GlobalIntlData globalIntlData; 213 #endif 214 215 GCPtr<ArgumentsObject*> mappedArgumentsTemplate; 216 GCPtr<ArgumentsObject*> unmappedArgumentsTemplate; 217 218 // Template objects to speed up allocation of Map/Set objects. 219 GCPtr<MapObject*> mapObjectTemplate; 220 GCPtr<SetObject*> setObjectTemplate; 221 222 GCPtr<PlainObject*> iterResultTemplate; 223 GCPtr<PlainObject*> iterResultWithoutPrototypeTemplate; 224 225 // Lazily initialized script source object to use for scripts cloned from the 226 // self-hosting stencil. 227 GCPtr<ScriptSourceObject*> selfHostingScriptSource; 228 229 // The number of times that one of the following has occurred: 230 // 1. A property of this GlobalObject is deleted. 231 // 2. A data property of this GlobalObject is converted to an accessor, 232 // or vice versa. 233 // 3. A property is defined on the global lexical that shadows a property on 234 // this GlobalObject. 235 uint32_t generationCount = 0; 236 237 // Whether the |globalThis| property has been resolved on the global object. 238 bool globalThisResolved = false; 239 240 void trace(JSTracer* trc, GlobalObject* global); 241 void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, 242 JS::ClassInfo* info) const; 243 244 static constexpr size_t offsetOfLexicalEnvironment() { 245 static_assert(sizeof(lexicalEnvironment) == sizeof(uintptr_t), 246 "JIT code assumes field is pointer-sized"); 247 return offsetof(GlobalObjectData, lexicalEnvironment); 248 } 249 static constexpr size_t offsetOfRegExpRealm() { 250 return offsetof(GlobalObjectData, regExpRealm); 251 } 252 }; 253 254 class GlobalObject : public NativeObject { 255 enum : unsigned { 256 GLOBAL_DATA_SLOT = JSCLASS_GLOBAL_APPLICATION_SLOTS, 257 258 // Total reserved-slot count for global objects. 259 RESERVED_SLOTS 260 }; 261 262 // The slot count must be in the public API for JSCLASS_GLOBAL_FLAGS, and 263 // we won't expose GlobalObject, so just assert that the two values are 264 // synchronized. 265 static_assert(JSCLASS_GLOBAL_SLOT_COUNT == RESERVED_SLOTS, 266 "global object slot counts are inconsistent"); 267 268 // Ensure GlobalObjectData is only one dereference away. 269 static_assert(GLOBAL_DATA_SLOT < MAX_FIXED_SLOTS, 270 "GlobalObjectData should be stored in a fixed slot for " 271 "performance reasons"); 272 273 public: 274 using ProtoKind = GlobalObjectData::ProtoKind; 275 276 private: 277 GlobalObjectData* maybeData() { 278 Value v = getReservedSlot(GLOBAL_DATA_SLOT); 279 return static_cast<GlobalObjectData*>(v.toPrivate()); 280 } 281 const GlobalObjectData* maybeData() const { 282 Value v = getReservedSlot(GLOBAL_DATA_SLOT); 283 return static_cast<const GlobalObjectData*>(v.toPrivate()); 284 } 285 286 GlobalObjectData& data() { return *maybeData(); } 287 const GlobalObjectData& data() const { return *maybeData(); } 288 289 void initBuiltinProto(ProtoKind kind, JSObject* proto) { 290 MOZ_ASSERT(proto); 291 // Use set, as it's possible to construct oomTest test 292 // cases where the proto is already initialized. 293 // 294 // See Bugs 1969353 and 1928852. 295 data().builtinProtos[kind].set(proto); 296 } 297 298 void setBuiltinProto(ProtoKind kind, JSObject* proto) { 299 MOZ_ASSERT(proto); 300 data().builtinProtos[kind].set(proto); 301 } 302 303 bool hasBuiltinProto(ProtoKind kind) const { 304 return bool(data().builtinProtos[kind]); 305 } 306 JSObject& getBuiltinProto(ProtoKind kind) const { 307 MOZ_ASSERT(hasBuiltinProto(kind)); 308 return *data().builtinProtos[kind]; 309 } 310 311 public: 312 GlobalLexicalEnvironmentObject& lexicalEnvironment() { 313 return *data().lexicalEnvironment; 314 } 315 GlobalScope& emptyGlobalScope() const; 316 317 void traceData(JSTracer* trc, GlobalObject* global) { 318 data().trace(trc, global); 319 } 320 void releaseData(JS::GCContext* gcx); 321 322 void addSizeOfData(mozilla::MallocSizeOf mallocSizeOf, 323 JS::ClassInfo* info) const { 324 if (maybeData()) { 325 data().addSizeOfIncludingThis(mallocSizeOf, info); 326 } 327 } 328 329 void setOriginalEval(JSFunction* evalFun) { 330 MOZ_ASSERT(!data().eval); 331 data().eval.init(evalFun); 332 } 333 334 bool hasConstructor(JSProtoKey key) const { 335 return bool(data().builtinConstructors[key].constructor); 336 } 337 JSObject& getConstructor(JSProtoKey key) const { 338 MOZ_ASSERT(hasConstructor(key)); 339 return *maybeGetConstructor(key); 340 } 341 342 static bool skipDeselectedConstructor(JSContext* cx, JSProtoKey key); 343 344 private: 345 enum class IfClassIsDisabled { DoNothing, Throw }; 346 347 static bool resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, 348 JSProtoKey key, IfClassIsDisabled mode); 349 350 public: 351 static bool ensureConstructor(JSContext* cx, Handle<GlobalObject*> global, 352 JSProtoKey key) { 353 if (global->isStandardClassResolved(key)) { 354 return true; 355 } 356 return resolveConstructor(cx, global, key, IfClassIsDisabled::Throw); 357 } 358 359 static JSObject* getOrCreateConstructor(JSContext* cx, JSProtoKey key) { 360 MOZ_ASSERT(key != JSProto_Null); 361 Handle<GlobalObject*> global = cx->global(); 362 if (!GlobalObject::ensureConstructor(cx, global, key)) { 363 return nullptr; 364 } 365 return &global->getConstructor(key); 366 } 367 368 static JSObject* getOrCreatePrototype(JSContext* cx, JSProtoKey key) { 369 MOZ_ASSERT(key != JSProto_Null); 370 Handle<GlobalObject*> global = cx->global(); 371 if (!GlobalObject::ensureConstructor(cx, global, key)) { 372 return nullptr; 373 } 374 return &global->getPrototype(key); 375 } 376 377 static JS::Handle<JSObject*> getOrCreatePrototypeHandle(JSContext* cx, 378 JSProtoKey key) { 379 MOZ_ASSERT(key != JSProto_Null); 380 Handle<GlobalObject*> global = cx->global(); 381 if (!GlobalObject::ensureConstructor(cx, global, key)) { 382 return nullptr; 383 } 384 return global->getPrototypeHandle(key); 385 } 386 387 JSObject* maybeGetConstructor(JSProtoKey protoKey) const { 388 MOZ_ASSERT(JSProto_Null < protoKey); 389 MOZ_ASSERT(protoKey < JSProto_LIMIT); 390 return data().builtinConstructors[protoKey].constructor; 391 } 392 393 template <typename T> 394 T* maybeGetConstructor(JSProtoKey protoKey) const { 395 JSObject* ctor = maybeGetConstructor(protoKey); 396 return ctor ? &ctor->as<T>() : nullptr; 397 } 398 399 JSObject* maybeGetPrototype(JSProtoKey protoKey) const { 400 MOZ_ASSERT(JSProto_Null < protoKey); 401 MOZ_ASSERT(protoKey < JSProto_LIMIT); 402 return data().builtinConstructors[protoKey].prototype; 403 } 404 405 template <typename T> 406 T* maybeGetPrototype(JSProtoKey protoKey) const { 407 JSObject* proto = maybeGetPrototype(protoKey); 408 return proto ? &proto->as<T>() : nullptr; 409 } 410 411 static bool maybeResolveGlobalThis(JSContext* cx, 412 Handle<GlobalObject*> global, 413 bool* resolved); 414 415 void setConstructor(JSProtoKey key, JSObject* obj) { 416 MOZ_ASSERT(obj); 417 data().builtinConstructors[key].constructor = obj; 418 } 419 420 bool hasPrototype(JSProtoKey key) const { 421 return bool(data().builtinConstructors[key].prototype); 422 } 423 JSObject& getPrototype(JSProtoKey key) const { 424 MOZ_ASSERT(hasPrototype(key)); 425 return *maybeGetPrototype(key); 426 } 427 428 JS::Handle<JSObject*> getPrototypeHandle(JSProtoKey protoKey) const { 429 MOZ_ASSERT(hasPrototype(protoKey)); 430 MOZ_ASSERT(JSProto_Null < protoKey); 431 MOZ_ASSERT(protoKey < JSProto_LIMIT); 432 return Handle<JSObject*>::fromMarkedLocation( 433 &data().builtinConstructors[protoKey].prototype.get()); 434 } 435 436 void setPrototype(JSProtoKey key, JSObject* obj) { 437 MOZ_ASSERT(obj); 438 data().builtinConstructors[key].prototype = obj; 439 } 440 441 /* 442 * Lazy standard classes need a way to indicate they have been initialized. 443 * Otherwise, when we delete them, we might accidentally recreate them via 444 * a lazy initialization. We use the presence of an object in the constructor 445 * array to indicate that they've been initialized. 446 * 447 * Note: A few builtin objects, like JSON and Math, are not constructors, 448 * so getConstructor is a bit of a misnomer. 449 */ 450 bool isStandardClassResolved(JSProtoKey key) const { 451 return hasConstructor(key); 452 } 453 454 private: 455 bool classIsInitialized(JSProtoKey key) const { 456 bool inited = hasConstructor(key); 457 MOZ_ASSERT(inited == hasPrototype(key)); 458 return inited; 459 } 460 461 bool functionObjectClassesInitialized() const { 462 bool inited = classIsInitialized(JSProto_Function); 463 MOZ_ASSERT(inited == classIsInitialized(JSProto_Object)); 464 return inited; 465 } 466 467 // Disallow use of unqualified JSObject::create in GlobalObject. 468 static GlobalObject* create(...) = delete; 469 470 friend struct ::JSRuntime; 471 static GlobalObject* createInternal(JSContext* cx, const JSClass* clasp); 472 473 public: 474 static GlobalObject* new_(JSContext* cx, const JSClass* clasp, 475 JSPrincipals* principals, 476 JS::OnNewGlobalHookOption hookOption, 477 const JS::RealmOptions& options); 478 479 /* 480 * Create a constructor function with the specified name and length using 481 * ctor, a method which creates objects with the given class. 482 */ 483 static JSFunction* createConstructor( 484 JSContext* cx, JSNative ctor, JSAtom* name, unsigned length, 485 gc::AllocKind kind = gc::AllocKind::FUNCTION, 486 const JSJitInfo* jitInfo = nullptr); 487 488 /* 489 * Create an object to serve as [[Prototype]] for instances of the given 490 * class, using |Object.prototype| as its [[Prototype]]. Users creating 491 * prototype objects with particular internal structure (e.g. reserved 492 * slots guaranteed to contain values of particular types) must immediately 493 * complete the minimal initialization to make the returned object safe to 494 * touch. 495 */ 496 static NativeObject* createBlankPrototype( 497 JSContext* cx, Handle<GlobalObject*> global, const JSClass* clasp, 498 ObjectFlags objFlags = ObjectFlags()); 499 500 /* 501 * Identical to createBlankPrototype, but uses proto as the [[Prototype]] 502 * of the returned blank prototype. 503 */ 504 static NativeObject* createBlankPrototypeInheriting(JSContext* cx, 505 const JSClass* clasp, 506 HandleObject proto); 507 508 template <typename T> 509 static T* createBlankPrototypeInheriting(JSContext* cx, HandleObject proto) { 510 NativeObject* res = createBlankPrototypeInheriting(cx, &T::class_, proto); 511 return res ? &res->template as<T>() : nullptr; 512 } 513 514 template <typename T> 515 static T* createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global, 516 ObjectFlags objFlags = ObjectFlags()) { 517 NativeObject* res = createBlankPrototype(cx, global, &T::class_, objFlags); 518 return res ? &res->template as<T>() : nullptr; 519 } 520 521 // Object, Function, and eval are eagerly resolved when creating the global. 522 JSObject& getObjectPrototype() { 523 MOZ_ASSERT(functionObjectClassesInitialized()); 524 return getPrototype(JSProto_Object); 525 } 526 Handle<JSObject*> getObjectPrototypeHandle() { 527 MOZ_ASSERT(functionObjectClassesInitialized()); 528 return getPrototypeHandle(JSProto_Object); 529 } 530 JSObject& getFunctionConstructor() { 531 MOZ_ASSERT(functionObjectClassesInitialized()); 532 return getConstructor(JSProto_Function); 533 } 534 JSObject& getFunctionPrototype() { 535 MOZ_ASSERT(functionObjectClassesInitialized()); 536 return getPrototype(JSProto_Function); 537 } 538 Handle<JSObject*> getFunctionPrototypeHandle() { 539 MOZ_ASSERT(functionObjectClassesInitialized()); 540 return getPrototypeHandle(JSProto_Function); 541 } 542 JSFunction& getEvalFunction() { 543 MOZ_ASSERT(data().eval); 544 return *data().eval; 545 } 546 547 static NativeObject* getOrCreateArrayPrototype(JSContext* cx, 548 Handle<GlobalObject*> global) { 549 if (!ensureConstructor(cx, global, JSProto_Array)) { 550 return nullptr; 551 } 552 return &global->getPrototype(JSProto_Array).as<NativeObject>(); 553 } 554 555 NativeObject* maybeGetArrayPrototype() { 556 if (classIsInitialized(JSProto_Array)) { 557 return &getPrototype(JSProto_Array).as<NativeObject>(); 558 } 559 return nullptr; 560 } 561 562 static JSObject* getOrCreateBooleanPrototype(JSContext* cx, 563 Handle<GlobalObject*> global) { 564 if (!ensureConstructor(cx, global, JSProto_Boolean)) { 565 return nullptr; 566 } 567 return &global->getPrototype(JSProto_Boolean); 568 } 569 570 static JSObject* getOrCreateNumberPrototype(JSContext* cx, 571 Handle<GlobalObject*> global) { 572 if (!ensureConstructor(cx, global, JSProto_Number)) { 573 return nullptr; 574 } 575 return &global->getPrototype(JSProto_Number); 576 } 577 578 static JSObject* getOrCreateStringPrototype(JSContext* cx, 579 Handle<GlobalObject*> global) { 580 if (!ensureConstructor(cx, global, JSProto_String)) { 581 return nullptr; 582 } 583 return &global->getPrototype(JSProto_String); 584 } 585 586 static JSObject* getOrCreateSymbolPrototype(JSContext* cx, 587 Handle<GlobalObject*> global) { 588 if (!ensureConstructor(cx, global, JSProto_Symbol)) { 589 return nullptr; 590 } 591 return &global->getPrototype(JSProto_Symbol); 592 } 593 594 static JSObject* getOrCreateBigIntPrototype(JSContext* cx, 595 Handle<GlobalObject*> global) { 596 if (!ensureConstructor(cx, global, JSProto_BigInt)) { 597 return nullptr; 598 } 599 return &global->getPrototype(JSProto_BigInt); 600 } 601 602 static JSObject* getOrCreatePromisePrototype(JSContext* cx, 603 Handle<GlobalObject*> global) { 604 if (!ensureConstructor(cx, global, JSProto_Promise)) { 605 return nullptr; 606 } 607 return &global->getPrototype(JSProto_Promise); 608 } 609 610 static JSObject* getOrCreateRegExpPrototype(JSContext* cx, 611 Handle<GlobalObject*> global) { 612 if (!ensureConstructor(cx, global, JSProto_RegExp)) { 613 return nullptr; 614 } 615 return &global->getPrototype(JSProto_RegExp); 616 } 617 618 static JSObject* getOrCreateRegExpConstructor(JSContext* cx, 619 Handle<GlobalObject*> global) { 620 if (!ensureConstructor(cx, global, JSProto_RegExp)) { 621 return nullptr; 622 } 623 return &global->getConstructor(JSProto_RegExp); 624 } 625 626 JSObject* maybeGetRegExpPrototype() { 627 if (classIsInitialized(JSProto_RegExp)) { 628 return &getPrototype(JSProto_RegExp); 629 } 630 return nullptr; 631 } 632 633 static JSObject* getOrCreateSavedFramePrototype( 634 JSContext* cx, Handle<GlobalObject*> global) { 635 if (!ensureConstructor(cx, global, JSProto_SavedFrame)) { 636 return nullptr; 637 } 638 return &global->getPrototype(JSProto_SavedFrame); 639 } 640 641 static JSObject* getOrCreateArrayBufferConstructor( 642 JSContext* cx, Handle<GlobalObject*> global) { 643 if (!ensureConstructor(cx, global, JSProto_ArrayBuffer)) { 644 return nullptr; 645 } 646 return &global->getConstructor(JSProto_ArrayBuffer); 647 } 648 649 static JSObject* getOrCreateArrayBufferPrototype( 650 JSContext* cx, Handle<GlobalObject*> global) { 651 if (!ensureConstructor(cx, global, JSProto_ArrayBuffer)) { 652 return nullptr; 653 } 654 return &global->getPrototype(JSProto_ArrayBuffer); 655 } 656 657 static JSObject* getOrCreateSharedArrayBufferPrototype( 658 JSContext* cx, Handle<GlobalObject*> global) { 659 if (!ensureConstructor(cx, global, JSProto_SharedArrayBuffer)) { 660 return nullptr; 661 } 662 return &global->getPrototype(JSProto_SharedArrayBuffer); 663 } 664 665 static JSObject* getOrCreateSharedArrayBufferConstructor( 666 JSContext* cx, Handle<GlobalObject*> global) { 667 if (!ensureConstructor(cx, global, JSProto_SharedArrayBuffer)) { 668 return nullptr; 669 } 670 return &global->getConstructor(JSProto_SharedArrayBuffer); 671 } 672 673 static JSObject* getOrCreateCustomErrorPrototype(JSContext* cx, 674 Handle<GlobalObject*> global, 675 JSExnType exnType) { 676 JSProtoKey key = GetExceptionProtoKey(exnType); 677 if (!ensureConstructor(cx, global, key)) { 678 return nullptr; 679 } 680 return &global->getPrototype(key); 681 } 682 683 static JSFunction* getOrCreateErrorConstructor(JSContext* cx, 684 Handle<GlobalObject*> global) { 685 if (!ensureConstructor(cx, global, JSProto_Error)) { 686 return nullptr; 687 } 688 return &global->getConstructor(JSProto_Error).as<JSFunction>(); 689 } 690 691 static JSObject* getOrCreateErrorPrototype(JSContext* cx, 692 Handle<GlobalObject*> global) { 693 return getOrCreateCustomErrorPrototype(cx, global, JSEXN_ERR); 694 } 695 696 static JSFunction* getOrCreateTypedArrayConstructor( 697 JSContext* cx, Handle<GlobalObject*> global) { 698 if (!ensureConstructor(cx, global, JSProto_TypedArray)) { 699 return nullptr; 700 } 701 return &global->getConstructor(JSProto_TypedArray).as<JSFunction>(); 702 } 703 704 static JSObject* getOrCreateTypedArrayPrototype( 705 JSContext* cx, Handle<GlobalObject*> global) { 706 if (!ensureConstructor(cx, global, JSProto_TypedArray)) { 707 return nullptr; 708 } 709 return &global->getPrototype(JSProto_TypedArray); 710 } 711 712 private: 713 using ObjectInitOp = bool (*)(JSContext*, Handle<GlobalObject*>); 714 using ObjectInitWithTagOp = bool (*)(JSContext*, Handle<GlobalObject*>, 715 Handle<JSAtom*>); 716 717 static JSObject* getOrCreateBuiltinProto(JSContext* cx, 718 Handle<GlobalObject*> global, 719 ProtoKind kind, ObjectInitOp init) { 720 if (JSObject* proto = global->maybeBuiltinProto(kind)) { 721 return proto; 722 } 723 724 return createBuiltinProto(cx, global, kind, init); 725 } 726 727 static JSObject* getOrCreateBuiltinProto(JSContext* cx, 728 Handle<GlobalObject*> global, 729 ProtoKind kind, Handle<JSAtom*> tag, 730 ObjectInitWithTagOp init) { 731 if (JSObject* proto = global->maybeBuiltinProto(kind)) { 732 return proto; 733 } 734 735 return createBuiltinProto(cx, global, kind, tag, init); 736 } 737 738 static JSObject* createBuiltinProto(JSContext* cx, 739 Handle<GlobalObject*> global, 740 ProtoKind kind, ObjectInitOp init); 741 static JSObject* createBuiltinProto(JSContext* cx, 742 Handle<GlobalObject*> global, 743 ProtoKind kind, Handle<JSAtom*> tag, 744 ObjectInitWithTagOp init); 745 746 static JSObject* createIteratorPrototype(JSContext* cx, 747 Handle<GlobalObject*> global); 748 749 public: 750 JSObject* maybeBuiltinProto(ProtoKind kind) const { 751 return data().builtinProtos[kind]; 752 } 753 754 NativeObject* maybeGetIteratorPrototype() { 755 if (!hasPrototype(JSProto_Iterator)) { 756 return nullptr; 757 } 758 return &(getPrototype(JSProto_Iterator).as<NativeObject>()); 759 } 760 761 static JSObject* getOrCreateIteratorPrototype(JSContext* cx, 762 Handle<GlobalObject*> global) { 763 if (!ensureConstructor(cx, global, JSProto_Iterator)) { 764 return nullptr; 765 } 766 return &global->getPrototype(JSProto_Iterator); 767 } 768 769 static NativeObject* getOrCreateArrayIteratorPrototype( 770 JSContext* cx, Handle<GlobalObject*> global); 771 772 NativeObject* maybeGetArrayIteratorPrototype() { 773 if (JSObject* obj = maybeBuiltinProto(ProtoKind::ArrayIteratorProto)) { 774 return &obj->as<NativeObject>(); 775 } 776 return nullptr; 777 } 778 779 static JSObject* getOrCreateStringIteratorPrototype( 780 JSContext* cx, Handle<GlobalObject*> global); 781 782 static JSObject* getOrCreateRegExpStringIteratorPrototype( 783 JSContext* cx, Handle<GlobalObject*> global); 784 785 #ifdef NIGHTLY_BUILD 786 static JSObject* getOrCreateIteratorRangePrototype( 787 JSContext* cx, Handle<GlobalObject*> global); 788 #endif 789 790 void setGeneratorObjectPrototype(JSObject* obj) { 791 setBuiltinProto(ProtoKind::GeneratorObjectProto, obj); 792 } 793 794 static JSObject* getOrCreateGeneratorObjectPrototype( 795 JSContext* cx, Handle<GlobalObject*> global) { 796 if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) { 797 return nullptr; 798 } 799 return &global->getBuiltinProto(ProtoKind::GeneratorObjectProto); 800 } 801 802 static JSObject* getOrCreateGeneratorFunctionPrototype( 803 JSContext* cx, Handle<GlobalObject*> global) { 804 if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) { 805 return nullptr; 806 } 807 return &global->getPrototype(JSProto_GeneratorFunction); 808 } 809 810 static JSObject* getOrCreateGeneratorFunction(JSContext* cx, 811 Handle<GlobalObject*> global) { 812 if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) { 813 return nullptr; 814 } 815 return &global->getConstructor(JSProto_GeneratorFunction); 816 } 817 818 static JSObject* getOrCreateAsyncFunctionPrototype( 819 JSContext* cx, Handle<GlobalObject*> global) { 820 if (!ensureConstructor(cx, global, JSProto_AsyncFunction)) { 821 return nullptr; 822 } 823 return &global->getPrototype(JSProto_AsyncFunction); 824 } 825 826 static JSObject* getOrCreateAsyncFunction(JSContext* cx, 827 Handle<GlobalObject*> global) { 828 if (!ensureConstructor(cx, global, JSProto_AsyncFunction)) { 829 return nullptr; 830 } 831 return &global->getConstructor(JSProto_AsyncFunction); 832 } 833 834 static JSObject* createAsyncIteratorPrototype(JSContext* cx, 835 Handle<GlobalObject*> global); 836 837 static JSObject* getOrCreateAsyncIteratorPrototype( 838 JSContext* cx, Handle<GlobalObject*> global) { 839 if (JSObject* proto = 840 global->maybeBuiltinProto(ProtoKind::AsyncIteratorProto)) { 841 return proto; 842 } 843 return createAsyncIteratorPrototype(cx, global); 844 } 845 846 static JSObject* getOrCreateAsyncFromSyncIteratorPrototype( 847 JSContext* cx, Handle<GlobalObject*> global) { 848 return getOrCreateBuiltinProto(cx, global, 849 ProtoKind::AsyncFromSyncIteratorProto, 850 initAsyncFromSyncIteratorProto); 851 } 852 853 static JSObject* getOrCreateAsyncGenerator(JSContext* cx, 854 Handle<GlobalObject*> global) { 855 if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) { 856 return nullptr; 857 } 858 return &global->getPrototype(JSProto_AsyncGeneratorFunction); 859 } 860 861 static JSObject* getOrCreateAsyncGeneratorFunction( 862 JSContext* cx, Handle<GlobalObject*> global) { 863 if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) { 864 return nullptr; 865 } 866 return &global->getConstructor(JSProto_AsyncGeneratorFunction); 867 } 868 869 void setAsyncGeneratorPrototype(JSObject* obj) { 870 initBuiltinProto(ProtoKind::AsyncGeneratorProto, obj); 871 } 872 873 static JSObject* getOrCreateAsyncGeneratorPrototype( 874 JSContext* cx, Handle<GlobalObject*> global) { 875 if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) { 876 return nullptr; 877 } 878 return &global->getBuiltinProto(ProtoKind::AsyncGeneratorProto); 879 } 880 881 static JSObject* getOrCreateMapIteratorPrototype( 882 JSContext* cx, Handle<GlobalObject*> global) { 883 return getOrCreateBuiltinProto(cx, global, ProtoKind::MapIteratorProto, 884 initMapIteratorProto); 885 } 886 887 static JSObject* getOrCreateSetIteratorPrototype( 888 JSContext* cx, Handle<GlobalObject*> global) { 889 return getOrCreateBuiltinProto(cx, global, ProtoKind::SetIteratorProto, 890 initSetIteratorProto); 891 } 892 893 static JSObject* getOrCreateSegmentsPrototype(JSContext* cx, 894 Handle<GlobalObject*> global) { 895 return getOrCreateBuiltinProto(cx, global, ProtoKind::SegmentsProto, 896 initSegmentsProto); 897 } 898 899 static JSObject* getOrCreateSegmentIteratorPrototype( 900 JSContext* cx, Handle<GlobalObject*> global) { 901 return getOrCreateBuiltinProto(cx, global, ProtoKind::SegmentIteratorProto, 902 initSegmentIteratorProto); 903 } 904 905 static JSObject* getOrCreateDataViewPrototype(JSContext* cx, 906 Handle<GlobalObject*> global) { 907 if (!ensureConstructor(cx, global, JSProto_DataView)) { 908 return nullptr; 909 } 910 return &global->getPrototype(JSProto_DataView); 911 } 912 913 static JSObject* getOrCreatePromiseConstructor(JSContext* cx, 914 Handle<GlobalObject*> global) { 915 if (!ensureConstructor(cx, global, JSProto_Promise)) { 916 return nullptr; 917 } 918 return &global->getConstructor(JSProto_Promise); 919 } 920 921 static NativeObject* getOrCreateWrapForValidIteratorPrototype( 922 JSContext* cx, Handle<GlobalObject*> global); 923 924 static NativeObject* getOrCreateIteratorHelperPrototype( 925 JSContext* cx, Handle<GlobalObject*> global); 926 927 static NativeObject* getOrCreateAsyncIteratorHelperPrototype( 928 JSContext* cx, Handle<GlobalObject*> global); 929 static bool initAsyncIteratorHelperProto(JSContext* cx, 930 Handle<GlobalObject*> global); 931 932 NativeObject& getIntrinsicsHolder() const { 933 MOZ_ASSERT(data().intrinsicsHolder); 934 return *data().intrinsicsHolder; 935 } 936 937 static bool createIntrinsicsHolder(JSContext* cx, 938 Handle<GlobalObject*> global); 939 940 NativeObject* getComputedIntrinsicsHolder() { 941 return data().computedIntrinsicsHolder; 942 } 943 void setComputedIntrinsicsHolder(NativeObject* holder) { 944 data().computedIntrinsicsHolder = holder; 945 } 946 947 // If a self-hosting intrinsic with the given |name| exists, it's stored in 948 // |*vp| and this function returns true. Else it returns false. 949 bool maybeGetIntrinsicValue(PropertyName* name, Value* vp, JSContext* cx) { 950 NativeObject& holder = getIntrinsicsHolder(); 951 952 if (mozilla::Maybe<PropertyInfo> prop = holder.lookup(cx, name)) { 953 *vp = holder.getSlot(prop->slot()); 954 return true; 955 } 956 957 return false; 958 } 959 960 static bool getIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global, 961 Handle<PropertyName*> name, 962 MutableHandleValue value) { 963 // `undefined` in self-hosted JS code should be emitted as JSOp::Undefined. 964 MOZ_ASSERT(name != cx->names().undefined); 965 966 if (global->maybeGetIntrinsicValue(name, value.address(), cx)) { 967 return true; 968 } 969 return getIntrinsicValueSlow(cx, global, name, value); 970 } 971 972 static bool getIntrinsicValueSlow(JSContext* cx, Handle<GlobalObject*> global, 973 Handle<PropertyName*> name, 974 MutableHandleValue value); 975 976 static bool addIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global, 977 Handle<PropertyName*> name, HandleValue value); 978 979 static inline bool setIntrinsicValue(JSContext* cx, 980 Handle<GlobalObject*> global, 981 Handle<PropertyName*> name, 982 HandleValue value); 983 984 static bool getSelfHostedFunction(JSContext* cx, Handle<GlobalObject*> global, 985 Handle<PropertyName*> selfHostedName, 986 Handle<JSAtom*> name, unsigned nargs, 987 MutableHandleValue funVal); 988 989 static RegExpStatics* getRegExpStatics(JSContext* cx, 990 Handle<GlobalObject*> global); 991 992 static JSObject* getOrCreateThrowTypeError(JSContext* cx, 993 Handle<GlobalObject*> global); 994 995 RegExpRealm& regExpRealm() { return data().regExpRealm; } 996 997 #ifdef JS_HAS_INTL_API 998 intl::GlobalIntlData& globalIntlData() { return data().globalIntlData; } 999 #endif 1000 1001 // Infallibly test whether the given value is the eval function for this 1002 // global. 1003 bool valueIsEval(const Value& val); 1004 1005 static ArgumentsObject* getOrCreateArgumentsTemplateObject(JSContext* cx, 1006 bool mapped); 1007 ArgumentsObject* maybeArgumentsTemplateObject(bool mapped) const; 1008 1009 static MapObject* getOrCreateMapTemplateObject(JSContext* cx); 1010 static SetObject* getOrCreateSetTemplateObject(JSContext* cx); 1011 1012 static const size_t IterResultObjectValueSlot = 0; 1013 static const size_t IterResultObjectDoneSlot = 1; 1014 static js::PlainObject* getOrCreateIterResultTemplateObject(JSContext* cx); 1015 static js::PlainObject* getOrCreateIterResultWithoutPrototypeTemplateObject( 1016 JSContext* cx); 1017 1018 private: 1019 enum class WithObjectPrototype { No, Yes }; 1020 static js::PlainObject* createIterResultTemplateObject( 1021 JSContext* cx, WithObjectPrototype withProto); 1022 1023 public: 1024 static ScriptSourceObject* getOrCreateSelfHostingScriptSourceObject( 1025 JSContext* cx, Handle<GlobalObject*> global); 1026 1027 // Implemented in vm/Iteration.cpp. 1028 template <ProtoKind Kind, const JSClass* ProtoClass, 1029 const JSFunctionSpec* Methods, const bool needsFuseProperty = false> 1030 static bool initObjectIteratorProto(JSContext* cx, 1031 Handle<GlobalObject*> global, 1032 Handle<JSAtom*> tag); 1033 1034 // Implemented in vm/AsyncIteration.cpp. 1035 static bool initAsyncIteratorProto(JSContext* cx, 1036 Handle<GlobalObject*> global); 1037 static bool initAsyncFromSyncIteratorProto(JSContext* cx, 1038 Handle<GlobalObject*> global); 1039 1040 // Implemented in builtin/MapObject.cpp. 1041 static bool initMapIteratorProto(JSContext* cx, Handle<GlobalObject*> global); 1042 static bool initSetIteratorProto(JSContext* cx, Handle<GlobalObject*> global); 1043 1044 // Implemented in builtin/intl/Segmenter.cpp. 1045 static bool initSegmentsProto(JSContext* cx, Handle<GlobalObject*> global); 1046 static bool initSegmentIteratorProto(JSContext* cx, 1047 Handle<GlobalObject*> global); 1048 1049 static bool initStandardClasses(JSContext* cx, Handle<GlobalObject*> global); 1050 1051 // Disallow GC as it may mutate the vector. 1052 Realm::DebuggerVector& getDebuggers(const JS::AutoRequireNoGC& nogc) const { 1053 return realm()->getDebuggers(nogc); 1054 } 1055 bool hasDebuggers() const { return realm()->hasDebuggers(); } 1056 1057 JSObject* maybeWindowProxy() const { return data().windowProxy; } 1058 1059 void setWindowProxy(JSObject* windowProxy) { 1060 // Note: the global must always be associated with the same WindowProxy. 1061 // CacheIR optimizations rely on this by baking in the WindowProxy for the 1062 // global. 1063 MOZ_ASSERT(!data().windowProxy); 1064 data().windowProxy.init(windowProxy); 1065 } 1066 1067 ArrayObject* getSourceURLsHolder() const { return data().sourceURLsHolder; } 1068 1069 void setSourceURLsHolder(ArrayObject* holder) { 1070 data().sourceURLsHolder = holder; 1071 } 1072 void clearSourceURLSHolder() { setSourceURLsHolder(nullptr); } 1073 1074 SharedShape* maybeArrayShapeWithDefaultProto() const { 1075 return data().arrayShapeWithDefaultProto; 1076 } 1077 1078 static SharedShape* getArrayShapeWithDefaultProto(JSContext* cx) { 1079 if (SharedShape* shape = cx->global()->data().arrayShapeWithDefaultProto; 1080 MOZ_LIKELY(shape)) { 1081 return shape; 1082 } 1083 return createArrayShapeWithDefaultProto(cx); 1084 } 1085 static SharedShape* createArrayShapeWithDefaultProto(JSContext* cx); 1086 1087 static SharedShape* getPlainObjectShapeWithDefaultProto(JSContext* cx, 1088 gc::AllocKind kind) { 1089 PlainObjectSlotsKind slotsKind = PlainObjectSlotsKindFromAllocKind(kind); 1090 SharedShape* shape = 1091 cx->global()->data().plainObjectShapesWithDefaultProto[slotsKind]; 1092 if (MOZ_LIKELY(shape)) { 1093 return shape; 1094 } 1095 return createPlainObjectShapeWithDefaultProto(cx, kind); 1096 } 1097 static SharedShape* createPlainObjectShapeWithDefaultProto( 1098 JSContext* cx, gc::AllocKind kind); 1099 1100 static SharedShape* getEmptyPlainObjectShape(JSContext* cx) { 1101 const PlainObjectSlotsKind kind = PlainObjectSlotsKind::Slots0; 1102 SharedShape* shape = 1103 cx->global()->data().plainObjectShapesWithDefaultProto[kind]; 1104 MOZ_ASSERT(shape); // This is created on initialization. 1105 return shape; 1106 } 1107 1108 static SharedShape* getFunctionShapeWithDefaultProto(JSContext* cx, 1109 bool extended) { 1110 GlobalObjectData& data = cx->global()->data(); 1111 SharedShape* shape = extended ? data.extendedFunctionShapeWithDefaultProto 1112 : data.functionShapeWithDefaultProto; 1113 if (MOZ_LIKELY(shape)) { 1114 return shape; 1115 } 1116 return createFunctionShapeWithDefaultProto(cx, extended); 1117 } 1118 static SharedShape* createFunctionShapeWithDefaultProto(JSContext* cx, 1119 bool extended); 1120 1121 SharedShape* maybeBoundFunctionShapeWithDefaultProto() const { 1122 return data().boundFunctionShapeWithDefaultProto; 1123 } 1124 void setBoundFunctionShapeWithDefaultProto(SharedShape* shape) { 1125 data().boundFunctionShapeWithDefaultProto = shape; 1126 } 1127 1128 SharedShape* maybeRegExpShapeWithDefaultProto() const { 1129 return data().regExpShapeWithDefaultProto; 1130 } 1131 void setRegExpShapeWithDefaultProto(SharedShape* shape) { 1132 data().regExpShapeWithDefaultProto = shape; 1133 } 1134 1135 static PropertyIteratorObject* getOrCreateEmptyIterator(JSContext* cx); 1136 1137 // Returns an object that represents the realm, used by embedder. 1138 static JSObject* getOrCreateRealmKeyObject(JSContext* cx, 1139 Handle<GlobalObject*> global); 1140 1141 static size_t offsetOfGlobalDataSlot() { 1142 return getFixedSlotOffset(GLOBAL_DATA_SLOT); 1143 } 1144 1145 uint32_t generationCount() const { return data().generationCount; } 1146 const void* addressOfGenerationCount() const { 1147 return &data().generationCount; 1148 } 1149 void bumpGenerationCount() { 1150 MOZ_RELEASE_ASSERT(data().generationCount < UINT32_MAX); 1151 data().generationCount++; 1152 } 1153 }; 1154 1155 /* 1156 * Unless otherwise specified, define ctor.prototype = proto as non-enumerable, 1157 * non-configurable, and non-writable; and define proto.constructor = ctor as 1158 * non-enumerable but configurable and writable. 1159 */ 1160 extern bool LinkConstructorAndPrototype( 1161 JSContext* cx, JSObject* ctor, JSObject* proto, 1162 unsigned prototypeAttrs = JSPROP_PERMANENT | JSPROP_READONLY, 1163 unsigned constructorAttrs = 0); 1164 1165 /* 1166 * Define properties and/or functions on any object. Either ps or fs, or both, 1167 * may be null. 1168 */ 1169 extern bool DefinePropertiesAndFunctions(JSContext* cx, HandleObject obj, 1170 const JSPropertySpec* ps, 1171 const JSFunctionSpec* fs); 1172 1173 extern bool DefineToStringTag(JSContext* cx, HandleObject obj, JSAtom* tag); 1174 1175 /* 1176 * Convenience templates to generic constructor and prototype creation functions 1177 * for ClassSpecs. 1178 */ 1179 1180 template <JSNative ctor, unsigned length, gc::AllocKind kind, 1181 const JSJitInfo* jitInfo = nullptr> 1182 JSObject* GenericCreateConstructor(JSContext* cx, JSProtoKey key) { 1183 // Note - We duplicate the trick from ClassName() so that we don't need to 1184 // include vm/JSAtomUtils-inl.h here. 1185 PropertyName* name = (&cx->names().Null)[key]; 1186 return GlobalObject::createConstructor(cx, ctor, name, length, kind, jitInfo); 1187 } 1188 1189 template <typename T> 1190 JSObject* GenericCreatePrototype(JSContext* cx, JSProtoKey key) { 1191 static_assert( 1192 !std::is_same_v<T, PlainObject>, 1193 "creating Object.prototype is very special and isn't handled here"); 1194 MOZ_ASSERT(&T::class_ == ProtoKeyToClass(key), 1195 "type mismatch--probably too much copy/paste in your ClassSpec"); 1196 MOZ_ASSERT( 1197 InheritanceProtoKeyForStandardClass(key) == JSProto_Object, 1198 "subclasses (of anything but Object) can't use GenericCreatePrototype"); 1199 return GlobalObject::createBlankPrototype(cx, cx->global(), &T::protoClass_); 1200 } 1201 1202 // Which object(s) should be marked as having a RealmFuse property in 1203 // GenericFinishInit. 1204 enum class WhichHasRealmFuseProperty { 1205 Proto, 1206 ProtoAndCtor, 1207 }; 1208 1209 template <WhichHasRealmFuseProperty FuseProperty> 1210 inline bool GenericFinishInit(JSContext* cx, HandleObject ctor, 1211 HandleObject proto) { 1212 if constexpr (FuseProperty == WhichHasRealmFuseProperty::ProtoAndCtor) { 1213 if (!JSObject::setHasRealmFuseProperty(cx, ctor)) { 1214 return false; 1215 } 1216 } 1217 return JSObject::setHasRealmFuseProperty(cx, proto); 1218 } 1219 1220 inline JSProtoKey StandardProtoKeyOrNull(const JSObject* obj) { 1221 return JSCLASS_CACHED_PROTO_KEY(obj->getClass()); 1222 } 1223 1224 JSObject* NewTenuredObjectWithFunctionPrototype(JSContext* cx, 1225 Handle<GlobalObject*> global); 1226 1227 } // namespace js 1228 1229 template <> 1230 inline bool JSObject::is<js::GlobalObject>() const { 1231 return !!(getClass()->flags & JSCLASS_IS_GLOBAL); 1232 } 1233 1234 #endif /* vm_GlobalObject_h */