Bug 1726737 - Part 14: Add public header for global object functions. r=arai
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 20 Aug 2021 18:10:37 +0000
changeset 589447 d70a75fd64629f67763ca73939cc3e168062be9d
parent 589446 0b8f97ff63c4c7ccbdfddfc2ad89f68ca7bf1fcd
child 589448 b1c14abc11533e9650d47b19406f4d0639acb9de
push id38723
push usernbeleuzu@mozilla.com
push dateSat, 21 Aug 2021 09:35:16 +0000
treeherdermozilla-central@3db432e28208 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1726737
milestone93.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1726737 - Part 14: Add public header for global object functions. r=arai Differential Revision: https://phabricator.services.mozilla.com/D123205
js/public/GlobalObject.h
js/src/builtin/TestingFunctions.cpp
js/src/ctypes/CTypes.cpp
js/src/fuzz-tests/tests.cpp
js/src/gdb/gdb-tests.cpp
js/src/gdb/tests/test-GCCellPtr.cpp
js/src/gdb/tests/test-JSObject.cpp
js/src/gdb/tests/test-Root.cpp
js/src/gdb/tests/test-jsval.cpp
js/src/gdb/tests/test-unwind.cpp
js/src/jsapi-tests/testArrayBufferView.cpp
js/src/jsapi-tests/testBug604087.cpp
js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
js/src/jsapi-tests/testChromeBuffer.cpp
js/src/jsapi-tests/testDebugger.cpp
js/src/jsapi-tests/testErrorLineOfContext.cpp
js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
js/src/jsapi-tests/testGCFinalizeCallback.cpp
js/src/jsapi-tests/testGCMarking.cpp
js/src/jsapi-tests/testLooselyEqual.cpp
js/src/jsapi-tests/testMutedErrors.cpp
js/src/jsapi-tests/testPreserveJitCode.cpp
js/src/jsapi-tests/testProfileStrings.cpp
js/src/jsapi-tests/testSourcePolicy.cpp
js/src/jsapi-tests/testStructuredClone.cpp
js/src/jsapi-tests/testUbiNode.cpp
js/src/jsapi-tests/testValueABI.cpp
js/src/jsapi-tests/testWeakMap.cpp
js/src/jsapi-tests/tests.cpp
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/moz.build
js/src/shell/js.cpp
js/src/shell/jsshell.cpp
js/src/vm/GlobalObject.h
js/src/vm/HelperThreads.cpp
new file mode 100644
--- /dev/null
+++ b/js/public/GlobalObject.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef js_GlobalObject_h
+#define js_GlobalObject_h
+
+#include "mozilla/Attributes.h"
+
+#include "jstypes.h"
+
+#include "js/TypeDecls.h"
+
+class JS_PUBLIC_API JSTracer;
+
+struct JSClassOps;
+
+extern JS_PUBLIC_API bool JS_IsGlobalObject(JSObject* obj);
+
+namespace JS {
+
+class JS_PUBLIC_API RealmOptions;
+
+/**
+ * Get the current realm's global. Returns nullptr if no realm has been
+ * entered.
+ */
+extern JS_PUBLIC_API JSObject* CurrentGlobalOrNull(JSContext* cx);
+
+/**
+ * Get the global object associated with an object's realm. The object must not
+ * be a cross-compartment wrapper (because CCWs are shared by all realms in the
+ * compartment).
+ */
+extern JS_PUBLIC_API JSObject* GetNonCCWObjectGlobal(JSObject* obj);
+
+/**
+ * During global creation, we fire notifications to callbacks registered
+ * via the Debugger API. These callbacks are arbitrary script, and can touch
+ * the global in arbitrary ways. When that happens, the global should not be
+ * in a half-baked state. But this creates a problem for consumers that need
+ * to set slots on the global to put it in a consistent state.
+ *
+ * This API provides a way for consumers to set slots atomically (immediately
+ * after the global is created), before any debugger hooks are fired. It's
+ * unfortunately on the clunky side, but that's the way the cookie crumbles.
+ *
+ * If callers have no additional state on the global to set up, they may pass
+ * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
+ * fire the hook as its final act before returning. Otherwise, callers should
+ * pass |DontFireOnNewGlobalHook|, which means that they are responsible for
+ * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
+ * an error occurs and the operation aborts, callers should skip firing the
+ * hook. But otherwise, callers must take care to fire the hook exactly once
+ * before compiling any script in the global's scope (we have assertions in
+ * place to enforce this). This lets us be sure that debugger clients never miss
+ * breakpoints.
+ */
+enum OnNewGlobalHookOption { FireOnNewGlobalHook, DontFireOnNewGlobalHook };
+
+}  // namespace JS
+
+extern JS_PUBLIC_API JSObject* JS_NewGlobalObject(
+    JSContext* cx, const JSClass* clasp, JSPrincipals* principals,
+    JS::OnNewGlobalHookOption hookOption, const JS::RealmOptions& options);
+/**
+ * Spidermonkey does not have a good way of keeping track of what compartments
+ * should be marked on their own. We can mark the roots unconditionally, but
+ * marking GC things only relevant in live compartments is hard. To mitigate
+ * this, we create a static trace hook, installed on each global object, from
+ * which we can be sure the compartment is relevant, and mark it.
+ *
+ * It is still possible to specify custom trace hooks for global object classes.
+ * They can be provided via the RealmOptions passed to JS_NewGlobalObject.
+ */
+extern JS_PUBLIC_API void JS_GlobalObjectTraceHook(JSTracer* trc,
+                                                   JSObject* global);
+
+namespace JS {
+
+/**
+ * This allows easily constructing a global object without having to deal with
+ * JSClassOps, forgetting to add JS_GlobalObjectTraceHook, or forgetting to call
+ * JS::InitRealmStandardClasses(). Example:
+ *
+ *     const JSClass globalClass = { "MyGlobal", JSCLASS_GLOBAL_FLAGS,
+ *         &JS::DefaultGlobalClassOps };
+ *     JS_NewGlobalObject(cx, &globalClass, ...);
+ */
+extern JS_PUBLIC_DATA const JSClassOps DefaultGlobalClassOps;
+
+}  // namespace JS
+
+extern JS_PUBLIC_API void JS_FireOnNewGlobalObject(JSContext* cx,
+                                                   JS::HandleObject global);
+
+#endif  // js_GlobalObject_h
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -70,16 +70,17 @@
 #include "js/Debug.h"
 #include "js/experimental/CodeCoverage.h"      // js::GetCodeCoverageSummary
 #include "js/experimental/JSStencil.h"         // JS::Stencil
 #include "js/experimental/PCCountProfiling.h"  // JS::{Start,Stop}PCCountProfiling, JS::PurgePCCounts, JS::GetPCCountScript{Count,Summary,Contents}
 #include "js/experimental/TypedData.h"         // JS_GetObjectAsUint8Array
 #include "js/friend/DumpFunctions.h"  // js::Dump{Backtrace,Heap,Object}, JS::FormatStackDump, js::IgnoreNurseryObjects
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/friend/WindowProxy.h"    // js::ToWindowProxyIfWindow
+#include "js/GlobalObject.h"
 #include "js/HashTable.h"
 #include "js/Interrupt.h"
 #include "js/LocaleSensitive.h"
 #include "js/OffThreadScriptCompilation.h"  // js::UseOffThreadParseGlobal
 #include "js/Printf.h"
 #include "js/PropertyAndElement.h"  // JS_DefineProperties, JS_DefineProperty, JS_DefinePropertyById, JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_HasProperty, JS_SetElement, JS_SetProperty
 #include "js/PropertySpec.h"
 #include "js/RegExpFlags.h"  // JS::RegExpFlag, JS::RegExpFlags
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -40,16 +40,17 @@
 #include "gc/Policy.h"
 #include "jit/AtomicOperations.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
 #include "js/ArrayBuffer.h"  // JS::{IsArrayBufferObject,GetArrayBufferData,GetArrayBuffer{ByteLength,Data}}
 #include "js/CallAndConstruct.h"  // JS::IsCallable, JS_CallFunctionValue
 #include "js/CharacterEncoding.h"
 #include "js/experimental/TypedData.h"  // JS_GetArrayBufferView{Type,Data}, JS_GetTypedArrayByteLength, JS_IsArrayBufferViewObject, JS_IsTypedArrayObject
 #include "js/friend/ErrorMessages.h"    // js::GetErrorMessage, JSMSG_*
+#include "js/GlobalObject.h"            // JS::CurrentGlobalOrNull
 #include "js/Object.h"  // JS::GetMaybePtrFromReservedSlot, JS::GetReservedSlot, JS::SetReservedSlot
 #include "js/PropertyAndElement.h"  // JS_DefineFunction, JS_DefineFunctions, JS_DefineProperties, JS_DefineProperty, JS_DefinePropertyById, JS_DefineUCProperty, JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById
 #include "js/PropertySpec.h"
 #include "js/SharedArrayBuffer.h"  // JS::{GetSharedArrayBuffer{ByteLength,Data},IsSharedArrayBufferObject}
 #include "js/StableStringChars.h"
 #include "js/UniquePtr.h"
 #include "js/Utility.h"
 #include "js/Vector.h"
--- a/js/src/fuzz-tests/tests.cpp
+++ b/js/src/fuzz-tests/tests.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "fuzz-tests/tests.h"
 
 #include <stdio.h>
 
 #include "js/AllocPolicy.h"
+#include "js/GlobalObject.h"
 #include "js/Initialization.h"
 #include "js/RootingAPI.h"
 #include "js/Stack.h"
 #include "vm/JSContext.h"
 
 #ifdef LIBFUZZER
 #  include "FuzzerDefs.h"
 #endif
--- a/js/src/gdb/gdb-tests.cpp
+++ b/js/src/gdb/gdb-tests.cpp
@@ -5,16 +5,17 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "gdb-tests.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Context.h"
+#include "js/GlobalObject.h"
 #include "js/Initialization.h"
 #include "js/RealmOptions.h"
 #include "js/Warnings.h"  // JS::SetWarningReporter
 
 using namespace JS;
 
 /* The class of the global object. */
 static const JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS,
--- a/js/src/gdb/tests/test-GCCellPtr.cpp
+++ b/js/src/gdb/tests/test-GCCellPtr.cpp
@@ -1,14 +1,15 @@
 #include "gdb-tests.h"
 
 #include "jsapi.h"
 
 #include "js/CompileOptions.h"
 #include "js/CompilationAndEvaluation.h"
+#include "js/GlobalObject.h"
 #include "js/HeapAPI.h"
 #include "js/RegExpFlags.h"
 #include "js/SourceText.h"
 #include "js/Symbol.h"
 #include "js/TypeDecls.h"
 #include "vm/BigIntType.h"
 #include "vm/JSObject.h"
 #include "vm/RegExpObject.h"
--- a/js/src/gdb/tests/test-JSObject.cpp
+++ b/js/src/gdb/tests/test-JSObject.cpp
@@ -1,10 +1,11 @@
 #include "gdb-tests.h"
 #include "jsapi.h"
+#include "js/GlobalObject.h"
 #include "js/Object.h"  // JS::GetClass
 
 FRAGMENT(JSObject, simple) {
   AutoSuppressHazardsForTest noanalysis;
 
   JS::Rooted<JSObject*> glob(cx, JS::CurrentGlobalOrNull(cx));
   JS::Rooted<JSObject*> plain(cx, JS_NewPlainObject(cx));
   JS::Rooted<JSObject*> objectProto(cx, JS::GetRealmObjectPrototype(cx));
--- a/js/src/gdb/tests/test-Root.cpp
+++ b/js/src/gdb/tests/test-Root.cpp
@@ -1,14 +1,15 @@
 #include "gdb-tests.h"
 
 #include "jsapi.h"
 
 #include "gc/Barrier.h"
 #include "js/Array.h"  // JS::NewArrayObject
+#include "js/GlobalObject.h"
 #include "js/ValueArray.h"
 #include "vm/JSFunction.h"
 
 FRAGMENT(Root, null) {
   JS::Rooted<JSObject*> null(cx, nullptr);
 
   breakpoint();
 
--- a/js/src/gdb/tests/test-jsval.cpp
+++ b/js/src/gdb/tests/test-jsval.cpp
@@ -1,11 +1,12 @@
 #include "gdb-tests.h"
 #include "jsapi.h"
 
+#include "js/GlobalObject.h"
 #include "js/Symbol.h"
 #include "vm/BigIntType.h"
 
 FRAGMENT(jsval, simple) {
   using namespace JS;
 
   RootedValue fortytwo(cx, Int32Value(42));
   RootedValue fortytwoD(cx, DoubleValue(42));
--- a/js/src/gdb/tests/test-unwind.cpp
+++ b/js/src/gdb/tests/test-unwind.cpp
@@ -1,16 +1,17 @@
 #include "gdb-tests.h"
 #include "jsapi.h"  // sundry symbols not moved to more-specific headers yet
 #include "jsfriendapi.h"  // JSFunctionSpecWithHelp
 
 #include "jit/JitOptions.h"               // js::jit::JitOptions
 #include "js/CallArgs.h"                  // JS::CallArgs, JS::CallArgsFromVp
 #include "js/CompilationAndEvaluation.h"  // JS::Evaluate
 #include "js/CompileOptions.h"            // JS::CompileOptions
+#include "js/GlobalObject.h"              // JS::CurrentGlobalOrNull
 #include "js/PropertyAndElement.h"        // JS_DefineProperty
 #include "js/RootingAPI.h"                // JS::Rooted
 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
 #include "js/Value.h"                     // JS::Value
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include <stdint.h>  // uint32_t
--- a/js/src/jsapi-tests/testArrayBufferView.cpp
+++ b/js/src/jsapi-tests/testArrayBufferView.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  */
 
 #include "js/ArrayBuffer.h"             // JS::NewArrayBuffer
 #include "js/experimental/TypedData.h"  // JS_GetArrayBufferView{Type,ByteLength,Data}, JS_GetObjectAsArrayBufferView, JS_GetObjectAs{{Ui,I}nt{8,16,32},Float{32,64}}Array, JS_IsArrayBufferViewObject, JS_NewDataView, JS_New{{Ui,I}nt{8,16,32},Float{32,64},Uint8Clamped}Array
+#include "js/GlobalObject.h"            // JS_NewGlobalObject
 #include "js/PropertyAndElement.h"      // JS_SetProperty
 #include "js/ScalarType.h"              // js::Scalar::Type
 #include "jsapi-tests/tests.h"
 #include "vm/ProxyObject.h"
 #include "vm/Realm.h"
 
 #include "vm/Realm-inl.h"
 
--- a/js/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -3,16 +3,17 @@
  *
  * Tests JS_TransplantObject
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "js/friend/WindowProxy.h"  // js::SetWindowProxyClass
+#include "js/GlobalObject.h"        // JS_NewGlobalObject
 #include "js/Wrapper.h"
 #include "js/WrapperCallbacks.h"
 #include "jsapi-tests/tests.h"
 #include "vm/JSObject.h"
 #include "vm/ProxyObject.h"
 
 const JSClass OuterWrapperClass = PROXY_CLASS_DEF(
     "Proxy", JSCLASS_HAS_RESERVED_SLOTS(1) /* additional class flags */);
--- a/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
+++ b/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "js/CallAndConstruct.h"
+#include "js/GlobalObject.h"
 #include "js/Object.h"  // JS::GetClass, JS::GetReservedSlot
 #include "jsapi-tests/tests.h"
 
 using namespace JS;
 
 static const JSClass CustomClass = {"CustomClass",
                                     JSCLASS_HAS_RESERVED_SLOTS(1)};
 
--- a/js/src/jsapi-tests/testChromeBuffer.cpp
+++ b/js/src/jsapi-tests/testChromeBuffer.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include "js/CallAndConstruct.h"          // JS_CallFunctionValue
 #include "js/CompilationAndEvaluation.h"  // JS::CompileFunction
 #include "js/ContextOptions.h"
+#include "js/GlobalObject.h"        // JS_NewGlobalObject
 #include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/SourceText.h"          // JS::Source{Ownership,Text}
 #include "jsapi-tests/tests.h"
 #include "util/Text.h"
 
 static TestJSPrincipals system_principals(1);
 
 static const JSClass global_class = {"global",
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "js/CallAndConstruct.h"
+#include "js/GlobalObject.h"        // JS_NewGlobalObject
 #include "js/PropertyAndElement.h"  // JS_SetProperty
 #include "jsapi-tests/tests.h"
 #include "vm/JSContext.h"
 
 using namespace js;
 
 BEGIN_TEST(testDebugger_newScriptHook) {
   // Test that top-level indirect eval fires the newScript hook.
--- a/js/src/jsapi-tests/testErrorLineOfContext.cpp
+++ b/js/src/jsapi-tests/testErrorLineOfContext.cpp
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "js/CompilationAndEvaluation.h"
 #include "js/Exception.h"
+#include "js/GlobalObject.h"
 #include "js/SourceText.h"
 #include "jsapi-tests/tests.h"
 #include "vm/ErrorReporting.h"
 
 BEGIN_TEST(testErrorLineOfContext) {
   static const char16_t fullLineR[] = u"\n  var x = @;  \r  ";
   CHECK(testLineOfContextHasNoLineTerminator(fullLineR, ' '));
 
--- a/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
+++ b/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
@@ -3,16 +3,17 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include "js/CompilationAndEvaluation.h"  // JS::Evaluate
+#include "js/GlobalObject.h"              // JS_NewGlobalObject
 #include "js/PropertyAndElement.h"        // JS_GetProperty
 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
 #include "jsapi-tests/tests.h"
 #include "util/Text.h"
 
 static bool GlobalResolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                           bool* resolvedp) {
   return JS_ResolveStandardClass(cx, obj, id, resolvedp);
--- a/js/src/jsapi-tests/testGCFinalizeCallback.cpp
+++ b/js/src/jsapi-tests/testGCFinalizeCallback.cpp
@@ -1,12 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "js/GlobalObject.h"
 #include "jsapi-tests/tests.h"
 
 static const unsigned BufSize = 20;
 static unsigned FinalizeCalls = 0;
 static JSFinalizeStatus StatusBuffer[BufSize];
 
 BEGIN_TEST(testGCFinalizeCallback) {
   AutoGCParameter param1(cx, JSGC_INCREMENTAL_GC_ENABLED, true);
--- a/js/src/jsapi-tests/testGCMarking.cpp
+++ b/js/src/jsapi-tests/testGCMarking.cpp
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi.h"
 
+#include "js/GlobalObject.h"  // JS_NewGlobalObject
 #include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty, JS_SetProperty
 #include "js/RootingAPI.h"
 #include "js/SliceBudget.h"
 #include "jsapi-tests/tests.h"
 #include "vm/Realm.h"
 
 using namespace js;
 
--- a/js/src/jsapi-tests/testLooselyEqual.cpp
+++ b/js/src/jsapi-tests/testLooselyEqual.cpp
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <limits>
 #include <math.h>
 
 #include "js/Equality.h"  // JS::LooselyEqual
+#include "js/GlobalObject.h"
 #include "jsapi-tests/tests.h"
 
 using namespace std;
 
 struct LooseEqualityFixture : public JSAPITest {
   virtual ~LooseEqualityFixture() {}
 
   bool leq(JS::HandleValue x, JS::HandleValue y) {
--- a/js/src/jsapi-tests/testMutedErrors.cpp
+++ b/js/src/jsapi-tests/testMutedErrors.cpp
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsfriendapi.h"
 #include "js/CompilationAndEvaluation.h"
 #include "js/Exception.h"
+#include "js/GlobalObject.h"
 #include "js/SourceText.h"
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testMutedErrors) {
   CHECK(testOuter("function f() {return 1}; f;"));
   CHECK(testOuter(
       "function outer() { return (function () {return 2}); }; outer();"));
   CHECK(testOuter("eval('(function() {return 3})');"));
--- a/js/src/jsapi-tests/testPreserveJitCode.cpp
+++ b/js/src/jsapi-tests/testPreserveJitCode.cpp
@@ -2,16 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include "jit/Ion.h"                      // js::jit::IsIonEnabled
 #include "js/CallAndConstruct.h"          // JS::CallFunction
 #include "js/CompilationAndEvaluation.h"  // JS::CompileFunction
+#include "js/GlobalObject.h"              // JS_NewGlobalObject
 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
 #include "jsapi-tests/tests.h"
 #include "util/Text.h"
 
 #include "vm/JSObject-inl.h"
 #include "vm/JSScript-inl.h"
 
 using namespace JS;
--- a/js/src/jsapi-tests/testProfileStrings.cpp
+++ b/js/src/jsapi-tests/testProfileStrings.cpp
@@ -6,16 +6,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Atomics.h"
 
 #include "js/CallAndConstruct.h"
 #include "js/ContextOptions.h"
+#include "js/GlobalObject.h"
 #include "js/PropertySpec.h"
 #include "jsapi-tests/tests.h"
 #include "vm/JSContext.h"
 
 static ProfilingStack profilingStack;
 static uint32_t peakStackPointer = 0;
 
 static void reset(JSContext* cx) {
--- a/js/src/jsapi-tests/testSourcePolicy.cpp
+++ b/js/src/jsapi-tests/testSourcePolicy.cpp
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include "js/CompilationAndEvaluation.h"  // JS::CompileFunction, JS::Evaluate
+#include "js/GlobalObject.h"              // JS_NewGlobalObject
 #include "js/MemoryFunctions.h"
 #include "js/SourceText.h"  // JS::Source{Ownership,Text}
 #include "jsapi-tests/tests.h"
 #include "vm/JSScript.h"
 
 BEGIN_TEST(testBug795104) {
   JS::RealmOptions options;
   options.behaviors().setDiscardSource(true);
--- a/js/src/jsapi-tests/testStructuredClone.cpp
+++ b/js/src/jsapi-tests/testStructuredClone.cpp
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "builtin/TestingFunctions.h"
 #include "js/ArrayBuffer.h"  // JS::{IsArrayBufferObject,GetArrayBufferLengthAndData,NewExternalArrayBuffer}
+#include "js/GlobalObject.h"        // JS_NewGlobalObject
 #include "js/PropertyAndElement.h"  // JS_GetProperty, JS_SetProperty
 #include "js/StructuredClone.h"
 
 #include "jsapi-tests/tests.h"
 
 using namespace js;
 
 BEGIN_TEST(testStructuredClone_object) {
--- a/js/src/jsapi-tests/testUbiNode.cpp
+++ b/js/src/jsapi-tests/testUbiNode.cpp
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include "builtin/TestingFunctions.h"
 #include "js/CompilationAndEvaluation.h"  // JS::Compile
+#include "js/GlobalObject.h"              // JS_NewGlobalObject
 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
 #include "js/UbiNode.h"
 #include "js/UbiNodeDominatorTree.h"
 #include "js/UbiNodePostOrder.h"
 #include "js/UbiNodeShortestPaths.h"
 #include "jsapi-tests/tests.h"
 #include "util/Text.h"
 #include "vm/Realm.h"
--- a/js/src/jsapi-tests/testValueABI.cpp
+++ b/js/src/jsapi-tests/testValueABI.cpp
@@ -1,12 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "js/GlobalObject.h"
 #include "jsapi-tests/tests.h"
 
 /*
  * Bug 689101 - jsval is technically a non-POD type because it has a private
  * data member. On gcc, this doesn't seem to matter. On MSVC, this prevents
  * returning a jsval from a function between C and C++ because it will use a
  * retparam in C++ and a direct return value in C.
  *
--- a/js/src/jsapi-tests/testWeakMap.cpp
+++ b/js/src/jsapi-tests/testWeakMap.cpp
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gc/Zone.h"
 #include "js/Array.h"               // JS::GetArrayLength
+#include "js/GlobalObject.h"        // JS_NewGlobalObject
 #include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/WeakMap.h"
 #include "jsapi-tests/tests.h"
 #include "vm/Realm.h"
 
 using namespace js;
 
 JSObject* keyDelegate = nullptr;
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -7,16 +7,17 @@
 #include "jsapi-tests/tests.h"
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include <stdio.h>
 
 #include "js/ArrayBuffer.h"
 #include "js/CompilationAndEvaluation.h"  // JS::Evaluate
+#include "js/GlobalObject.h"              // JS_NewGlobalObject
 #include "js/Initialization.h"
 #include "js/PropertyAndElement.h"  // JS_DefineFunction
 #include "js/RootingAPI.h"
 #include "js/SourceText.h"  // JS::Source{Ownership,Text}
 
 JSAPITest* JSAPITest::list;
 
 bool JSAPITest::init(JSContext* maybeReusableContext) {
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -16,18 +16,19 @@
 #include <string.h>
 #include <type_traits>
 
 #include "jsapi.h"
 
 #include "gc/GC.h"
 #include "js/AllocPolicy.h"
 #include "js/CharacterEncoding.h"
-#include "js/Equality.h"     // JS::SameValue
-#include "js/RegExpFlags.h"  // JS::RegExpFlags
+#include "js/Equality.h"      // JS::SameValue
+#include "js/GlobalObject.h"  // JS::DefaultGlobalClassOps
+#include "js/RegExpFlags.h"   // JS::RegExpFlags
 #include "js/Vector.h"
 #include "js/Warnings.h"  // JS::SetWarningReporter
 #include "vm/JSContext.h"
 
 /* Note: Aborts on OOM. */
 class JSAPITestString {
   js::Vector<char, 0, js::SystemAllocPolicy> chars;
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -43,16 +43,17 @@
 #include "js/CallAndConstruct.h"  // JS::IsCallable
 #include "js/CharacterEncoding.h"
 #include "js/CompileOptions.h"
 #include "js/ContextOptions.h"  // JS::ContextOptions{,Ref}
 #include "js/Conversions.h"
 #include "js/ErrorInterceptor.h"
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/friend/StackLimits.h"    // js::AutoCheckRecursionLimit
+#include "js/GlobalObject.h"
 #include "js/Initialization.h"
 #include "js/Interrupt.h"
 #include "js/JSON.h"
 #include "js/LocaleSensitive.h"
 #include "js/MemoryCallbacks.h"
 #include "js/MemoryFunctions.h"
 #include "js/OffThreadScriptCompilation.h"  // js::UseOffThreadParseGlobal
 #include "js/PropertySpec.h"
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -33,16 +33,17 @@
 #include "js/Class.h"
 #include "js/CompileOptions.h"
 #include "js/Context.h"
 #include "js/ErrorInterceptor.h"
 #include "js/ErrorReport.h"
 #include "js/Exception.h"
 #include "js/GCAPI.h"
 #include "js/GCVector.h"
+#include "js/GlobalObject.h"
 #include "js/HashTable.h"
 #include "js/Id.h"
 #include "js/Interrupt.h"
 #include "js/MapAndSet.h"
 #include "js/MemoryCallbacks.h"
 #include "js/MemoryFunctions.h"
 #include "js/OffThreadScriptCompilation.h"
 #include "js/Principals.h"
@@ -240,41 +241,22 @@ extern JS_PUBLIC_API JSProtoKey Identify
 
 extern JS_PUBLIC_API void ProtoKeyToId(JSContext* cx, JSProtoKey key,
                                        JS::MutableHandleId idp);
 
 } /* namespace JS */
 
 extern JS_PUBLIC_API JSProtoKey JS_IdToProtoKey(JSContext* cx, JS::HandleId id);
 
-extern JS_PUBLIC_API bool JS_IsGlobalObject(JSObject* obj);
-
 extern JS_PUBLIC_API JSObject* JS_GlobalLexicalEnvironment(JSObject* obj);
 
 extern JS_PUBLIC_API bool JS_HasExtensibleLexicalEnvironment(JSObject* obj);
 
 extern JS_PUBLIC_API JSObject* JS_ExtensibleLexicalEnvironment(JSObject* obj);
 
-namespace JS {
-
-/**
- * Get the current realm's global. Returns nullptr if no realm has been
- * entered.
- */
-extern JS_PUBLIC_API JSObject* CurrentGlobalOrNull(JSContext* cx);
-
-/**
- * Get the global object associated with an object's realm. The object must not
- * be a cross-compartment wrapper (because CCWs are shared by all realms in the
- * compartment).
- */
-extern JS_PUBLIC_API JSObject* GetNonCCWObjectGlobal(JSObject* obj);
-
-}  // namespace JS
-
 /**
  * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
  * given global.
  */
 extern JS_PUBLIC_API bool JS_InitReflectParse(JSContext* cx,
                                               JS::HandleObject global);
 
 /**
@@ -379,78 +361,16 @@ extern JS_PUBLIC_API bool OrdinaryHasIns
 extern JS_PUBLIC_API bool InstanceofOperator(JSContext* cx, HandleObject obj,
                                              HandleValue v, bool* bp);
 
 }  // namespace JS
 
 extern JS_PUBLIC_API JSObject* JS_GetConstructor(JSContext* cx,
                                                  JS::Handle<JSObject*> proto);
 
-namespace JS {
-
-/**
- * During global creation, we fire notifications to callbacks registered
- * via the Debugger API. These callbacks are arbitrary script, and can touch
- * the global in arbitrary ways. When that happens, the global should not be
- * in a half-baked state. But this creates a problem for consumers that need
- * to set slots on the global to put it in a consistent state.
- *
- * This API provides a way for consumers to set slots atomically (immediately
- * after the global is created), before any debugger hooks are fired. It's
- * unfortunately on the clunky side, but that's the way the cookie crumbles.
- *
- * If callers have no additional state on the global to set up, they may pass
- * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
- * fire the hook as its final act before returning. Otherwise, callers should
- * pass |DontFireOnNewGlobalHook|, which means that they are responsible for
- * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
- * an error occurs and the operation aborts, callers should skip firing the
- * hook. But otherwise, callers must take care to fire the hook exactly once
- * before compiling any script in the global's scope (we have assertions in
- * place to enforce this). This lets us be sure that debugger clients never miss
- * breakpoints.
- */
-enum OnNewGlobalHookOption { FireOnNewGlobalHook, DontFireOnNewGlobalHook };
-
-} /* namespace JS */
-
-extern JS_PUBLIC_API JSObject* JS_NewGlobalObject(
-    JSContext* cx, const JSClass* clasp, JSPrincipals* principals,
-    JS::OnNewGlobalHookOption hookOption, const JS::RealmOptions& options);
-/**
- * Spidermonkey does not have a good way of keeping track of what compartments
- * should be marked on their own. We can mark the roots unconditionally, but
- * marking GC things only relevant in live compartments is hard. To mitigate
- * this, we create a static trace hook, installed on each global object, from
- * which we can be sure the compartment is relevant, and mark it.
- *
- * It is still possible to specify custom trace hooks for global object classes.
- * They can be provided via the RealmOptions passed to JS_NewGlobalObject.
- */
-extern JS_PUBLIC_API void JS_GlobalObjectTraceHook(JSTracer* trc,
-                                                   JSObject* global);
-
-namespace JS {
-
-/**
- * This allows easily constructing a global object without having to deal with
- * JSClassOps, forgetting to add JS_GlobalObjectTraceHook, or forgetting to call
- * JS::InitRealmStandardClasses(). Example:
- *
- *     const JSClass globalClass = { "MyGlobal", JSCLASS_GLOBAL_FLAGS,
- *         &JS::DefaultGlobalClassOps };
- *     JS_NewGlobalObject(cx, &globalClass, ...);
- */
-extern JS_PUBLIC_DATA const JSClassOps DefaultGlobalClassOps;
-
-}  // namespace JS
-
-extern JS_PUBLIC_API void JS_FireOnNewGlobalObject(JSContext* cx,
-                                                   JS::HandleObject global);
-
 extern JS_PUBLIC_API JSObject* JS_NewObject(JSContext* cx,
                                             const JSClass* clasp);
 
 extern JS_PUBLIC_API bool JS_IsNative(JSObject* obj);
 
 /**
  * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
  * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -153,16 +153,17 @@ EXPORTS.js += [
     "../public/ForOfIterator.h",
     "../public/GCAnnotations.h",
     "../public/GCAPI.h",
     "../public/GCHashTable.h",
     "../public/GCPolicyAPI.h",
     "../public/GCTypeMacros.h",
     "../public/GCVariant.h",
     "../public/GCVector.h",
+    "../public/GlobalObject.h",
     "../public/HashTable.h",
     "../public/HeapAPI.h",
     "../public/HelperThreadAPI.h",
     "../public/Id.h",
     "../public/Initialization.h",
     "../public/Interrupt.h",
     "../public/JSON.h",
     "../public/LocaleSensitive.h",
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -124,16 +124,17 @@
 #include "js/experimental/SourceHook.h"  // js::{Set,Forget,}SourceHook
 #include "js/experimental/TypedData.h"   // JS_NewUint8Array
 #include "js/friend/DumpFunctions.h"     // JS::FormatStackDump
 #include "js/friend/ErrorMessages.h"     // js::GetErrorMessage, JSMSG_*
 #include "js/friend/StackLimits.h"       // js::AutoCheckRecursionLimit
 #include "js/friend/WindowProxy.h"  // js::IsWindowProxy, js::SetWindowProxyClass, js::ToWindowProxyIfWindow, js::ToWindowIfWindowProxy
 #include "js/GCAPI.h"               // JS::AutoCheckCannotGC
 #include "js/GCVector.h"
+#include "js/GlobalObject.h"
 #include "js/Initialization.h"
 #include "js/Interrupt.h"
 #include "js/JSON.h"
 #include "js/MemoryCallbacks.h"
 #include "js/MemoryFunctions.h"
 #include "js/Modules.h"  // JS::GetModulePrivate, JS::SetModule{DynamicImport,Metadata,Resolve}Hook, JS::SetModulePrivate
 #include "js/Object.h"  // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot, JS::SetReservedSlot
 #include "js/OffThreadScriptCompilation.h"  // JS::SetUseOffThreadParseGlobal, js::UseOffThreadParseGlobal
--- a/js/src/shell/jsshell.cpp
+++ b/js/src/shell/jsshell.cpp
@@ -8,16 +8,17 @@
 
 #include "shell/jsshell.h"
 
 #include "mozilla/Sprintf.h"
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
+#include "js/GlobalObject.h"
 #include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty, JS_GetPropertyById
 #include "util/StringBuffer.h"
 
 using namespace JS;
 
 namespace js {
 namespace shell {
 
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -2,16 +2,18 @@
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_GlobalObject_h
 #define vm_GlobalObject_h
 
+#include "js/GlobalObject.h"
+
 #include "mozilla/Assertions.h"
 #include "mozilla/EnumeratedArray.h"
 
 #include <stdint.h>
 #include <type_traits>
 
 #include "jsapi.h"
 #include "jsexn.h"
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -17,16 +17,17 @@
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/CompilationStencil.h"  // frontend::{CompilationStencil, ExtensibleCompilationStencil, CompilationInput, CompilationGCOutput, BorrowingCompilationStencil}
 #include "frontend/ParserAtom.h"          // frontend::ParserAtomsTable
 #include "gc/GC.h"                        // gc::MergeRealms
 #include "jit/IonCompileTask.h"
 #include "jit/JitRuntime.h"
 #include "js/ContextOptions.h"      // JS::ContextOptions
 #include "js/friend/StackLimits.h"  // js::ReportOverRecursed
+#include "js/GlobalObject.h"
 #include "js/HelperThreadAPI.h"
 #include "js/OffThreadScriptCompilation.h"  // JS::OffThreadToken, JS::OffThreadCompileCallback
 #include "js/SourceText.h"
 #include "js/Stack.h"
 #include "js/UniquePtr.h"
 #include "js/Utility.h"
 #include "threading/CpuCount.h"
 #include "util/NativeStack.h"