Bug 1708448 - Move property and element functions into js/public/PropertyAndElement.h. r=nbp
authorTooru Fujisawa <arai_a@mac.com>
Tue, 13 Jul 2021 11:52:42 +0000
changeset 585399 3a72f69192c6d75dea48034e554c3a9bf4f58055
parent 585398 a98f9be641e16a4b3c168d0e761bb14d91179dca
child 585400 e5c0a4fc953289b2132e148d36190f07384e0ba4
push id38611
push userdluca@mozilla.com
push dateTue, 13 Jul 2021 21:42:32 +0000
treeherdermozilla-central@e3fb9f4b3db8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1708448
milestone92.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 1708448 - Move property and element functions into js/public/PropertyAndElement.h. r=nbp Differential Revision: https://phabricator.services.mozilla.com/D119619
accessible/xpcom/xpcAccessibleMacInterface.mm
devtools/shared/heapsnapshot/HeapSnapshot.cpp
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeUtils.cpp
dom/base/ChromeUtils.cpp
dom/base/CustomElementRegistry.cpp
dom/base/MaybeCrossOriginObject.cpp
dom/base/nsContentPermissionHelper.cpp
dom/base/nsContentUtils.cpp
dom/base/nsFrameMessageManager.cpp
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/base/nsJSEnvironment.cpp
dom/base/test/gtest/TestContentUtils.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/CallbackInterface.cpp
dom/bindings/Codegen.py
dom/bindings/DOMJSProxyHandler.cpp
dom/bindings/ToJSValue.h
dom/cache/Cache.cpp
dom/cache/CacheStorage.cpp
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/CanvasUtils.h
dom/canvas/ClientWebGLContext.cpp
dom/console/Console.cpp
dom/console/ConsoleUtils.cpp
dom/filesystem/compat/FileSystemDirectoryReader.cpp
dom/html/HTMLMediaElement.cpp
dom/indexedDB/ActorsChild.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/Key.cpp
dom/indexedDB/KeyPath.cpp
dom/indexedDB/test/gtest/TestKey.cpp
dom/ipc/jsactor/JSActorManager.cpp
dom/media/webaudio/AudioWorkletGlobalScope.cpp
dom/media/webaudio/AudioWorkletNode.cpp
dom/performance/PerformanceMainThread.cpp
dom/reporting/ReportingHeader.cpp
dom/script/ScriptLoader.cpp
dom/script/ScriptSettings.cpp
dom/security/nsContentSecurityUtils.cpp
dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp
dom/serviceworkers/ServiceWorkerScriptCache.cpp
dom/system/OSFileConstants.cpp
dom/workers/ChromeWorkerScope.cpp
extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
intl/l10n/FluentBundle.cpp
intl/l10n/Localization.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/public/PropertyAndElement.h
js/src/builtin/MapObject.cpp
js/src/builtin/Profilers.cpp
js/src/builtin/ReflectParse.cpp
js/src/builtin/String.cpp
js/src/builtin/TestingFunctions.cpp
js/src/builtin/TestingUtility.cpp
js/src/builtin/intl/DateTimeFormat.cpp
js/src/builtin/intl/DisplayNames.cpp
js/src/ctypes/CTypes.cpp
js/src/ctypes/Library.cpp
js/src/debugger/Debugger.cpp
js/src/debugger/Object.cpp
js/src/fuzz-tests/testWasm.cpp
js/src/gc/GC.cpp
js/src/gdb/tests/test-unwind.cpp
js/src/jsapi-tests/testAddPropertyPropcache.cpp
js/src/jsapi-tests/testArrayBuffer.cpp
js/src/jsapi-tests/testArrayBufferView.cpp
js/src/jsapi-tests/testCallArgs.cpp
js/src/jsapi-tests/testChromeBuffer.cpp
js/src/jsapi-tests/testDebugger.cpp
js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp
js/src/jsapi-tests/testDefineProperty.cpp
js/src/jsapi-tests/testException.cpp
js/src/jsapi-tests/testExecuteInJSMEnvironment.cpp
js/src/jsapi-tests/testForwardSetProperty.cpp
js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
js/src/jsapi-tests/testFunctionNonSyntactic.cpp
js/src/jsapi-tests/testFunctionProperties.cpp
js/src/jsapi-tests/testGCExactRooting.cpp
js/src/jsapi-tests/testGCGrayMarking.cpp
js/src/jsapi-tests/testGCHeapBarriers.cpp
js/src/jsapi-tests/testGCMarking.cpp
js/src/jsapi-tests/testJSEvaluateScript.cpp
js/src/jsapi-tests/testLookup.cpp
js/src/jsapi-tests/testNewObject.cpp
js/src/jsapi-tests/testParseJSON.cpp
js/src/jsapi-tests/testPropCache.cpp
js/src/jsapi-tests/testReadableStream.cpp
js/src/jsapi-tests/testResolveRecursion.cpp
js/src/jsapi-tests/testScriptObject.cpp
js/src/jsapi-tests/testSetProperty.cpp
js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.cpp
js/src/jsapi-tests/testSlowScript.cpp
js/src/jsapi-tests/testStencil.cpp
js/src/jsapi-tests/testStructuredClone.cpp
js/src/jsapi-tests/testTypedArrays.cpp
js/src/jsapi-tests/testWeakMap.cpp
js/src/jsapi-tests/testWindowNonConfigurable.cpp
js/src/jsapi-tests/tests.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsnum.cpp
js/src/moz.build
js/src/shell/ModuleLoader.cpp
js/src/shell/OSObject.cpp
js/src/shell/js.cpp
js/src/shell/jsrtfuzzing/jsrtfuzzing.cpp
js/src/shell/jsshell.cpp
js/src/vm/EnvironmentObject.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/JSContext.cpp
js/src/vm/PropertyAndElement.cpp
js/src/vm/SavedStacks.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/StringType.cpp
js/src/vm/StructuredClone.cpp
js/src/wasm/WasmJS.cpp
js/src/wasm/WasmModule.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/nsImportModule.cpp
js/xpconnect/src/ExportHelpers.cpp
js/xpconnect/src/JSServices.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCInlines.h
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCShellImpl.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/XPCWrapper.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
mobile/android/components/geckoview/GeckoViewHistory.cpp
netwerk/base/LoadInfo.cpp
netwerk/base/ProxyAutoConfig.cpp
storage/mozStorageAsyncStatementJSHelper.cpp
storage/mozStorageStatementJSHelper.cpp
storage/mozStorageStatementRow.cpp
toolkit/components/backgroundhangmonitor/HangDetails.cpp
toolkit/components/ctypes/ctypes.cpp
toolkit/components/extensions/ExtensionsParent.cpp
toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp
toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
toolkit/components/glean/bindings/Glean.cpp
toolkit/components/glean/bindings/GleanPings.cpp
toolkit/components/glean/bindings/private/CustomDistribution.cpp
toolkit/components/glean/bindings/private/Event.cpp
toolkit/components/glean/bindings/private/MemoryDistribution.cpp
toolkit/components/glean/bindings/private/TimingDistribution.cpp
toolkit/components/mozintl/MozIntlHelper.cpp
toolkit/components/places/History.cpp
toolkit/components/places/PlaceInfo.cpp
toolkit/components/sessionstore/SessionStoreUtils.cpp
toolkit/components/startup/nsAppStartup.cpp
toolkit/components/telemetry/core/Telemetry.cpp
toolkit/components/telemetry/core/TelemetryEvent.cpp
toolkit/components/telemetry/core/TelemetryHistogram.cpp
toolkit/components/telemetry/core/TelemetryOrigin.cpp
toolkit/components/telemetry/core/TelemetryScalar.cpp
toolkit/components/telemetry/other/CombinedStacks.cpp
toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp
toolkit/components/telemetry/other/UntrustedModulesDataSerializer.cpp
toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp
toolkit/components/telemetry/tests/gtest/TestEvents.cpp
toolkit/components/telemetry/tests/gtest/TestOrigins.cpp
toolkit/components/telemetry/tests/gtest/TestScalars.cpp
toolkit/mozapps/extensions/AddonManagerStartup-inlines.h
toolkit/mozapps/extensions/AddonManagerStartup.cpp
tools/fuzzing/messagemanager/MessageManagerFuzzer.cpp
tools/profiler/gecko/nsProfiler.cpp
widget/GfxInfoBase.cpp
widget/GfxInfoCollector.cpp
widget/android/EventDispatcher.cpp
widget/cocoa/GfxInfo.mm
widget/cocoa/nsMacSharingService.mm
widget/windows/GfxInfo.cpp
xpcom/base/CycleCollectedJSRuntime.cpp
xpcom/base/nsSystemInfo.cpp
xpcom/components/StaticComponents.cpp.in
xpcom/tests/gtest/TestGCPostBarriers.cpp
--- a/accessible/xpcom/xpcAccessibleMacInterface.mm
+++ b/accessible/xpcom/xpcAccessibleMacInterface.mm
@@ -11,16 +11,17 @@
 #include "nsCocoaUtils.h"
 #include "nsContentUtils.h"
 #include "nsIObserverService.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIXPConnect.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/Services.h"
 #include "nsString.h"
+#include "js/PropertyAndElement.h" // JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById, JS_HasOwnProperty, JS_SetUCProperty
 
 #import "mozAccessible.h"
 
 using namespace mozilla::a11y;
 
 // xpcAccessibleMacNSObjectWrapper
 
 NS_IMPL_ISUPPORTS(xpcAccessibleMacNSObjectWrapper, nsIAccessibleMacNSObjectWrapper)
--- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp
@@ -6,16 +6,17 @@
 #include "HeapSnapshot.h"
 
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/gzip_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 
 #include "js/Array.h"  // JS::NewArrayObject
 #include "js/Debug.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/TypeDecls.h"
 #include "js/UbiNodeBreadthFirst.h"
 #include "js/UbiNodeCensus.h"
 #include "js/UbiNodeDominatorTree.h"
 #include "js/UbiNodeShortestPaths.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/devtools/AutoMemMap.h"
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -34,16 +34,17 @@
 #include "nsCSSPseudoElements.h"    // For PseudoStyleType
 #include "nsCSSRendering.h"         // For IsCanvasFrame
 #include "nsDOMMutationObserver.h"  // For nsAutoAnimationMutationBatch
 #include "nsIFrame.h"
 #include "nsIFrameInlines.h"
 #include "nsIScrollableFrame.h"
 #include "nsPresContextInlines.h"
 #include "nsRefreshDriver.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 
 namespace mozilla {
 
 void AnimationProperty::SetPerformanceWarning(
     const AnimationPerformanceWarning& aWarning, const dom::Element* aElement) {
   if (mPerformanceWarning && *mPerformanceWarning == aWarning) {
     return;
   }
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -4,18 +4,19 @@
  * 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/KeyframeUtils.h"
 
 #include <algorithm>  // For std::stable_sort, std::min
 #include <utility>
 
+#include "jsapi.h"             // For most JSAPI
 #include "js/ForOfIterator.h"  // For JS::ForOfIterator
-#include "jsapi.h"             // For most JSAPI
+#include "js/PropertyAndElement.h"  // JS_Enumerate, JS_GetProperty, JS_GetPropertyById
 #include "mozilla/ComputedStyle.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/RangedArray.h"
 #include "mozilla/ServoBindingTypes.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/ServoCSSParser.h"
 #include "mozilla/StaticPrefs_dom.h"
 #include "mozilla/StyleAnimationValue.h"
--- a/dom/base/ChromeUtils.cpp
+++ b/dom/base/ChromeUtils.cpp
@@ -2,17 +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/. */
 
 #include "ChromeUtils.h"
 
 #include "js/CharacterEncoding.h"
-#include "js/Object.h"  // JS::GetClass
+#include "js/Object.h"              // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById, JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_SetProperty, JS_SetPropertyById
 #include "js/PropertyDescriptor.h"  // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById
 #include "js/SavedFrameAPI.h"
 #include "jsfriendapi.h"
 #include "WrapperFactory.h"
 
 #include "mozilla/Base64.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/EventStateManager.h"
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -19,17 +19,18 @@
 #include "mozilla/dom/WebComponentsBinding.h"
 #include "mozilla/dom/DocGroup.h"
 #include "mozilla/dom/CustomEvent.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "nsHTMLTags.h"
 #include "jsapi.h"
-#include "js/ForOfIterator.h"  // JS::ForOfIterator
+#include "js/ForOfIterator.h"       // JS::ForOfIterator
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_GetUCProperty
 #include "xpcprivate.h"
 #include "nsGlobalWindow.h"
 
 namespace mozilla::dom {
 
 //-----------------------------------------------------
 // CustomElementUpgradeReaction
 
--- a/dom/base/MaybeCrossOriginObject.cpp
+++ b/dom/base/MaybeCrossOriginObject.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/dom/MaybeCrossOriginObject.h"
 
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DOMJSProxyHandler.h"
 #include "mozilla/dom/RemoteObjectProxy.h"
 #include "js/friend/WindowProxy.h"  // js::IsWindowProxy
 #include "js/Object.h"              // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions, JS_DefineProperties
 #include "js/PropertyDescriptor.h"  // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById
 #include "js/Proxy.h"
 #include "js/RootingAPI.h"
 #include "js/Wrapper.h"
 #include "jsfriendapi.h"
 #include "AccessCheck.h"
 #include "nsContentUtils.h"
 
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -24,16 +24,17 @@
 #include "nsArrayUtils.h"
 #include "nsIMutableArray.h"
 #include "nsContentPermissionHelper.h"
 #include "nsJSUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
 #include "mozilla/dom/Document.h"
 #include "nsIWeakReferenceUtils.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_SetProperty
 
 using mozilla::Unused;  // <snicker>
 using namespace mozilla::dom;
 using namespace mozilla;
 using DelegateInfo = PermissionDelegateHandler::PermissionDelegateInfo;
 
 namespace mozilla::dom {
 
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -36,16 +36,17 @@
 #include "imgIRequest.h"
 #include "imgLoader.h"
 #include "js/Array.h"
 #include "js/ArrayBuffer.h"
 #include "js/BuildId.h"
 #include "js/GCAPI.h"
 #include "js/Id.h"
 #include "js/JSON.h"
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_GetProperty
 #include "js/PropertyDescriptor.h"
 #include "js/Realm.h"
 #include "js/RegExp.h"
 #include "js/RegExpFlags.h"
 #include "js/RootingAPI.h"
 #include "js/TypeDecls.h"
 #include "js/Value.h"
 #include "js/Wrapper.h"
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -14,16 +14,17 @@
 #include <utility>
 #include "ContentChild.h"
 #include "ErrorList.h"
 #include "mozilla/ProfilerLabels.h"
 #include "base/process_util.h"
 #include "chrome/common/ipc_channel.h"
 #include "js/CompilationAndEvaluation.h"
 #include "js/JSON.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 #include "js/SourceText.h"
 #include "js/StructuredClone.h"
 #include "js/Wrapper.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/ClearOnShutdown.h"
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -25,16 +25,17 @@
 #include "SessionStorageCache.h"
 #include "Units.h"
 #include "VRManagerChild.h"
 #include "WindowDestroyedEvent.h"
 #include "WindowNamedPropertiesHandler.h"
 #include "js/ComparisonOperators.h"
 #include "js/CompileOptions.h"
 #include "js/Id.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty
 #include "js/PropertyDescriptor.h"
 #include "js/RealmOptions.h"
 #include "js/RootingAPI.h"
 #include "js/TypeDecls.h"
 #include "js/Value.h"
 #include "js/Warnings.h"
 #include "js/shadow/String.h"
 #include "jsapi.h"
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -76,16 +76,17 @@
 #include "mozilla/dom/WindowGlobalChild.h"
 
 // Helper Classes
 #include "nsJSUtils.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/friend/StackLimits.h"  // js::AutoCheckRecursionLimit
 #include "js/friend/WindowProxy.h"  // js::IsWindowProxy, js::SetWindowProxy
+#include "js/PropertyAndElement.h"  // JS_DefineObject, JS_GetProperty
 #include "js/PropertySpec.h"
 #include "js/Wrapper.h"
 #include "nsLayoutUtils.h"
 #include "nsReadableUtils.h"
 #include "nsJSEnvironment.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -37,17 +37,18 @@
 #  include <process.h>
 #  define getpid _getpid
 #else
 #  include <unistd.h>  // for getpid()
 #endif
 #include "xpcpublic.h"
 
 #include "jsapi.h"
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/PropertySpec.h"
 #include "js/SliceBudget.h"
 #include "js/Wrapper.h"
 #include "nsIArray.h"
 #include "CCGCScheduler.h"
 #include "WrapperFactory.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/AutoRestore.h"
--- a/dom/base/test/gtest/TestContentUtils.cpp
+++ b/dom/base/test/gtest/TestContentUtils.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 "gtest/gtest.h"
 
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "nsContentUtils.h"
 #include "nsNetUtil.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/SimpleGlobalObject.h"
 
 struct IsURIInListMatch {
   nsLiteralCString pattern;
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -21,16 +21,17 @@
 #include "mozilla/UseCounter.h"
 
 #include "AccessCheck.h"
 #include "js/experimental/JitInfo.h"  // JSJit{Getter,Setter,Method}CallArgs, JSJit{Getter,Setter}Op, JSJitInfo
 #include "js/friend/StackLimits.h"  // js::AutoCheckRecursionLimit
 #include "js/Id.h"
 #include "js/JSON.h"
 #include "js/Object.h"  // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot, JS::SetReservedSlot
+#include "js/PropertyAndElement.h"  // JS_AlreadyHasOwnPropertyById, JS_DefineFunction, JS_DefineFunctionById, JS_DefineFunctions, JS_DefineProperties, JS_DefineProperty, JS_DefinePropertyById, JS_ForwardGetPropertyTo, JS_GetProperty, JS_HasProperty, JS_HasPropertyById
 #include "js/StableStringChars.h"
 #include "js/String.h"  // JS::GetStringLength, JS::MaxStringLength, JS::StringHasLatin1Chars
 #include "js/Symbol.h"
 #include "jsfriendapi.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsHTMLTags.h"
--- a/dom/bindings/CallbackInterface.cpp
+++ b/dom/bindings/CallbackInterface.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 "mozilla/dom/CallbackInterface.h"
 #include "jsapi.h"
 #include "js/CharacterEncoding.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_GetPropertyById
 #include "mozilla/dom/BindingUtils.h"
 #include "nsPrintfCString.h"
 
 namespace mozilla::dom {
 
 bool CallbackInterface::GetCallableProperty(
     BindingCallContext& cx, JS::Handle<jsid> aPropId,
     JS::MutableHandle<JS::Value> aCallable) {
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -18134,16 +18134,22 @@ class CGBindingRoot(CGThing):
         # *at* the places where their definitions are required.
         bindingHeaders["js/experimental/JitInfo.h"] = True
 
         # JS::GetClass, JS::GetCompartment, JS::GetReservedSlot, and
         # JS::SetReservedSlot are also used too many places to restate
         # dependency logic.
         bindingHeaders["js/Object.h"] = True
 
+        # JS_DefineElement, JS_DefineProperty, JS_DefinePropertyById,
+        # JS_DefineUCProperty, JS_ForwardGetPropertyTo, JS_GetProperty,
+        # JS_GetPropertyById, JS_HasPropertyById, JS_SetProperty,
+        # JS_SetPropertyById
+        bindingHeaders["js/PropertyAndElement.h"] = True
+
         # JS_GetOwnPropertyDescriptorById
         bindingHeaders["js/PropertyDescriptor.h"] = True
 
         def descriptorDeprecated(desc):
             iface = desc.interface
             return any(
                 m.getExtendedAttribute("Deprecated") for m in iface.members + [iface]
             )
--- a/dom/bindings/DOMJSProxyHandler.cpp
+++ b/dom/bindings/DOMJSProxyHandler.cpp
@@ -9,17 +9,18 @@
 #include "xpcprivate.h"
 #include "XPCWrapper.h"
 #include "WrapperFactory.h"
 #include "nsWrapperCacheInlines.h"
 #include "mozilla/dom/BindingUtils.h"
 
 #include "jsapi.h"
 #include "js/friend/DOMProxy.h"  // JS::DOMProxyShadowsResult, JS::ExpandoAndGeneration, JS::SetDOMProxyInformation
-#include "js/Object.h"           // JS::GetCompartment
+#include "js/PropertyAndElement.h"  // JS_AlreadyHasOwnPropertyById, JS_DefineProperty, JS_DefinePropertyById, JS_DeleteProperty, JS_DeletePropertyById
+#include "js/Object.h"              // JS::GetCompartment
 
 using namespace JS;
 
 namespace mozilla::dom {
 
 jsid s_length_id = JSID_VOID;
 
 bool DefineStaticJSVals(JSContext* cx) {
--- a/dom/bindings/ToJSValue.h
+++ b/dom/bindings/ToJSValue.h
@@ -5,24 +5,25 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_ToJSValue_h
 #define mozilla_dom_ToJSValue_h
 
 #include <cstddef>  // for size_t
 #include <cstdint>  // for int32_t, int64_t, uint32_t, uint64_t
 #include <type_traits>  // for is_base_of, enable_if_t, enable_if, is_pointer, is_same, void_t
-#include <utility>          // for forward
-#include "ErrorList.h"      // for nsresult
-#include "js/Array.h"       // for NewArrayObject
-#include "js/GCVector.h"    // for RootedVector, MutableWrappedPtrOperations
-#include "js/RootingAPI.h"  // for MutableHandle, Rooted, Handle, Heap
-#include "js/Value.h"       // for Value
-#include "js/ValueArray.h"  // for HandleValueArray
-#include "jsapi.h"          // for CurrentGlobalOrNull
+#include <utility>        // for forward
+#include "ErrorList.h"    // for nsresult
+#include "js/Array.h"     // for NewArrayObject
+#include "js/GCVector.h"  // for RootedVector, MutableWrappedPtrOperations
+#include "js/PropertyAndElement.h"  // JS_DefineUCProperty
+#include "js/RootingAPI.h"          // for MutableHandle, Rooted, Handle, Heap
+#include "js/Value.h"               // for Value
+#include "js/ValueArray.h"          // for HandleValueArray
+#include "jsapi.h"                  // for CurrentGlobalOrNull
 #include "mozilla/Assertions.h"  // for AssertionConditionType, MOZ_ASSERT, MOZ_ASSERT_HELPER1
 #include "mozilla/UniquePtr.h"         // for UniquePtr
 #include "mozilla/Unused.h"            // for Unused
 #include "mozilla/dom/BindingUtils.h"  // for MaybeWrapValue, MaybeWrapObjectOrNullValue, XPCOMObjectToJsval, GetOrCreateDOMReflector
 #include "mozilla/dom/CallbackObject.h"  // for CallbackObject
 #include "mozilla/dom/Record.h"
 #include "nsID.h"         // for NS_GET_TEMPLATE_IID, nsIID
 #include "nsISupports.h"  // for nsISupports
--- a/dom/cache/Cache.cpp
+++ b/dom/cache/Cache.cpp
@@ -1,17 +1,18 @@
 /* -*- 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 "mozilla/dom/cache/Cache.h"
 
-#include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
+#include "js/Array.h"               // JS::GetArrayLength, JS::IsArrayObject
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "mozilla/dom/Headers.h"
 #include "mozilla/dom/InternalResponse.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/dom/Response.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/CacheBinding.h"
 #include "mozilla/dom/cache/AutoUtils.h"
--- a/dom/cache/CacheStorage.cpp
+++ b/dom/cache/CacheStorage.cpp
@@ -30,17 +30,18 @@
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/StaticPrefs_dom.h"
 #include "mozilla/StaticPrefs_extensions.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/Document.h"
 #include "nsIGlobalObject.h"
 #include "nsMixedContentBlocker.h"
 #include "nsURLParsers.h"
-#include "js/Object.h"  // JS::GetClass
+#include "js/Object.h"              // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 
 namespace mozilla::dom::cache {
 
 using mozilla::ErrorResult;
 using mozilla::Unused;
 using mozilla::dom::quota::QuotaManager;
 using mozilla::ipc::BackgroundChild;
 using mozilla::ipc::IProtocol;
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -64,17 +64,18 @@
 #include <algorithm>
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::GetArrayLength
 #include "js/Conversions.h"
 #include "js/experimental/TypedData.h"  // JS_NewUint8ClampedArray, JS_GetUint8ClampedArrayData
 #include "js/HeapAPI.h"
-#include "js/Warnings.h"  // JS::WarnASCII
+#include "js/PropertyAndElement.h"  // JS_GetElement
+#include "js/Warnings.h"            // JS::WarnASCII
 
 #include "mozilla/Alignment.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/CanvasGradient.h"
 #include "mozilla/dom/CanvasPattern.h"
 #include "mozilla/dom/DOMMatrix.h"
--- a/dom/canvas/CanvasUtils.h
+++ b/dom/canvas/CanvasUtils.h
@@ -5,17 +5,18 @@
 
 #ifndef _CANVASUTILS_H_
 #define _CANVASUTILS_H_
 
 #include "CanvasRenderingContextHelper.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "jsapi.h"
-#include "js/Array.h"  // JS::GetArrayLength
+#include "js/Array.h"               // JS::GetArrayLength
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "mozilla/FloatingPoint.h"
 
 class nsIPrincipal;
 
 namespace mozilla {
 
 namespace dom {
 class Document;
--- a/dom/canvas/ClientWebGLContext.cpp
+++ b/dom/canvas/ClientWebGLContext.cpp
@@ -4,17 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ClientWebGLContext.h"
 
 #include "ClientWebGLExtensions.h"
 #include "Layers.h"
 #include "gfxCrashReporterUtils.h"
 #include "HostWebGLContext.h"
-#include "js/ScalarType.h"  // js::Scalar::Type
+#include "js/PropertyAndElement.h"  // JS_DefineElement
+#include "js/ScalarType.h"          // js::Scalar::Type
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/WebGLContextEvent.h"
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/EnumeratedRange.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/ipc/Shmem.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -4,17 +4,18 @@
  * 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/dom/Console.h"
 #include "mozilla/dom/ConsoleInstance.h"
 #include "mozilla/dom/ConsoleBinding.h"
 #include "ConsoleCommon.h"
 
-#include "js/Array.h"  // JS::GetArrayLength, JS::NewArrayObject
+#include "js/Array.h"               // JS::GetArrayLength, JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty, JS_GetElement
 #include "mozilla/dom/BlobBinding.h"
 #include "mozilla/dom/BlobImpl.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/Exceptions.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/PromiseBinding.h"
--- a/dom/console/ConsoleUtils.cpp
+++ b/dom/console/ConsoleUtils.cpp
@@ -11,16 +11,17 @@
 #include "nsIXPConnect.h"
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/NullPrincipal.h"
 #include "mozilla/dom/ConsoleBinding.h"
 #include "mozilla/dom/RootedDictionary.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 
 namespace mozilla::dom {
 
 namespace {
 
 StaticRefPtr<ConsoleUtils> gConsoleUtilsService;
 
 }
--- a/dom/filesystem/compat/FileSystemDirectoryReader.cpp
+++ b/dom/filesystem/compat/FileSystemDirectoryReader.cpp
@@ -2,17 +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/. */
 
 #include "FileSystemDirectoryReader.h"
 #include "CallbackRunnables.h"
 #include "FileSystemFileEntry.h"
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "mozilla/dom/FileBinding.h"
 #include "mozilla/dom/FileSystem.h"
 #include "mozilla/dom/FileSystemDirectoryReaderBinding.h"
 #include "mozilla/dom/FileSystemUtils.h"
 #include "mozilla/dom/Directory.h"
 #include "mozilla/dom/DirectoryBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -46,16 +46,17 @@
 #include "MediaTrackList.h"
 #include "Navigator.h"
 #include "TimeRanges.h"
 #include "VideoFrameContainer.h"
 #include "VideoOutput.h"
 #include "VideoStreamTrack.h"
 #include "base/basictypes.h"
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/EMEUtils.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/NotNull.h"
 #include "mozilla/Preferences.h"
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -16,18 +16,19 @@
 #include "IDBIndex.h"
 #include "IDBMutableFile.h"
 #include "IDBObjectStore.h"
 #include "IDBRequest.h"
 #include "IDBTransaction.h"
 #include "IndexedDatabase.h"
 #include "IndexedDatabaseInlines.h"
 #include "IndexedDBCommon.h"
-#include "js/Array.h"  // JS::NewArrayObject, JS::SetArrayLength
-#include "js/Date.h"   // JS::NewDateObject, JS::TimeClip
+#include "js/Array.h"               // JS::NewArrayObject, JS::SetArrayLength
+#include "js/Date.h"                // JS::NewDateObject, JS::TimeClip
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty
 #include <mozIRemoteLazyInputStream.h>
 #include "mozilla/ArrayAlgorithm.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/dom/BlobImpl.h"
 #include "mozilla/dom/Element.h"
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -24,16 +24,17 @@
 #include "IndexedDBCommon.h"
 #include "KeyPath.h"
 #include "ProfilerHelpers.h"
 #include "ReportInternalError.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
 #include "js/Class.h"
 #include "js/Date.h"
 #include "js/Object.h"  // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_GetPropertyById, JS_HasOwnProperty, JS_HasOwnPropertyById
 #include "js/StructuredClone.h"
 #include "mozilla/EndianUtils.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/BlobBinding.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/IDBMutableFileBinding.h"
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -6,17 +6,18 @@
 
 #include "IndexedDatabaseManager.h"
 
 #include "chrome/common/ipc_channel.h"  // for IPC::Channel::kMaximumMessageSize
 #include "nsIScriptError.h"
 #include "nsIScriptGlobalObject.h"
 
 #include "jsapi.h"
-#include "js/Object.h"  // JS::GetClass
+#include "js/Object.h"              // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/ErrorEventBinding.h"
--- a/dom/indexedDB/Key.cpp
+++ b/dom/indexedDB/Key.cpp
@@ -12,17 +12,18 @@
 #include "IndexedDatabase.h"
 #include "IndexedDatabaseInlines.h"
 #include "IndexedDatabaseManager.h"
 #include "js/Array.h"        // JS::NewArrayObject
 #include "js/ArrayBuffer.h"  // JS::{IsArrayBufferObject,NewArrayBuffer{,WithContents},GetArrayBufferLengthAndData}
 #include "js/Date.h"
 #include "js/experimental/TypedData.h"  // JS_IsArrayBufferViewObject, JS_GetObjectAsArrayBufferView
 #include "js/MemoryFunctions.h"
-#include "js/Object.h"  // JS::GetBuiltinClass
+#include "js/Object.h"              // JS::GetBuiltinClass
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_GetProperty, JS_GetPropertyById, JS_HasOwnProperty, JS_HasOwnPropertyById
 #include "js/Value.h"
 #include "jsfriendapi.h"
 #include "mozilla/Casting.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/EndianUtils.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/ReverseIterator.h"
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -5,17 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "KeyPath.h"
 
 #include "IDBObjectStore.h"
 #include "IndexedDBCommon.h"
 #include "Key.h"
 #include "ReportInternalError.h"
-#include "js/Array.h"               // JS::NewArrayObject
+#include "js/Array.h"  // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineUCProperty, JS_DeleteUCProperty
 #include "js/PropertyDescriptor.h"  // JS::PropertyDescriptor, JS_GetOwnUCPropertyDescriptor
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/Blob.h"
 #include "mozilla/dom/BlobBinding.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/IDBObjectStoreBinding.h"
 #include "nsCharSeparatedTokenizer.h"
--- a/dom/indexedDB/test/gtest/TestKey.cpp
+++ b/dom/indexedDB/test/gtest/TestKey.cpp
@@ -10,16 +10,17 @@
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/indexedDB/Key.h"
 #include "mozilla/IntegerRange.h"
 #include "mozilla/Unused.h"
 
 #include "jsapi.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
 #include "js/ArrayBuffer.h"
+#include "js/PropertyAndElement.h"  // JS_GetElement, JS_SetElement
 
 // TODO: This PrintTo overload is defined in dom/media/gtest/TestGroupId.cpp.
 // However, it is not used, probably because of
 // https://stackoverflow.com/a/36941270
 void PrintTo(const nsString& value, std::ostream* os);
 
 using namespace mozilla;
 using namespace mozilla::dom::indexedDB;
--- a/dom/ipc/jsactor/JSActorManager.cpp
+++ b/dom/ipc/jsactor/JSActorManager.cpp
@@ -8,16 +8,17 @@
 
 #include "mozilla/dom/AutoEntryScript.h"
 #include "mozilla/dom/JSActorService.h"
 #include "mozilla/dom/PWindowGlobal.h"
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ScopeExit.h"
 #include "mozJSComponentLoader.h"
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 #include "nsContentUtils.h"
 
 namespace mozilla::dom {
 
 already_AddRefed<JSActor> JSActorManager::GetActor(JSContext* aCx,
                                                    const nsACString& aName,
                                                    ErrorResult& aRv) {
   MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
--- a/dom/media/webaudio/AudioWorkletGlobalScope.cpp
+++ b/dom/media/webaudio/AudioWorkletGlobalScope.cpp
@@ -6,16 +6,17 @@
 
 #include "AudioWorkletGlobalScope.h"
 
 #include "AudioNodeEngine.h"
 #include "AudioNodeTrack.h"
 #include "AudioWorkletImpl.h"
 #include "jsapi.h"
 #include "js/ForOfIterator.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 #include "mozilla/dom/AudioWorkletGlobalScopeBinding.h"
 #include "mozilla/dom/AudioWorkletProcessor.h"
 #include "mozilla/dom/BindingCallContext.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/StructuredCloneHolder.h"
 #include "mozilla/dom/WorkletPrincipals.h"
 #include "mozilla/dom/AudioParamDescriptorBinding.h"
 #include "nsPrintfCString.h"
--- a/dom/media/webaudio/AudioWorkletNode.cpp
+++ b/dom/media/webaudio/AudioWorkletNode.cpp
@@ -7,16 +7,17 @@
 #include "AudioWorkletNode.h"
 
 #include "AudioNodeEngine.h"
 #include "AudioParamMap.h"
 #include "AudioWorkletImpl.h"
 #include "js/Array.h"  // JS::{Get,Set}ArrayLength, JS::NewArrayLength
 #include "js/Exception.h"
 #include "js/experimental/TypedData.h"  // JS_NewFloat32Array, JS_GetFloat32ArrayData, JS_GetTypedArrayLength, JS_GetArrayBufferViewBuffer
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineUCProperty, JS_GetProperty
 #include "mozilla/dom/AudioWorkletNodeBinding.h"
 #include "mozilla/dom/AudioParamMapBinding.h"
 #include "mozilla/dom/AutoEntryScript.h"
 #include "mozilla/dom/RootedDictionary.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/Worklet.h"
 #include "nsIScriptGlobalObject.h"
 #include "AudioParam.h"
--- a/dom/performance/PerformanceMainThread.cpp
+++ b/dom/performance/PerformanceMainThread.cpp
@@ -2,18 +2,19 @@
 /* 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 "PerformanceMainThread.h"
 #include "PerformanceNavigation.h"
 #include "PerformancePaintTiming.h"
+#include "jsapi.h"
 #include "js/GCAPI.h"
-#include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "mozilla/HoldDropJSObjects.h"
 #include "PerformanceEventTiming.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/EventCounts.h"
 #include "mozilla/dom/PerformanceEventTimingBinding.h"
 #include "mozilla/dom/PerformanceNavigationTiming.h"
 #include "mozilla/dom/PerformanceResourceTiming.h"
--- a/dom/reporting/ReportingHeader.cpp
+++ b/dom/reporting/ReportingHeader.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/dom/ReportingHeader.h"
 
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
 #include "js/JSON.h"
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "mozilla/dom/ReportingBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/SimpleGlobalObject.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/OriginAttributes.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPrefs_dom.h"
 #include "mozilla/StaticPtr.h"
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -16,16 +16,17 @@
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::GetArrayLength
 #include "js/CompilationAndEvaluation.h"
 #include "js/ContextOptions.h"        // JS::ContextOptionsRef
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/MemoryFunctions.h"
 #include "js/Modules.h"  // JS::FinishDynamicModuleImport, JS::{G,S}etModuleResolveHook, JS::Get{ModulePrivate,ModuleScript,RequestedModule{s,Specifier,SourcePos}}, JS::SetModule{DynamicImport,Metadata}Hook
 #include "js/OffThreadScriptCompilation.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetElement
 #include "js/Realm.h"
 #include "js/SourceText.h"
 #include "js/Utility.h"
 #include "xpcpublic.h"
 #include "GeckoProfiler.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIContent.h"
 #include "nsJSUtils.h"
--- a/dom/script/ScriptSettings.cpp
+++ b/dom/script/ScriptSettings.cpp
@@ -10,16 +10,17 @@
 #include "LoadedScript.h"
 #include "MainThreadUtils.h"
 #include "js/CharacterEncoding.h"
 #include "js/CompilationAndEvaluation.h"
 #include "js/Conversions.h"
 #include "js/ErrorReport.h"
 #include "js/Exception.h"
 #include "js/GCAPI.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 #include "js/TypeDecls.h"
 #include "js/Value.h"
 #include "js/Warnings.h"
 #include "js/Wrapper.h"
 #include "js/friend/ErrorMessages.h"
 #include "jsapi.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/BasePrincipal.h"
--- a/dom/security/nsContentSecurityUtils.cpp
+++ b/dom/security/nsContentSecurityUtils.cpp
@@ -23,16 +23,17 @@
 #if defined(XP_WIN)
 #  include "WinUtils.h"
 #  include <wininet.h>
 #endif
 
 #include "FramingChecker.h"
 #include "js/Array.h"  // JS::GetArrayLength
 #include "js/ContextOptions.h"
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "js/RegExp.h"
 #include "js/RegExpFlags.h"  // JS::RegExpFlags
 #include "mozilla/ExtensionPolicyService.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/nsCSPContext.h"
 #include "mozilla/StaticPrefs_security.h"
--- a/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp
+++ b/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp
@@ -1,17 +1,18 @@
 /* -*- 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 "core/TelemetryEvent.h"
 #include "gtest/gtest.h"
-#include "js/Array.h"  // JS::GetArrayLength
+#include "js/Array.h"               // JS::GetArrayLength
+#include "js/PropertyAndElement.h"  // JS_GetElement, JS_GetProperty
 #include "js/TypeDecls.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "TelemetryFixture.h"
 #include "TelemetryTestHelpers.h"
--- a/dom/serviceworkers/ServiceWorkerScriptCache.cpp
+++ b/dom/serviceworkers/ServiceWorkerScriptCache.cpp
@@ -1,17 +1,18 @@
 /* -*- 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 "ServiceWorkerScriptCache.h"
 
-#include "js/Array.h"  // JS::GetArrayLength
+#include "js/Array.h"               // JS::GetArrayLength
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "mozilla/Unused.h"
 #include "mozilla/dom/CacheBinding.h"
 #include "mozilla/dom/cache/CacheStorage.h"
 #include "mozilla/dom/cache/Cache.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseWorkerProxy.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "mozilla/dom/WorkerCommon.h"
--- a/dom/system/OSFileConstants.cpp
+++ b/dom/system/OSFileConstants.cpp
@@ -54,16 +54,17 @@
 #    define PATH_MAX MAX_PATH
 #  endif
 
 #endif  // defined(XP_WIN)
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
+#include "js/PropertyAndElement.h"  // JS_DefineObject, JS_DefineProperty, JS_GetProperty, JS_SetProperty
 #include "BindingUtils.h"
 
 // Used to provide information on the OS
 
 #include "nsThreadUtils.h"
 #include "nsIObserverService.h"
 #include "nsIObserver.h"
 #include "nsDirectoryServiceUtils.h"
--- a/dom/workers/ChromeWorkerScope.cpp
+++ b/dom/workers/ChromeWorkerScope.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 "ChromeWorkerScope.h"
 
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 #include "js/experimental/CTypes.h"  // JS::InitCTypesClass, JS::CTypesCallbacks, JS::SetCTypesCallbacks
 #include "js/MemoryFunctions.h"
 
 #include "nsNativeCharsetUtils.h"
 #include "nsString.h"
 
 namespace mozilla {
 namespace dom {
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -12,16 +12,17 @@
 #include "nspr.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/NullPrincipal.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "nsContentUtils.h"
 #include "nsJSPrincipals.h"
 #include "nsIScriptError.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/Wrapper.h"
 #include "mozilla/Utf8.h"
 
 extern mozilla::LazyLogModule MCD;
 using mozilla::AutoSafeJSContext;
 using mozilla::IsUtf8;
 using mozilla::NullPrincipal;
 using mozilla::dom::AutoJSAPI;
--- a/intl/l10n/FluentBundle.cpp
+++ b/intl/l10n/FluentBundle.cpp
@@ -7,16 +7,17 @@
 #include "FluentBundle.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/UnionTypes.h"
 #include "mozilla/intl/NumberFormat.h"
 #include "mozilla/intl/DateTimeFormat.h"
 #include "nsIInputStream.h"
 #include "nsStringFwd.h"
 #include "nsTArray.h"
+#include "js/PropertyAndElement.h"  // JS_DefineElement
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 namespace intl {
 
 class SizeableUTF8Buffer {
  public:
--- a/intl/l10n/Localization.cpp
+++ b/intl/l10n/Localization.cpp
@@ -7,16 +7,17 @@
 #include "Localization.h"
 #include "nsImportModule.h"
 #include "nsIObserverService.h"
 #include "nsContentUtils.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 
 #define INTL_APP_LOCALES_CHANGED "intl:app-locales-changed"
 #define L10N_PSEUDO_PREF "intl.l10n.pseudo"
 
 static const char* kObservedPrefs[] = {L10N_PSEUDO_PREF, nullptr};
 
 using namespace mozilla::intl;
 using namespace mozilla::dom;
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -13,16 +13,17 @@
 #  include <unistd.h> /* for isatty() */
 #endif
 
 #include "base/basictypes.h"
 
 #include "jsapi.h"
 #include "js/CharacterEncoding.h"
 #include "js/CompilationAndEvaluation.h"  // JS::Compile{,Utf8File}
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions, JS_DefineProperty, JS_GetProperty
 #include "js/PropertySpec.h"
 #include "js/SourceText.h"  // JS::Source{Ownership,Text}
 
 #include "xpcpublic.h"
 
 #include "XPCShellEnvironment.h"
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
new file mode 100644
--- /dev/null
+++ b/js/public/PropertyAndElement.h
@@ -0,0 +1,485 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+/* Property and element API. */
+
+#ifndef js_PropertyAndElement_h
+#define js_PropertyAndElement_h
+
+#include <stddef.h>  // size_t
+#include <stdint.h>  // uint32_t
+
+#include "jstypes.h"  // JS_PUBLIC_API
+
+#include "js/CallArgs.h"            // JSNative
+#include "js/Class.h"               // JS::ObjectOpResult
+#include "js/GCVector.h"            // JS::GCVector
+#include "js/Id.h"                  // jsid
+#include "js/PropertyDescriptor.h"  // JS::PropertyDescriptor
+#include "js/RootingAPI.h"          // JS::Handle, JS::MutableHandle
+
+struct JSContext;
+class JSFunction;
+class JSObject;
+class JSString;
+
+namespace JS {
+
+using IdVector = JS::GCVector<jsid>;
+
+} /* namespace JS */
+
+/**
+ * Define a property on obj.
+ *
+ * This function uses JS::ObjectOpResult to indicate conditions that ES6
+ * specifies as non-error failures. This is inconvenient at best, so use this
+ * function only if you are implementing a proxy handler's defineProperty()
+ * method. For all other purposes, use one of the many DefineProperty functions
+ * below that throw an exception in all failure cases.
+ *
+ * Implements: ES6 [[DefineOwnProperty]] internal method.
+ */
+extern JS_PUBLIC_API bool JS_DefinePropertyById(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& result);
+
+/**
+ * Define a property on obj, throwing a TypeError if the attempt fails.
+ * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`.
+ */
+extern JS_PUBLIC_API bool JS_DefinePropertyById(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JS::Handle<JS::PropertyDescriptor> desc);
+
+extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                JS::Handle<JS::Value> value,
+                                                unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefinePropertyById(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JSNative getter, JSNative setter, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefinePropertyById(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JS::Handle<JSObject*> getter, JS::Handle<JSObject*> setter, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                JS::Handle<JSObject*> value,
+                                                unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                JS::Handle<JSString*> value,
+                                                unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                int32_t value, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                uint32_t value, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                double value, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name,
+                                            JS::Handle<JS::Value> value,
+                                            unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name, JSNative getter,
+                                            JSNative setter, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineProperty(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char* name,
+    JS::Handle<JSObject*> getter, JS::Handle<JSObject*> setter, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name,
+                                            JS::Handle<JSObject*> value,
+                                            unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name,
+                                            JS::Handle<JSString*> value,
+                                            unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name, int32_t value,
+                                            unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name, uint32_t value,
+                                            unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name, double value,
+                                            unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
+    size_t namelen, JS::Handle<JS::PropertyDescriptor> desc,
+    JS::ObjectOpResult& result);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
+    size_t namelen, JS::Handle<JS::PropertyDescriptor> desc);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
+    size_t namelen, JS::Handle<JS::Value> value, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
+    size_t namelen, JS::Handle<JSObject*> getter, JS::Handle<JSObject*> setter,
+    unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
+    size_t namelen, JS::Handle<JSObject*> value, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
+    size_t namelen, JS::Handle<JSString*> value, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
+                                              JS::Handle<JSObject*> obj,
+                                              const char16_t* name,
+                                              size_t namelen, int32_t value,
+                                              unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
+                                              JS::Handle<JSObject*> obj,
+                                              const char16_t* name,
+                                              size_t namelen, uint32_t value,
+                                              unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
+                                              JS::Handle<JSObject*> obj,
+                                              const char16_t* name,
+                                              size_t namelen, double value,
+                                              unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index,
+                                           JS::Handle<JS::Value> value,
+                                           unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineElement(
+    JSContext* cx, JS::Handle<JSObject*> obj, uint32_t index,
+    JS::Handle<JSObject*> getter, JS::Handle<JSObject*> setter, unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index,
+                                           JS::Handle<JSObject*> value,
+                                           unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index,
+                                           JS::Handle<JSString*> value,
+                                           unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index, int32_t value,
+                                           unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index, uint32_t value,
+                                           unsigned attrs);
+
+extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index, double value,
+                                           unsigned attrs);
+
+/**
+ * Compute the expression `id in obj`.
+ *
+ * If obj has an own or inherited property obj[id], set *foundp = true and
+ * return true. If not, set *foundp = false and return true. On error, return
+ * false with an exception pending.
+ *
+ * Implements: ES6 [[Has]] internal method.
+ */
+extern JS_PUBLIC_API bool JS_HasPropertyById(JSContext* cx,
+                                             JS::Handle<JSObject*> obj,
+                                             JS::Handle<jsid> id, bool* foundp);
+
+extern JS_PUBLIC_API bool JS_HasProperty(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         const char* name, bool* foundp);
+
+extern JS_PUBLIC_API bool JS_HasUCProperty(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           const char16_t* name, size_t namelen,
+                                           bool* vp);
+
+extern JS_PUBLIC_API bool JS_HasElement(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        uint32_t index, bool* foundp);
+
+/**
+ * Determine whether obj has an own property with the key `id`.
+ *
+ * Implements: ES6 7.3.11 HasOwnProperty(O, P).
+ */
+extern JS_PUBLIC_API bool JS_HasOwnPropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                bool* foundp);
+
+extern JS_PUBLIC_API bool JS_HasOwnProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name, bool* foundp);
+
+/**
+ * Get the value of the property `obj[id]`, or undefined if no such property
+ * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`.
+ *
+ * Most callers don't need the `receiver` argument. Consider using
+ * JS_GetProperty instead. (But if you're implementing a proxy handler's set()
+ * method, it's often correct to call this function and pass the receiver
+ * through.)
+ *
+ * Implements: ES6 [[Get]] internal method.
+ */
+extern JS_PUBLIC_API bool JS_ForwardGetPropertyTo(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JS::Handle<JS::Value> receiver, JS::MutableHandleValue vp);
+
+extern JS_PUBLIC_API bool JS_ForwardGetElementTo(JSContext* cx,
+                                                 JS::Handle<JSObject*> obj,
+                                                 uint32_t index,
+                                                 JS::Handle<JSObject*> receiver,
+                                                 JS::MutableHandleValue vp);
+
+/**
+ * Get the value of the property `obj[id]`, or undefined if no such property
+ * exists. The result is stored in vp.
+ *
+ * Implements: ES6 7.3.1 Get(O, P).
+ */
+extern JS_PUBLIC_API bool JS_GetPropertyById(JSContext* cx,
+                                             JS::Handle<JSObject*> obj,
+                                             JS::Handle<jsid> id,
+                                             JS::MutableHandleValue vp);
+
+extern JS_PUBLIC_API bool JS_GetProperty(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         const char* name,
+                                         JS::MutableHandleValue vp);
+
+extern JS_PUBLIC_API bool JS_GetUCProperty(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           const char16_t* name, size_t namelen,
+                                           JS::MutableHandleValue vp);
+
+extern JS_PUBLIC_API bool JS_GetElement(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        uint32_t index,
+                                        JS::MutableHandleValue vp);
+
+/**
+ * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`.
+ *
+ * This function has a `receiver` argument that most callers don't need.
+ * Consider using JS_SetProperty instead.
+ *
+ * Implements: ES6 [[Set]] internal method.
+ */
+extern JS_PUBLIC_API bool JS_ForwardSetPropertyTo(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
+    JS::ObjectOpResult& result);
+
+/**
+ * Perform the assignment `obj[id] = v`.
+ *
+ * This function performs non-strict assignment, so if the property is
+ * read-only, nothing happens and no error is thrown.
+ */
+extern JS_PUBLIC_API bool JS_SetPropertyById(JSContext* cx,
+                                             JS::Handle<JSObject*> obj,
+                                             JS::Handle<jsid> id,
+                                             JS::Handle<JS::Value> v);
+
+extern JS_PUBLIC_API bool JS_SetProperty(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         const char* name,
+                                         JS::Handle<JS::Value> v);
+
+extern JS_PUBLIC_API bool JS_SetUCProperty(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           const char16_t* name, size_t namelen,
+                                           JS::Handle<JS::Value> v);
+
+extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        uint32_t index,
+                                        JS::Handle<JS::Value> v);
+
+extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        uint32_t index,
+                                        JS::Handle<JSObject*> v);
+
+extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        uint32_t index,
+                                        JS::Handle<JSString*> v);
+
+extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        uint32_t index, int32_t v);
+
+extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        uint32_t index, uint32_t v);
+
+extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        uint32_t index, double v);
+
+/**
+ * Delete a property. This is the C++ equivalent of
+ * `result = Reflect.deleteProperty(obj, id)`.
+ *
+ * This function has a `result` out parameter that most callers don't need.
+ * Unless you can pass through an ObjectOpResult provided by your caller, it's
+ * probably best to use the JS_DeletePropertyById signature with just 3
+ * arguments.
+ *
+ * Implements: ES6 [[Delete]] internal method.
+ */
+extern JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                JS::ObjectOpResult& result);
+
+extern JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name,
+                                            JS::ObjectOpResult& result);
+
+extern JS_PUBLIC_API bool JS_DeleteUCProperty(JSContext* cx,
+                                              JS::Handle<JSObject*> obj,
+                                              const char16_t* name,
+                                              size_t namelen,
+                                              JS::ObjectOpResult& result);
+
+extern JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index,
+                                           JS::ObjectOpResult& result);
+
+/**
+ * Delete a property, ignoring strict failures. This is the C++ equivalent of
+ * the JS `delete obj[id]` in non-strict mode code.
+ */
+extern JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                jsid id);
+
+extern JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name);
+
+extern JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index);
+
+/**
+ * Get an array of the non-symbol enumerable properties of obj.
+ * This function is roughly equivalent to:
+ *
+ *     var result = [];
+ *     for (key in obj) {
+ *         result.push(key);
+ *     }
+ *     return result;
+ *
+ * This is the closest thing we currently have to the ES6 [[Enumerate]]
+ * internal method.
+ *
+ * The array of ids returned by JS_Enumerate must be rooted to protect its
+ * contents from garbage collection. Use JS::Rooted<JS::IdVector>.
+ */
+extern JS_PUBLIC_API bool JS_Enumerate(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       JS::MutableHandle<JS::IdVector> props);
+
+/*** Other property-defining functions **************************************/
+
+extern JS_PUBLIC_API JSObject* JS_DefineObject(JSContext* cx,
+                                               JS::Handle<JSObject*> obj,
+                                               const char* name,
+                                               const JSClass* clasp = nullptr,
+                                               unsigned attrs = 0);
+
+extern JS_PUBLIC_API bool JS_DefineProperties(JSContext* cx,
+                                              JS::Handle<JSObject*> obj,
+                                              const JSPropertySpec* ps);
+
+/* * */
+
+extern JS_PUBLIC_API bool JS_AlreadyHasOwnPropertyById(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    bool* foundp);
+
+extern JS_PUBLIC_API bool JS_AlreadyHasOwnProperty(JSContext* cx,
+                                                   JS::Handle<JSObject*> obj,
+                                                   const char* name,
+                                                   bool* foundp);
+
+extern JS_PUBLIC_API bool JS_AlreadyHasOwnUCProperty(JSContext* cx,
+                                                     JS::Handle<JSObject*> obj,
+                                                     const char16_t* name,
+                                                     size_t namelen,
+                                                     bool* foundp);
+
+extern JS_PUBLIC_API bool JS_AlreadyHasOwnElement(JSContext* cx,
+                                                  JS::Handle<JSObject*> obj,
+                                                  uint32_t index, bool* foundp);
+
+extern JS_PUBLIC_API bool JS_DefineFunctions(JSContext* cx,
+                                             JS::Handle<JSObject*> obj,
+                                             const JSFunctionSpec* fs);
+
+extern JS_PUBLIC_API JSFunction* JS_DefineFunction(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char* name, JSNative call,
+    unsigned nargs, unsigned attrs);
+
+extern JS_PUBLIC_API JSFunction* JS_DefineUCFunction(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
+    size_t namelen, JSNative call, unsigned nargs, unsigned attrs);
+
+extern JS_PUBLIC_API JSFunction* JS_DefineFunctionById(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JSNative call, unsigned nargs, unsigned attrs);
+
+#endif /* js_PropertyAndElement_h */
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.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 "builtin/MapObject.h"
 
 #include "ds/OrderedHashTable.h"
 #include "gc/FreeOp.h"
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions
 #include "js/PropertySpec.h"
 #include "js/Utility.h"
 #include "vm/BigIntType.h"
 #include "vm/EqualityOperations.h"  // js::SameValue
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/Iteration.h"
 #include "vm/JSContext.h"
--- a/js/src/builtin/Profilers.cpp
+++ b/js/src/builtin/Profilers.cpp
@@ -22,16 +22,17 @@
 
 #ifdef __APPLE__
 #  ifdef MOZ_INSTRUMENTS
 #    include "devtools/Instruments.h"
 #  endif
 #endif
 
 #include "js/CharacterEncoding.h"
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions
 #include "js/PropertySpec.h"
 #include "js/Utility.h"
 #include "util/Text.h"
 #include "vm/Probes.h"
 
 #include "vm/JSContext-inl.h"
 
 using namespace js;
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -18,16 +18,17 @@
 #include "builtin/Reflect.h"
 #include "frontend/CompilationStencil.h"
 #include "frontend/ModuleSharedContext.h"
 #include "frontend/ParseNode.h"
 #include "frontend/Parser.h"
 #include "js/CharacterEncoding.h"
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/friend/StackLimits.h"    // js::AutoCheckRecursionLimit
+#include "js/PropertyAndElement.h"    // JS_DefineFunction
 #include "js/StableStringChars.h"
 #include "vm/BigIntType.h"
 #include "vm/FunctionFlags.h"  // js::FunctionFlags
 #include "vm/JSAtom.h"
 #include "vm/JSObject.h"
 #include "vm/ModuleBuilder.h"  // js::ModuleBuilder
 #include "vm/PlainObject.h"    // js::PlainObject
 #include "vm/RegExpObject.h"
--- a/js/src/builtin/String.cpp
+++ b/js/src/builtin/String.cpp
@@ -30,16 +30,17 @@
 #include "builtin/RegExp.h"
 #include "jit/InlinableNatives.h"
 #include "js/Conversions.h"
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/friend/StackLimits.h"    // js::AutoCheckRecursionLimit
 #if !JS_HAS_INTL_API
 #  include "js/LocaleSensitive.h"
 #endif
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions
 #include "js/PropertySpec.h"
 #include "js/StableStringChars.h"
 #include "js/UniquePtr.h"
 #if JS_HAS_INTL_API
 #  include "unicode/uchar.h"
 #  include "unicode/unorm2.h"
 #  include "unicode/ustring.h"
 #  include "unicode/utypes.h"
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -73,16 +73,17 @@
 #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/HashTable.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
 #include "js/SourceText.h"
 #include "js/StableStringChars.h"
 #include "js/String.h"  // JS::GetLinearStringLength, JS::StringToLinearString
 #include "js/StructuredClone.h"
 #include "js/UbiNode.h"
 #include "js/UbiNodeBreadthFirst.h"
--- a/js/src/builtin/TestingUtility.cpp
+++ b/js/src/builtin/TestingUtility.cpp
@@ -3,26 +3,26 @@
  * 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/TestingUtility.h"
 
 #include <stdint.h>  // uint32_t
 
-#include "jsapi.h"                 // JS_GetProperty
 #include "js/CharacterEncoding.h"  // JS_EncodeStringToLatin1
 #include "js/CompileOptions.h"     // JS::CompileOptions
 #include "js/Conversions.h"  // JS::ToBoolean, JS::ToString, JS::ToUint32, JS::ToInt32
-#include "js/RootingAPI.h"  // JS::Rooted, JS::Handle
-#include "js/Utility.h"     // JS::UniqueChars
-#include "js/Value.h"       // JS::Value
-#include "vm/JSContext.h"   // JSContext
-#include "vm/JSObject.h"    // JSObject
-#include "vm/StringType.h"  // JSString
+#include "js/PropertyAndElement.h"  // JS_GetProperty
+#include "js/RootingAPI.h"          // JS::Rooted, JS::Handle
+#include "js/Utility.h"             // JS::UniqueChars
+#include "js/Value.h"               // JS::Value
+#include "vm/JSContext.h"           // JSContext
+#include "vm/JSObject.h"            // JSObject
+#include "vm/StringType.h"          // JSString
 
 bool js::ParseCompileOptions(JSContext* cx, JS::CompileOptions& options,
                              JS::Handle<JSObject*> opts,
                              UniqueChars* fileNameBytes) {
   JS::Rooted<JS::Value> v(cx);
   JS::Rooted<JSString*> s(cx);
 
   if (!JS_GetProperty(cx, opts, "isRunOnce", &v)) {
--- a/js/src/builtin/intl/DateTimeFormat.cpp
+++ b/js/src/builtin/intl/DateTimeFormat.cpp
@@ -26,16 +26,17 @@
 #include "builtin/intl/SharedIntlData.h"
 #include "builtin/intl/TimeZoneDataGenerated.h"
 #include "gc/FreeOp.h"
 #include "js/CharacterEncoding.h"
 #include "js/Date.h"
 #include "js/experimental/Intl.h"     // JS::AddMozDateTimeFormatConstructor
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/GCAPI.h"
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions, JS_DefineProperties
 #include "js/PropertySpec.h"
 #include "js/StableStringChars.h"
 #include "unicode/udat.h"
 #include "unicode/udateintervalformat.h"
 #include "unicode/uenum.h"
 #include "unicode/ufieldpositer.h"
 #include "unicode/uloc.h"
 #include "unicode/utypes.h"
--- a/js/src/builtin/intl/DisplayNames.cpp
+++ b/js/src/builtin/intl/DisplayNames.cpp
@@ -30,16 +30,17 @@
 #include "gc/AllocKind.h"
 #include "gc/FreeOp.h"
 #include "gc/Rooting.h"
 #include "js/CallArgs.h"
 #include "js/Class.h"
 #include "js/experimental/Intl.h"     // JS::AddMozDisplayNamesConstructor
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/GCVector.h"
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions, JS_DefineProperties
 #include "js/PropertyDescriptor.h"
 #include "js/PropertySpec.h"
 #include "js/Result.h"
 #include "js/RootingAPI.h"
 #include "js/TypeDecls.h"
 #include "js/Utility.h"
 #include "unicode/ucal.h"
 #include "unicode/ucurr.h"
--- 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/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/Object.h"  // JS::GetPrivate, JS::GetReservedSlot, JS::SetPrivate
+#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"
 #include "util/Text.h"
 #include "util/Unicode.h"
--- a/js/src/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -8,17 +8,18 @@
 
 #include "prerror.h"
 #include "prlink.h"
 
 #include "ctypes/CTypes.h"
 #include "js/CharacterEncoding.h"
 #include "js/experimental/CTypes.h"  // JS::CTypesCallbacks
 #include "js/MemoryFunctions.h"
-#include "js/Object.h"  // JS::GetReservedSlot
+#include "js/Object.h"              // JS::GetReservedSlot
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions
 #include "js/PropertySpec.h"
 #include "js/StableStringChars.h"
 #include "vm/JSObject.h"
 
 using JS::AutoStableStringChars;
 
 namespace js::ctypes {
 
--- a/js/src/debugger/Debugger.cpp
+++ b/js/src/debugger/Debugger.cpp
@@ -62,16 +62,17 @@
 #include "jit/JSJitFrameIter.h"       // for InlineFrameIterator
 #include "jit/RematerializedFrame.h"  // for RematerializedFrame
 #include "js/Conversions.h"           // for ToBoolean, ToUint32
 #include "js/Debug.h"                 // for Builder::Object, Builder
 #include "js/friend/ErrorMessages.h"  // for GetErrorMessage, JSMSG_*
 #include "js/GCAPI.h"                 // for GarbageCollectionEvent
 #include "js/HeapAPI.h"               // for ExposeObjectToActiveJS
 #include "js/Promise.h"               // for AutoDebuggerJobQueueInterruption
+#include "js/PropertyAndElement.h"    // for JS_GetProperty
 #include "js/Proxy.h"                 // for PropertyDescriptor
 #include "js/SourceText.h"            // for SourceOwnership, SourceText
 #include "js/StableStringChars.h"     // for AutoStableStringChars
 #include "js/UbiNode.h"               // for Node, RootList, Edge
 #include "js/UbiNodeBreadthFirst.h"   // for BreadthFirst
 #include "js/Warnings.h"              // for AutoSuppressWarningReporter
 #include "js/Wrapper.h"               // for CheckedUnwrapStatic
 #include "util/Text.h"                // for DuplicateString, js_strlen
--- a/js/src/debugger/Object.cpp
+++ b/js/src/debugger/Object.cpp
@@ -29,17 +29,18 @@
 #include "gc/Rooting.h"          // for RootedDebuggerObject
 #include "gc/Tracer.h"  // for TraceManuallyBarrieredCrossCompartmentEdge
 #include "js/CompilationAndEvaluation.h"  //  for Compile
 #include "js/Conversions.h"               // for ToObject
 #include "js/friend/ErrorMessages.h"      // for GetErrorMessage, JSMSG_*
 #include "js/friend/WindowProxy.h"  // for IsWindow, IsWindowProxy, ToWindowIfWindowProxy
 #include "js/HeapAPI.h"             // for IsInsideNursery
 #include "js/Promise.h"             // for PromiseState
-#include "js/Proxy.h"               // for PropertyDescriptor
+#include "js/PropertyAndElement.h"       // for JS_GetProperty
+#include "js/Proxy.h"                    // for PropertyDescriptor
 #include "js/SourceText.h"               // for SourceText
 #include "js/StableStringChars.h"        // for AutoStableStringChars
 #include "js/String.h"                   // for JS::StringHasLatin1Chars
 #include "proxy/ScriptedProxyHandler.h"  // for ScriptedProxyHandler
 #include "vm/ArgumentsObject.h"          // for ARGS_LENGTH_MAX
 #include "vm/ArrayObject.h"              // for ArrayObject
 #include "vm/AsyncFunction.h"            // for AsyncGeneratorObject
 #include "vm/AsyncIteration.h"           // for AsyncFunctionGeneratorObject
--- a/js/src/fuzz-tests/testWasm.cpp
+++ b/js/src/fuzz-tests/testWasm.cpp
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ScopeExit.h"
 
 #include "jsapi.h"
 #include "jspubtd.h"
 
 #include "fuzz-tests/tests.h"
+#include "js/PropertyAndElement.h"  // JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_HasProperty, JS_SetProperty
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/TypedArrayObject.h"
 
 #include "wasm/WasmCompile.h"
 #include "wasm/WasmCraneliftCompile.h"
 #include "wasm/WasmIonCompile.h"
 #include "wasm/WasmJS.h"
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -227,19 +227,20 @@
 #include "gc/Policy.h"
 #include "gc/WeakMap.h"
 #include "jit/BaselineJIT.h"
 #include "jit/JitCode.h"
 #include "jit/JitcodeMap.h"
 #include "jit/JitRealm.h"
 #include "jit/JitRuntime.h"
 #include "jit/JitZone.h"
-#include "jit/MacroAssembler.h"  // js::jit::CodeAlignment
-#include "js/HeapAPI.h"          // JS::GCCellPtr
-#include "js/Object.h"           // JS::GetClass
+#include "jit/MacroAssembler.h"     // js::jit::CodeAlignment
+#include "js/HeapAPI.h"             // JS::GCCellPtr
+#include "js/Object.h"              // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/SliceBudget.h"
 #include "proxy/DeadObjectProxy.h"
 #include "util/DifferentialTesting.h"
 #include "util/Poison.h"
 #include "util/Windows.h"
 #include "vm/BigIntType.h"
 #include "vm/GeckoProfiler.h"
 #include "vm/GetterSetter.h"
--- 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/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
 #include <string.h>  // strlen
--- a/js/src/jsapi-tests/testAddPropertyPropcache.cpp
+++ b/js/src/jsapi-tests/testAddPropertyPropcache.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/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty
 #include "jsapi-tests/tests.h"
 
 static int callCount = 0;
 
 static bool AddProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                         JS::HandleValue v) {
   callCount++;
   return true;
--- a/js/src/jsapi-tests/testArrayBuffer.cpp
+++ b/js/src/jsapi-tests/testArrayBuffer.cpp
@@ -6,16 +6,17 @@
 
 #include "builtin/TestingFunctions.h"
 #include "js/Array.h"        // JS::NewArrayObject
 #include "js/ArrayBuffer.h"  // JS::{GetArrayBuffer{ByteLength,Data},IsArrayBufferObject,NewArrayBuffer{,WithContents},StealArrayBufferContents}
 #include "js/Exception.h"
 #include "js/experimental/TypedData.h"  // JS_New{Int32,Uint8}ArrayWithBuffer
 #include "js/friend/ErrorMessages.h"    // JSMSG_*
 #include "js/MemoryFunctions.h"
+#include "js/PropertyAndElement.h"  // JS_GetElement, JS_GetProperty, JS_SetElement
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testArrayBuffer_bug720949_steal) {
   static const unsigned NUM_TEST_BUFFERS = 2;
   static const unsigned MAGIC_VALUE_1 = 3;
   static const unsigned MAGIC_VALUE_2 = 17;
 
   JS::RootedObject buf_len1(cx), buf_len200(cx);
--- a/js/src/jsapi-tests/testArrayBufferView.cpp
+++ b/js/src/jsapi-tests/testArrayBufferView.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:
  */
 
 #include "jsfriendapi.h"
 
 #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/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"
 
 using namespace js;
--- a/js/src/jsapi-tests/testCallArgs.cpp
+++ b/js/src/jsapi-tests/testCallArgs.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::Evaluate
+#include "js/PropertyAndElement.h"        // JS_DefineFunction
 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
 #include "jsapi-tests/tests.h"
 
 static bool CustomNative(JSContext* cx, unsigned argc, JS::Value* vp) {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
 
   MOZ_RELEASE_ASSERT(!JS_IsExceptionPending(cx));
 
--- a/js/src/jsapi-tests/testChromeBuffer.cpp
+++ b/js/src/jsapi-tests/testChromeBuffer.cpp
@@ -3,17 +3,18 @@
  * 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
 #include "js/ContextOptions.h"
-#include "js/SourceText.h"  // JS::Source{Ownership,Text}
+#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",
                                      JSCLASS_IS_GLOBAL | JSCLASS_GLOBAL_FLAGS,
                                      &JS::DefaultGlobalClassOps};
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/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.
   CHECK(JS_DefineDebuggerObject(cx, global));
--- a/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp
+++ b/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/PropertyDescriptor.h"  // JS_GetOwnPropertyDescriptor
 #include "jsapi-tests/tests.h"
 
 static bool NativeGetterSetter(JSContext* cx, unsigned argc, JS::Value* vp) {
   return true;
 }
 
 BEGIN_TEST(testDefineGetterSetterNonEnumerable) {
--- a/js/src/jsapi-tests/testDefineProperty.cpp
+++ b/js/src/jsapi-tests/testDefineProperty.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/PropertyAndElement.h"  // JS_DefineProperty
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testDefineProperty_bug564344) {
   JS::RootedValue x(cx);
   EVAL(
       "function f() {}\n"
       "var x = {p: f};\n"
       "x.p();  // brand x's scope\n"
--- a/js/src/jsapi-tests/testException.cpp
+++ b/js/src/jsapi-tests/testException.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/PropertyAndElement.h"  // JS_GetProperty
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testException_bug860435) {
   JS::RootedValue fun(cx);
 
   EVAL("ReferenceError", &fun);
   CHECK(fun.isObject());
 
--- a/js/src/jsapi-tests/testExecuteInJSMEnvironment.cpp
+++ b/js/src/jsapi-tests/testExecuteInJSMEnvironment.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 "js/CompilationAndEvaluation.h"  // JS::Compile
 #include "js/friend/JSMEnvironment.h"  // JS::ExecuteInJSMEnvironment, JS::GetJSMEnvironmentOfScriptedCaller, JS::NewJSMEnvironment
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions, JS_GetProperty, JS_SetProperty
 #include "js/PropertySpec.h"
 #include "js/SourceText.h"  // JS::Source{Ownership,Text}
 #include "jsapi-tests/tests.h"
 #include "util/Text.h"
 #include "vm/EnvironmentObject.h"
 #include "vm/EnvironmentObject-inl.h"
 
 BEGIN_TEST(testExecuteInJSMEnvironment_Basic) {
--- a/js/src/jsapi-tests/testForwardSetProperty.cpp
+++ b/js/src/jsapi-tests/testForwardSetProperty.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/PropertyAndElement.h"  // JS_ForwardSetPropertyTo
 #include "jsapi-tests/tests.h"
 
 using namespace JS;
 
 BEGIN_TEST(testForwardSetProperty) {
   RootedValue v1(cx);
   EVAL(
       "var foundValue; \n"
--- 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/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/testFunctionNonSyntactic.cpp
+++ b/js/src/jsapi-tests/testFunctionNonSyntactic.cpp
@@ -7,16 +7,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 "jsfriendapi.h"
 
 #include "js/CompilationAndEvaluation.h"  // JS::CompileFunction
+#include "js/PropertyAndElement.h"        // JS_DefineProperty
 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
 #include "jsapi-tests/tests.h"
 #include "util/Text.h"
 #include "vm/JSFunction.h"  // JSFunction
 #include "vm/ScopeKind.h"   // ScopeKind
 
 using namespace js;
 
--- a/js/src/jsapi-tests/testFunctionProperties.cpp
+++ b/js/src/jsapi-tests/testFunctionProperties.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/PropertyAndElement.h"  // JS_GetProperty
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testFunctionProperties) {
   JS::RootedValue x(cx);
   EVAL("(function f() {})", &x);
 
   JS::RootedObject obj(cx, x.toObjectOrNull());
 
--- a/js/src/jsapi-tests/testGCExactRooting.cpp
+++ b/js/src/jsapi-tests/testGCExactRooting.cpp
@@ -6,16 +6,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Maybe.h"
 
 #include "ds/TraceableFifo.h"
 #include "gc/Policy.h"
 #include "js/GCHashTable.h"
 #include "js/GCVector.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty, JS_SetProperty
 #include "js/RootingAPI.h"
 
 #include "jsapi-tests/tests.h"
 
 using namespace js;
 
 using mozilla::Maybe;
 using mozilla::Some;
--- a/js/src/jsapi-tests/testGCGrayMarking.cpp
+++ b/js/src/jsapi-tests/testGCGrayMarking.cpp
@@ -4,16 +4,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 <algorithm>
 
 #include "gc/WeakMap.h"
 #include "gc/Zone.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById
 #include "js/Proxy.h"
 #include "jsapi-tests/tests.h"
 
 using namespace js;
 using namespace js::gc;
 
 static constexpr CellColor AllCellColors[] = {CellColor::White, CellColor::Gray,
                                               CellColor::Black};
--- a/js/src/jsapi-tests/testGCHeapBarriers.cpp
+++ b/js/src/jsapi-tests/testGCHeapBarriers.cpp
@@ -4,17 +4,18 @@
 /* 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/Maybe.h"
 #include "mozilla/UniquePtr.h"
 
 #include "gc/GCRuntime.h"
-#include "js/ArrayBuffer.h"  // JS::NewArrayBuffer
+#include "js/ArrayBuffer.h"         // JS::NewArrayBuffer
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty
 #include "js/RootingAPI.h"
 #include "jsapi-tests/tests.h"
 #include "vm/Runtime.h"
 
 #include "vm/JSContext-inl.h"
 
 using namespace js;
 
--- 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/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;
 
 static bool ConstructCCW(JSContext* cx, const JSClass* globalClasp,
--- a/js/src/jsapi-tests/testJSEvaluateScript.cpp
+++ b/js/src/jsapi-tests/testJSEvaluateScript.cpp
@@ -1,13 +1,14 @@
 /* -*- 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/CompilationAndEvaluation.h"
+#include "js/PropertyAndElement.h"  // JS_AlreadyHasOwnProperty, JS_HasProperty
 #include "js/SourceText.h"
 #include "jsapi-tests/tests.h"
 #include "util/Text.h"
 
 BEGIN_TEST(testJSEvaluateScript) {
   JS::RootedObject obj(cx, JS_NewPlainObject(cx));
   CHECK(obj);
 
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -1,17 +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/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById, JS_GetProperty
 #include "jsapi-tests/tests.h"
-
 #include "vm/JSFunction.h"  // for js::IsInternalFunctionObject
 
 #include "vm/JSObject-inl.h"
 
 BEGIN_TEST(testLookup_bug522590) {
   // Define a function that makes method-bearing objects.
   JS::RootedValue x(cx);
   EXEC("function mkobj() { return {f: function () {return 2;}} }");
--- a/js/src/jsapi-tests/testNewObject.cpp
+++ b/js/src/jsapi-tests/testNewObject.cpp
@@ -1,17 +1,18 @@
 /* -*- 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/Array.h"   // JS::GetArrayLength, JS::IsArrayObject
-#include "js/Object.h"  // JS::GetClass
+#include "js/Array.h"               // JS::GetArrayLength, JS::IsArrayObject
+#include "js/Object.h"              // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_GetElement, JS_SetElement
 #include "jsapi-tests/tests.h"
 
 static bool constructHook(JSContext* cx, unsigned argc, JS::Value* vp) {
   JS::CallArgs args = CallArgsFromVp(argc, vp);
 
   // Check that arguments were passed properly from JS_New.
 
   JS::RootedObject obj(cx, JS_NewPlainObject(cx));
--- a/js/src/jsapi-tests/testParseJSON.cpp
+++ b/js/src/jsapi-tests/testParseJSON.cpp
@@ -9,16 +9,17 @@
 #include <string.h>
 
 #include "js/Array.h"  // JS::IsArrayObject
 #include "js/Exception.h"
 #include "js/friend/ErrorMessages.h"  // JSMSG_*
 #include "js/JSON.h"
 #include "js/MemoryFunctions.h"
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 #include "jsapi-tests/tests.h"
 
 using namespace js;
 
 class AutoInflatedString {
   JSContext* const cx;
   char16_t* chars_;
   size_t length_;
--- a/js/src/jsapi-tests/testPropCache.cpp
+++ b/js/src/jsapi-tests/testPropCache.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/PropertyAndElement.h"  // JS_DefineObject
 #include "jsapi-tests/tests.h"
 
 static int g_counter;
 
 static bool CounterAdd(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                        JS::HandleValue v) {
   g_counter++;
   return true;
--- a/js/src/jsapi-tests/testReadableStream.cpp
+++ b/js/src/jsapi-tests/testReadableStream.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 "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/experimental/TypedData.h"  // JS_GetArrayBufferViewData, JS_IsUint8Array
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_HasProperty, JS_SetProperty
 #include "js/Stream.h"
 #include "jsapi-tests/tests.h"
 
 using namespace JS;
 
 char testBufferData[] =
     "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
--- a/js/src/jsapi-tests/testResolveRecursion.cpp
+++ b/js/src/jsapi-tests/testResolveRecursion.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/Object.h"  // JS::GetPrivate, JS::SetPrivate
+#include "js/Object.h"              // JS::GetPrivate, JS::SetPrivate
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById
 #include "jsapi-tests/tests.h"
 
 /*
  * Test that resolve hook recursion for the same object and property is
  * prevented.
  */
 BEGIN_TEST(testResolveRecursion) {
   static const JSClassOps my_resolve_classOps = {
--- a/js/src/jsapi-tests/testScriptObject.cpp
+++ b/js/src/jsapi-tests/testScriptObject.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::Compile{,Utf8{File,Path}}
+#include "js/PropertyAndElement.h"        // JS_SetProperty
 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
 #include "jsapi-tests/tests.h"
 
 struct ScriptObjectFixture : public JSAPITest {
   static const int code_size;
   static const char code[];
   static char16_t uc_code[];
 
--- a/js/src/jsapi-tests/testSetProperty.cpp
+++ b/js/src/jsapi-tests/testSetProperty.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/Object.h"  // JS::GetClass
+#include "js/Object.h"              // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testSetProperty_InheritedGlobalSetter) {
   // This is a JSAPI test because jsapi-test globals can be set up to not have
   // a resolve hook and therefore can use the property cache in some cases
   // where the shell can't.
   MOZ_RELEASE_ASSERT(!JS::GetClass(global)->getResolve());
 
--- a/js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.cpp
+++ b/js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.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 "jsfriendapi.h"
 
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/Proxy.h"
 
 #include "jsapi-tests/tests.h"
 
 using namespace js;
 using namespace JS;
 
 class CustomProxyHandler : public Wrapper {
--- a/js/src/jsapi-tests/testSlowScript.cpp
+++ b/js/src/jsapi-tests/testSlowScript.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/PropertyAndElement.h"  // JS_DefineFunction
 #include "jsapi-tests/tests.h"
 
 static bool InterruptCallback(JSContext* cx) { return false; }
 
 static unsigned sRemain;
 
 static bool RequestInterruptCallback(JSContext* cx, unsigned argc, jsval* vp) {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
--- a/js/src/jsapi-tests/testStencil.cpp
+++ b/js/src/jsapi-tests/testStencil.cpp
@@ -8,16 +8,17 @@
 #include <string.h>
 
 #include "jsapi.h"
 
 #include "js/CompilationAndEvaluation.h"
 #include "js/experimental/JSStencil.h"
 #include "js/Modules.h"
 #include "js/OffThreadScriptCompilation.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_HasOwnProperty, JS_SetProperty
 #include "js/Transcoding.h"
 #include "jsapi-tests/tests.h"
 #include "vm/HelperThreads.h"  // js::RunPendingSourceCompressions
 #include "vm/Monitor.h"        // js::Monitor, js::AutoLockMonitor
 
 BEGIN_TEST(testStencil_Basic) {
   const char* chars =
       "function f() { return 42; }"
--- 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/PropertyAndElement.h"  // JS_GetProperty, JS_SetProperty
 #include "js/StructuredClone.h"
 
 #include "jsapi-tests/tests.h"
 
 using namespace js;
 
 BEGIN_TEST(testStructuredClone_object) {
   JS::RootedObject g1(cx, createGlobal());
--- a/js/src/jsapi-tests/testTypedArrays.cpp
+++ b/js/src/jsapi-tests/testTypedArrays.cpp
@@ -4,16 +4,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 "jsfriendapi.h"
 
 #include "js/ArrayBuffer.h"  // JS::{NewArrayBuffer,IsArrayBufferObject,GetArrayBuffer{ByteLength,Data}}
 #include "js/experimental/TypedData.h"  // JS_GetArrayBufferViewBuffer, JS_GetTypedArray{Length,ByteOffset,ByteLength}, JS_Get{{Ui,I}nt{8,16,32},Float{32,64},Uint8Clamped}ArrayData, JS_IsTypedArrayObject, JS_New{{Ui,I}nt{8,16,32},Float{32,64},Uint8Clamped}Array{,FromArray,WithBuffer}
+#include "js/PropertyAndElement.h"      // JS_GetElement, JS_SetElement
 #include "js/SharedArrayBuffer.h"  // JS::{NewSharedArrayBuffer,GetSharedArrayBufferData}
 #include "jsapi-tests/tests.h"
 #include "vm/Realm.h"
 
 using namespace js;
 
 BEGIN_TEST(testTypedArrays) {
   bool ok = true;
--- a/js/src/jsapi-tests/testWeakMap.cpp
+++ b/js/src/jsapi-tests/testWeakMap.cpp
@@ -1,17 +1,18 @@
 /* -*- 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 "gc/Zone.h"
-#include "js/Array.h"  // JS::GetArrayLength
+#include "js/Array.h"               // JS::GetArrayLength
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "jsapi-tests/tests.h"
 #include "vm/Realm.h"
 
 using namespace js;
 
 JSObject* keyDelegate = nullptr;
 
 BEGIN_TEST(testWeakMap_basicOperations) {
--- a/js/src/jsapi-tests/testWindowNonConfigurable.cpp
+++ b/js/src/jsapi-tests/testWindowNonConfigurable.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/PropertyAndElement.h"  // JS_DefineProperty
 #include "jsapi-tests/tests.h"
 
 static bool windowProxy_defineProperty(JSContext* cx, JS::HandleObject obj,
                                        JS::HandleId id,
                                        JS::Handle<JS::PropertyDescriptor> desc,
                                        JS::ObjectOpResult& result) {
   if (desc.hasConfigurable() && !desc.configurable()) {
     result.failCantDefineWindowNonConfigurable();
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -8,16 +8,17 @@
 
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include <stdio.h>
 
 #include "js/ArrayBuffer.h"
 #include "js/CompilationAndEvaluation.h"  // JS::Evaluate
 #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) {
   if (maybeReusableContext && reuseGlobal) {
     cx = maybeReusableContext;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -920,17 +920,17 @@ JS_PUBLIC_API bool JS_ResolveStandardCla
   if (!id.isAtom()) {
     return true;
   }
 
   /* Check whether we're resolving 'undefined', and define it if so. */
   JSAtom* idAtom = id.toAtom();
   if (idAtom == cx->names().undefined) {
     *resolved = true;
-    return DefineDataProperty(
+    return js::DefineDataProperty(
         cx, global, id, UndefinedHandleValue,
         JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_RESOLVING);
   }
 
   // Resolve a "globalThis" self-referential property if necessary.
   if (idAtom == cx->names().globalThis) {
     return GlobalObject::maybeResolveGlobalThis(cx, global, resolved);
   }
@@ -1955,694 +1955,16 @@ JS_PUBLIC_API bool JS_PreventExtensions(
 }
 
 JS_PUBLIC_API bool JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj,
                                             bool* succeeded) {
   cx->check(obj);
   return SetImmutablePrototype(cx, obj, succeeded);
 }
 
-static bool DefinePropertyByDescriptor(JSContext* cx, HandleObject obj,
-                                       HandleId id,
-                                       Handle<PropertyDescriptor> desc,
-                                       ObjectOpResult& result) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id, desc);
-  return DefineProperty(cx, obj, id, desc, result);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id,
-                                         Handle<PropertyDescriptor> desc,
-                                         ObjectOpResult& result) {
-  return DefinePropertyByDescriptor(cx, obj, id, desc, result);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id,
-                                         Handle<PropertyDescriptor> desc) {
-  ObjectOpResult result;
-  return DefinePropertyByDescriptor(cx, obj, id, desc, result) &&
-         result.checkStrict(cx, obj, id);
-}
-
-static bool DefineAccessorPropertyById(JSContext* cx, HandleObject obj,
-                                       HandleId id, HandleObject getter,
-                                       HandleObject setter, unsigned attrs) {
-  // JSPROP_READONLY has no meaning when accessors are involved. Ideally we'd
-  // throw if this happens, but we've accepted it for long enough that it's
-  // not worth trying to make callers change their ways. Just flip it off on
-  // its way through the API layer so that we can enforce this internally.
-  attrs &= ~JSPROP_READONLY;
-
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id, getter, setter);
-
-  return js::DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
-}
-
-static bool DefineAccessorPropertyById(JSContext* cx, HandleObject obj,
-                                       HandleId id, const JSNativeWrapper& get,
-                                       const JSNativeWrapper& set,
-                                       unsigned attrs) {
-  // Getter/setter are both possibly-null JSNatives. Wrap them in JSFunctions.
-
-  RootedFunction getter(cx);
-  if (get.op) {
-    RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Get));
-    if (!atom) {
-      return false;
-    }
-    getter = NewNativeFunction(cx, get.op, 0, atom);
-    if (!getter) {
-      return false;
-    }
-
-    if (get.info) {
-      getter->setJitInfo(get.info);
-    }
-  }
-
-  RootedFunction setter(cx);
-  if (set.op) {
-    RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Set));
-    if (!atom) {
-      return false;
-    }
-    setter = NewNativeFunction(cx, set.op, 1, atom);
-    if (!setter) {
-      return false;
-    }
-
-    if (set.info) {
-      setter->setJitInfo(set.info);
-    }
-  }
-
-  return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
-}
-
-static bool DefineDataPropertyById(JSContext* cx, HandleObject obj, HandleId id,
-                                   HandleValue value, unsigned attrs) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id, value);
-
-  return js::DefineDataProperty(cx, obj, id, value, attrs);
-}
-
-/*
- * Wrapper functions to create wrappers with no corresponding JSJitInfo from API
- * function arguments.
- */
-static JSNativeWrapper NativeOpWrapper(Native native) {
-  JSNativeWrapper ret;
-  ret.op = native;
-  ret.info = nullptr;
-  return ret;
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, HandleValue value,
-                                         unsigned attrs) {
-  return DefineDataPropertyById(cx, obj, id, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, Native getter,
-                                         Native setter, unsigned attrs) {
-  return DefineAccessorPropertyById(cx, obj, id, NativeOpWrapper(getter),
-                                    NativeOpWrapper(setter), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, HandleObject getter,
-                                         HandleObject setter, unsigned attrs) {
-  return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, HandleObject valueArg,
-                                         unsigned attrs) {
-  RootedValue value(cx, ObjectValue(*valueArg));
-  return DefineDataPropertyById(cx, obj, id, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, HandleString valueArg,
-                                         unsigned attrs) {
-  RootedValue value(cx, StringValue(valueArg));
-  return DefineDataPropertyById(cx, obj, id, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, int32_t valueArg,
-                                         unsigned attrs) {
-  Value value = Int32Value(valueArg);
-  return DefineDataPropertyById(cx, obj, id,
-                                HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, uint32_t valueArg,
-                                         unsigned attrs) {
-  Value value = NumberValue(valueArg);
-  return DefineDataPropertyById(cx, obj, id,
-                                HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, double valueArg,
-                                         unsigned attrs) {
-  Value value = NumberValue(valueArg);
-  return DefineDataPropertyById(cx, obj, id,
-                                HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-static bool DefineDataProperty(JSContext* cx, HandleObject obj,
-                               const char* name, HandleValue value,
-                               unsigned attrs) {
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-
-  return DefineDataPropertyById(cx, obj, id, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, HandleValue value,
-                                     unsigned attrs) {
-  return DefineDataProperty(cx, obj, name, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, Native getter,
-                                     Native setter, unsigned attrs) {
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return DefineAccessorPropertyById(cx, obj, id, NativeOpWrapper(getter),
-                                    NativeOpWrapper(setter), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, HandleObject getter,
-                                     HandleObject setter, unsigned attrs) {
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-
-  return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, HandleObject valueArg,
-                                     unsigned attrs) {
-  RootedValue value(cx, ObjectValue(*valueArg));
-  return DefineDataProperty(cx, obj, name, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, HandleString valueArg,
-                                     unsigned attrs) {
-  RootedValue value(cx, StringValue(valueArg));
-  return DefineDataProperty(cx, obj, name, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, int32_t valueArg,
-                                     unsigned attrs) {
-  Value value = Int32Value(valueArg);
-  return DefineDataProperty(cx, obj, name,
-                            HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, uint32_t valueArg,
-                                     unsigned attrs) {
-  Value value = NumberValue(valueArg);
-  return DefineDataProperty(cx, obj, name,
-                            HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, double valueArg,
-                                     unsigned attrs) {
-  Value value = NumberValue(valueArg);
-  return DefineDataProperty(cx, obj, name,
-                            HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-#define AUTO_NAMELEN(s, n) (((n) == (size_t)-1) ? js_strlen(s) : (n))
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       Handle<PropertyDescriptor> desc,
-                                       ObjectOpResult& result) {
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return DefinePropertyByDescriptor(cx, obj, id, desc, result);
-}
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       Handle<PropertyDescriptor> desc) {
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  ObjectOpResult result;
-  return DefinePropertyByDescriptor(cx, obj, id, desc, result) &&
-         result.checkStrict(cx, obj, id);
-}
-
-static bool DefineUCDataProperty(JSContext* cx, HandleObject obj,
-                                 const char16_t* name, size_t namelen,
-                                 HandleValue value, unsigned attrs) {
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return DefineDataPropertyById(cx, obj, id, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       HandleValue value, unsigned attrs) {
-  return DefineUCDataProperty(cx, obj, name, namelen, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       HandleObject getter, HandleObject setter,
-                                       unsigned attrs) {
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       HandleObject valueArg, unsigned attrs) {
-  RootedValue value(cx, ObjectValue(*valueArg));
-  return DefineUCDataProperty(cx, obj, name, namelen, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       HandleString valueArg, unsigned attrs) {
-  RootedValue value(cx, StringValue(valueArg));
-  return DefineUCDataProperty(cx, obj, name, namelen, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       int32_t valueArg, unsigned attrs) {
-  Value value = Int32Value(valueArg);
-  return DefineUCDataProperty(cx, obj, name, namelen,
-                              HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       uint32_t valueArg, unsigned attrs) {
-  Value value = NumberValue(valueArg);
-  return DefineUCDataProperty(cx, obj, name, namelen,
-                              HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       double valueArg, unsigned attrs) {
-  Value value = NumberValue(valueArg);
-  return DefineUCDataProperty(cx, obj, name, namelen,
-                              HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-static bool DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index,
-                              HandleValue value, unsigned attrs) {
-  cx->check(obj, value);
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  RootedId id(cx);
-  if (!IndexToId(cx, index, &id)) {
-    return false;
-  }
-  return DefineDataPropertyById(cx, obj, id, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index, HandleValue value,
-                                    unsigned attrs) {
-  return ::DefineDataElement(cx, obj, index, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index, HandleObject getter,
-                                    HandleObject setter, unsigned attrs) {
-  RootedId id(cx);
-  if (!IndexToId(cx, index, &id)) {
-    return false;
-  }
-  return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index, HandleObject valueArg,
-                                    unsigned attrs) {
-  RootedValue value(cx, ObjectValue(*valueArg));
-  return ::DefineDataElement(cx, obj, index, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index, HandleString valueArg,
-                                    unsigned attrs) {
-  RootedValue value(cx, StringValue(valueArg));
-  return ::DefineDataElement(cx, obj, index, value, attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index, int32_t valueArg,
-                                    unsigned attrs) {
-  Value value = Int32Value(valueArg);
-  return ::DefineDataElement(cx, obj, index,
-                             HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index, uint32_t valueArg,
-                                    unsigned attrs) {
-  Value value = NumberValue(valueArg);
-  return ::DefineDataElement(cx, obj, index,
-                             HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index, double valueArg,
-                                    unsigned attrs) {
-  Value value = NumberValue(valueArg);
-  return ::DefineDataElement(cx, obj, index,
-                             HandleValue::fromMarkedLocation(&value), attrs);
-}
-
-JS_PUBLIC_API bool JS_HasPropertyById(JSContext* cx, HandleObject obj,
-                                      HandleId id, bool* foundp) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id);
-
-  return HasProperty(cx, obj, id, foundp);
-}
-
-JS_PUBLIC_API bool JS_HasProperty(JSContext* cx, HandleObject obj,
-                                  const char* name, bool* foundp) {
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_HasPropertyById(cx, obj, id, foundp);
-}
-
-JS_PUBLIC_API bool JS_HasUCProperty(JSContext* cx, HandleObject obj,
-                                    const char16_t* name, size_t namelen,
-                                    bool* foundp) {
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_HasPropertyById(cx, obj, id, foundp);
-}
-
-JS_PUBLIC_API bool JS_HasElement(JSContext* cx, HandleObject obj,
-                                 uint32_t index, bool* foundp) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  RootedId id(cx);
-  if (!IndexToId(cx, index, &id)) {
-    return false;
-  }
-  return JS_HasPropertyById(cx, obj, id, foundp);
-}
-
-JS_PUBLIC_API bool JS_HasOwnPropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, bool* foundp) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id);
-
-  return HasOwnProperty(cx, obj, id, foundp);
-}
-
-JS_PUBLIC_API bool JS_HasOwnProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, bool* foundp) {
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_HasOwnPropertyById(cx, obj, id, foundp);
-}
-
-JS_PUBLIC_API bool JS_ForwardGetPropertyTo(JSContext* cx, HandleObject obj,
-                                           HandleId id, HandleValue receiver,
-                                           MutableHandleValue vp) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id, receiver);
-
-  return GetProperty(cx, obj, receiver, id, vp);
-}
-
-JS_PUBLIC_API bool JS_ForwardGetElementTo(JSContext* cx, HandleObject obj,
-                                          uint32_t index, HandleObject receiver,
-                                          MutableHandleValue vp) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj);
-
-  return GetElement(cx, obj, receiver, index, vp);
-}
-
-JS_PUBLIC_API bool JS_GetPropertyById(JSContext* cx, HandleObject obj,
-                                      HandleId id, MutableHandleValue vp) {
-  RootedValue receiver(cx, ObjectValue(*obj));
-  return JS_ForwardGetPropertyTo(cx, obj, id, receiver, vp);
-}
-
-JS_PUBLIC_API bool JS_GetProperty(JSContext* cx, HandleObject obj,
-                                  const char* name, MutableHandleValue vp) {
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_GetPropertyById(cx, obj, id, vp);
-}
-
-JS_PUBLIC_API bool JS_GetUCProperty(JSContext* cx, HandleObject obj,
-                                    const char16_t* name, size_t namelen,
-                                    MutableHandleValue vp) {
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_GetPropertyById(cx, obj, id, vp);
-}
-
-JS_PUBLIC_API bool JS_GetElement(JSContext* cx, HandleObject objArg,
-                                 uint32_t index, MutableHandleValue vp) {
-  return JS_ForwardGetElementTo(cx, objArg, index, objArg, vp);
-}
-
-JS_PUBLIC_API bool JS_ForwardSetPropertyTo(JSContext* cx, HandleObject obj,
-                                           HandleId id, HandleValue v,
-                                           HandleValue receiver,
-                                           ObjectOpResult& result) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id, v, receiver);
-
-  return SetProperty(cx, obj, id, v, receiver, result);
-}
-
-JS_PUBLIC_API bool JS_SetPropertyById(JSContext* cx, HandleObject obj,
-                                      HandleId id, HandleValue v) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id, v);
-
-  RootedValue receiver(cx, ObjectValue(*obj));
-  ObjectOpResult ignored;
-  return SetProperty(cx, obj, id, v, receiver, ignored);
-}
-
-JS_PUBLIC_API bool JS_SetProperty(JSContext* cx, HandleObject obj,
-                                  const char* name, HandleValue v) {
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_SetPropertyById(cx, obj, id, v);
-}
-
-JS_PUBLIC_API bool JS_SetUCProperty(JSContext* cx, HandleObject obj,
-                                    const char16_t* name, size_t namelen,
-                                    HandleValue v) {
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_SetPropertyById(cx, obj, id, v);
-}
-
-static bool SetElement(JSContext* cx, HandleObject obj, uint32_t index,
-                       HandleValue v) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, v);
-
-  RootedValue receiver(cx, ObjectValue(*obj));
-  ObjectOpResult ignored;
-  return SetElement(cx, obj, index, v, receiver, ignored);
-}
-
-JS_PUBLIC_API bool JS_SetElement(JSContext* cx, HandleObject obj,
-                                 uint32_t index, HandleValue v) {
-  return SetElement(cx, obj, index, v);
-}
-
-JS_PUBLIC_API bool JS_SetElement(JSContext* cx, HandleObject obj,
-                                 uint32_t index, HandleObject v) {
-  RootedValue value(cx, ObjectOrNullValue(v));
-  return SetElement(cx, obj, index, value);
-}
-
-JS_PUBLIC_API bool JS_SetElement(JSContext* cx, HandleObject obj,
-                                 uint32_t index, HandleString v) {
-  RootedValue value(cx, StringValue(v));
-  return SetElement(cx, obj, index, value);
-}
-
-JS_PUBLIC_API bool JS_SetElement(JSContext* cx, HandleObject obj,
-                                 uint32_t index, int32_t v) {
-  RootedValue value(cx, NumberValue(v));
-  return SetElement(cx, obj, index, value);
-}
-
-JS_PUBLIC_API bool JS_SetElement(JSContext* cx, HandleObject obj,
-                                 uint32_t index, uint32_t v) {
-  RootedValue value(cx, NumberValue(v));
-  return SetElement(cx, obj, index, value);
-}
-
-JS_PUBLIC_API bool JS_SetElement(JSContext* cx, HandleObject obj,
-                                 uint32_t index, double v) {
-  RootedValue value(cx, NumberValue(v));
-  return SetElement(cx, obj, index, value);
-}
-
-JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id, ObjectOpResult& result) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id);
-
-  return DeleteProperty(cx, obj, id, result);
-}
-
-JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, HandleObject obj,
-                                     const char* name, ObjectOpResult& result) {
-  CHECK_THREAD(cx);
-  cx->check(obj);
-
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return DeleteProperty(cx, obj, id, result);
-}
-
-JS_PUBLIC_API bool JS_DeleteUCProperty(JSContext* cx, HandleObject obj,
-                                       const char16_t* name, size_t namelen,
-                                       ObjectOpResult& result) {
-  CHECK_THREAD(cx);
-  cx->check(obj);
-
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return DeleteProperty(cx, obj, id, result);
-}
-
-JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index, ObjectOpResult& result) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj);
-
-  return DeleteElement(cx, obj, index, result);
-}
-
-JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx, HandleObject obj,
-                                         HandleId id) {
-  ObjectOpResult ignored;
-  return JS_DeletePropertyById(cx, obj, id, ignored);
-}
-
-JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, HandleObject obj,
-                                     const char* name) {
-  ObjectOpResult ignored;
-  return JS_DeleteProperty(cx, obj, name, ignored);
-}
-
-JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, HandleObject obj,
-                                    uint32_t index) {
-  ObjectOpResult ignored;
-  return JS_DeleteElement(cx, obj, index, ignored);
-}
-
-JS_PUBLIC_API bool JS_Enumerate(JSContext* cx, HandleObject obj,
-                                JS::MutableHandle<IdVector> props) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, props);
-  MOZ_ASSERT(props.empty());
-
-  RootedIdVector ids(cx);
-  if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY, &ids)) {
-    return false;
-  }
-
-  return props.append(ids.begin(), ids.end());
-}
-
 JS_PUBLIC_API bool JS::IsCallable(JSObject* obj) { return obj->isCallable(); }
 
 JS_PUBLIC_API bool JS::IsConstructor(JSObject* obj) {
   return obj->isConstructor();
 }
 
 JS_PUBLIC_API bool JS_CallFunctionValue(JSContext* cx, HandleObject obj,
                                         HandleValue fval,
@@ -2772,67 +2094,16 @@ JS_PUBLIC_API bool JS::Construct(JSConte
     return false;
   }
 
   return js::Construct(cx, fval, cargs, fval, objp);
 }
 
 /* * */
 
-JS_PUBLIC_API bool JS_AlreadyHasOwnPropertyById(JSContext* cx, HandleObject obj,
-                                                HandleId id, bool* foundp) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id);
-
-  if (!obj->is<NativeObject>()) {
-    return js::HasOwnProperty(cx, obj, id, foundp);
-  }
-
-  PropertyResult prop;
-  if (!NativeLookupOwnPropertyNoResolve(cx, &obj->as<NativeObject>(), id,
-                                        &prop)) {
-    return false;
-  }
-  *foundp = prop.isFound();
-  return true;
-}
-
-JS_PUBLIC_API bool JS_AlreadyHasOwnProperty(JSContext* cx, HandleObject obj,
-                                            const char* name, bool* foundp) {
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
-}
-
-JS_PUBLIC_API bool JS_AlreadyHasOwnUCProperty(JSContext* cx, HandleObject obj,
-                                              const char16_t* name,
-                                              size_t namelen, bool* foundp) {
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return false;
-  }
-  RootedId id(cx, AtomToId(atom));
-  return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
-}
-
-JS_PUBLIC_API bool JS_AlreadyHasOwnElement(JSContext* cx, HandleObject obj,
-                                           uint32_t index, bool* foundp) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  RootedId id(cx);
-  if (!IndexToId(cx, index, &id)) {
-    return false;
-  }
-  return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
-}
-
 JS_PUBLIC_API bool JS_FreezeObject(JSContext* cx, HandleObject obj) {
   AssertHeapIsIdle();
   CHECK_THREAD(cx);
   cx->check(obj);
   return FreezeObject(cx, obj);
 }
 
 static bool DeepFreezeSlot(JSContext* cx, const Value& v) {
@@ -2875,83 +2146,16 @@ JS_PUBLIC_API bool JS_DeepFreezeObject(J
         return false;
       }
     }
   }
 
   return true;
 }
 
-static bool DefineSelfHostedProperty(JSContext* cx, HandleObject obj,
-                                     HandleId id, const char* getterName,
-                                     const char* setterName, unsigned attrs) {
-  JSAtom* getterNameAtom = Atomize(cx, getterName, strlen(getterName));
-  if (!getterNameAtom) {
-    return false;
-  }
-  RootedPropertyName getterNameName(cx, getterNameAtom->asPropertyName());
-
-  RootedAtom name(cx, IdToFunctionName(cx, id));
-  if (!name) {
-    return false;
-  }
-
-  RootedValue getterValue(cx);
-  if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), getterNameName,
-                                           name, 0, &getterValue)) {
-    return false;
-  }
-  MOZ_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>());
-  RootedFunction getterFunc(cx, &getterValue.toObject().as<JSFunction>());
-
-  RootedFunction setterFunc(cx);
-  if (setterName) {
-    JSAtom* setterNameAtom = Atomize(cx, setterName, strlen(setterName));
-    if (!setterNameAtom) {
-      return false;
-    }
-    RootedPropertyName setterNameName(cx, setterNameAtom->asPropertyName());
-
-    RootedValue setterValue(cx);
-    if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), setterNameName,
-                                             name, 1, &setterValue)) {
-      return false;
-    }
-    MOZ_ASSERT(setterValue.isObject() &&
-               setterValue.toObject().is<JSFunction>());
-    setterFunc = &setterValue.toObject().as<JSFunction>();
-  }
-
-  return DefineAccessorPropertyById(cx, obj, id, getterFunc, setterFunc, attrs);
-}
-
-JS_PUBLIC_API JSObject* JS_DefineObject(JSContext* cx, HandleObject obj,
-                                        const char* name, const JSClass* clasp,
-                                        unsigned attrs) {
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj);
-
-  if (!clasp) {
-    clasp = &PlainObject::class_; /* default class is Object */
-  }
-
-  RootedObject nobj(cx, NewBuiltinClassInstance(cx, clasp));
-  if (!nobj) {
-    return nullptr;
-  }
-
-  RootedValue nobjValue(cx, ObjectValue(*nobj));
-  if (!DefineDataProperty(cx, obj, name, nobjValue, attrs)) {
-    return nullptr;
-  }
-
-  return nobj;
-}
-
 JS_PUBLIC_API bool JSPropertySpec::getValue(JSContext* cx,
                                             MutableHandleValue vp) const {
   MOZ_ASSERT(!isAccessor());
 
   switch (u.value.type) {
     case ValueWrapper::Type::String: {
       RootedAtom atom(cx, Atomize(cx, u.value.string, strlen(u.value.string)));
       if (!atom) {
@@ -2994,53 +2198,16 @@ JS_PUBLIC_API bool JS::PropertySpecNameT
   // We are calling fromMarkedLocation(idp) even though idp points to a
   // location that will never be marked. This is OK because the whole point
   // of this API is to populate *idp with a jsid that does not need to be
   // marked.
   return PropertySpecNameToId(
       cx, name, MutableHandleId::fromMarkedLocation(idp), js::PinAtom);
 }
 
-JS_PUBLIC_API bool JS_DefineProperties(JSContext* cx, HandleObject obj,
-                                       const JSPropertySpec* ps) {
-  RootedId id(cx);
-
-  for (; ps->name; ps++) {
-    if (!PropertySpecNameToId(cx, ps->name, &id)) {
-      return false;
-    }
-
-    if (ps->isAccessor()) {
-      if (ps->isSelfHosted()) {
-        if (!DefineSelfHostedProperty(
-                cx, obj, id, ps->u.accessors.getter.selfHosted.funname,
-                ps->u.accessors.setter.selfHosted.funname, ps->attributes())) {
-          return false;
-        }
-      } else {
-        if (!DefineAccessorPropertyById(
-                cx, obj, id, ps->u.accessors.getter.native,
-                ps->u.accessors.setter.native, ps->attributes())) {
-          return false;
-        }
-      }
-    } else {
-      RootedValue v(cx);
-      if (!ps->getValue(cx, &v)) {
-        return false;
-      }
-
-      if (!DefineDataPropertyById(cx, obj, id, v, ps->attributes())) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
 JS_PUBLIC_API bool JS::ObjectToCompletePropertyDescriptor(
     JSContext* cx, HandleObject obj, HandleValue descObj,
     MutableHandle<PropertyDescriptor> desc) {
   // |obj| can be in a different compartment here. The caller is responsible
   // for wrapping it (see JS_WrapPropertyDescriptor).
   cx->check(descObj);
   if (!ToPropertyDescriptor(cx, descObj, true, desc)) {
     return false;
@@ -3284,67 +2451,16 @@ JS_PUBLIC_API bool JS_IsNativeFunction(J
   JSFunction* fun = &funobj->as<JSFunction>();
   return fun->isNativeFun() && fun->native() == call;
 }
 
 extern JS_PUBLIC_API bool JS_IsConstructor(JSFunction* fun) {
   return fun->isConstructor();
 }
 
-JS_PUBLIC_API bool JS_DefineFunctions(JSContext* cx, HandleObject obj,
-                                      const JSFunctionSpec* fs) {
-  MOZ_ASSERT(!cx->zone()->isAtomsZone());
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj);
-
-  return DefineFunctions(cx, obj, fs, NotIntrinsic);
-}
-
-JS_PUBLIC_API JSFunction* JS_DefineFunction(JSContext* cx, HandleObject obj,
-                                            const char* name, JSNative call,
-                                            unsigned nargs, unsigned attrs) {
-  MOZ_ASSERT(!cx->zone()->isAtomsZone());
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj);
-  JSAtom* atom = Atomize(cx, name, strlen(name));
-  if (!atom) {
-    return nullptr;
-  }
-  Rooted<jsid> id(cx, AtomToId(atom));
-  return DefineFunction(cx, obj, id, call, nargs, attrs);
-}
-
-JS_PUBLIC_API JSFunction* JS_DefineUCFunction(JSContext* cx, HandleObject obj,
-                                              const char16_t* name,
-                                              size_t namelen, JSNative call,
-                                              unsigned nargs, unsigned attrs) {
-  MOZ_ASSERT(!cx->zone()->isAtomsZone());
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj);
-  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-  if (!atom) {
-    return nullptr;
-  }
-  Rooted<jsid> id(cx, AtomToId(atom));
-  return DefineFunction(cx, obj, id, call, nargs, attrs);
-}
-
-extern JS_PUBLIC_API JSFunction* JS_DefineFunctionById(
-    JSContext* cx, HandleObject obj, HandleId id, JSNative call, unsigned nargs,
-    unsigned attrs) {
-  MOZ_ASSERT(!cx->zone()->isAtomsZone());
-  AssertHeapIsIdle();
-  CHECK_THREAD(cx);
-  cx->check(obj, id);
-  return DefineFunction(cx, obj, id, call, nargs, attrs);
-}
-
 void JS::TransitiveCompileOptions::copyPODTransitiveOptions(
     const TransitiveCompileOptions& rhs) {
   mutedErrors_ = rhs.mutedErrors_;
   forceFullParse_ = rhs.forceFullParse_;
   forceStrictMode_ = rhs.forceStrictMode_;
   skipFilenameValidation_ = rhs.skipFilenameValidation_;
   sourcePragmas_ = rhs.sourcePragmas_;
   selfHostingMode = rhs.selfHostingMode;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -37,16 +37,17 @@
 #include "js/GCAPI.h"
 #include "js/GCVector.h"
 #include "js/HashTable.h"
 #include "js/Id.h"
 #include "js/MapAndSet.h"
 #include "js/MemoryFunctions.h"
 #include "js/OffThreadScriptCompilation.h"
 #include "js/Principals.h"
+#include "js/PropertyAndElement.h"  // JS_Enumerate
 #include "js/PropertyDescriptor.h"
 #include "js/PropertySpec.h"
 #include "js/Realm.h"
 #include "js/RealmIterators.h"
 #include "js/RealmOptions.h"
 #include "js/RefCounted.h"
 #include "js/RootingAPI.h"
 #include "js/String.h"
@@ -655,383 +656,16 @@ extern JS_PUBLIC_API bool JS_PreventExte
  *
  * This is a nonstandard internal method.
  */
 extern JS_PUBLIC_API bool JS_SetImmutablePrototype(JSContext* cx,
                                                    JS::HandleObject obj,
                                                    bool* succeeded);
 
 /**
- * Define a property on obj.
- *
- * This function uses JS::ObjectOpResult to indicate conditions that ES6
- * specifies as non-error failures. This is inconvenient at best, so use this
- * function only if you are implementing a proxy handler's defineProperty()
- * method. For all other purposes, use one of the many DefineProperty functions
- * below that throw an exception in all failure cases.
- *
- * Implements: ES6 [[DefineOwnProperty]] internal method.
- */
-extern JS_PUBLIC_API bool JS_DefinePropertyById(
-    JSContext* cx, JS::HandleObject obj, JS::HandleId id,
-    JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& result);
-
-/**
- * Define a property on obj, throwing a TypeError if the attempt fails.
- * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`.
- */
-extern JS_PUBLIC_API bool JS_DefinePropertyById(
-    JSContext* cx, JS::HandleObject obj, JS::HandleId id,
-    JS::Handle<JS::PropertyDescriptor> desc);
-
-extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
-                                                JS::HandleObject obj,
-                                                JS::HandleId id,
-                                                JS::HandleValue value,
-                                                unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefinePropertyById(
-    JSContext* cx, JS::HandleObject obj, JS::HandleId id, JSNative getter,
-    JSNative setter, unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefinePropertyById(
-    JSContext* cx, JS::HandleObject obj, JS::HandleId id,
-    JS::HandleObject getter, JS::HandleObject setter, unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
-                                                JS::HandleObject obj,
-                                                JS::HandleId id,
-                                                JS::HandleObject value,
-                                                unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
-                                                JS::HandleObject obj,
-                                                JS::HandleId id,
-                                                JS::HandleString value,
-                                                unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
-                                                JS::HandleObject obj,
-                                                JS::HandleId id, int32_t value,
-                                                unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
-                                                JS::HandleObject obj,
-                                                JS::HandleId id, uint32_t value,
-                                                unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
-                                                JS::HandleObject obj,
-                                                JS::HandleId id, double value,
-                                                unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name,
-                                            JS::HandleValue value,
-                                            unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name, JSNative getter,
-                                            JSNative setter, unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name,
-                                            JS::HandleObject getter,
-                                            JS::HandleObject setter,
-                                            unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name,
-                                            JS::HandleObject value,
-                                            unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name,
-                                            JS::HandleString value,
-                                            unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name, int32_t value,
-                                            unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name, uint32_t value,
-                                            unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name, double value,
-                                            unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(
-    JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
-    JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& result);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(
-    JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
-    JS::Handle<JS::PropertyDescriptor> desc);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(
-    JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
-    JS::HandleValue value, unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(
-    JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
-    JS::HandleObject getter, JS::HandleObject setter, unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(
-    JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
-    JS::HandleObject value, unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(
-    JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
-    JS::HandleString value, unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
-                                              JS::HandleObject obj,
-                                              const char16_t* name,
-                                              size_t namelen, int32_t value,
-                                              unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
-                                              JS::HandleObject obj,
-                                              const char16_t* name,
-                                              size_t namelen, uint32_t value,
-                                              unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx,
-                                              JS::HandleObject obj,
-                                              const char16_t* name,
-                                              size_t namelen, double value,
-                                              unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index,
-                                           JS::HandleValue value,
-                                           unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index,
-                                           JS::HandleObject getter,
-                                           JS::HandleObject setter,
-                                           unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index,
-                                           JS::HandleObject value,
-                                           unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index,
-                                           JS::HandleString value,
-                                           unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index, int32_t value,
-                                           unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index, uint32_t value,
-                                           unsigned attrs);
-
-extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index, double value,
-                                           unsigned attrs);
-
-/**
- * Compute the expression `id in obj`.
- *
- * If obj has an own or inherited property obj[id], set *foundp = true and
- * return true. If not, set *foundp = false and return true. On error, return
- * false with an exception pending.
- *
- * Implements: ES6 [[Has]] internal method.
- */
-extern JS_PUBLIC_API bool JS_HasPropertyById(JSContext* cx,
-                                             JS::HandleObject obj,
-                                             JS::HandleId id, bool* foundp);
-
-extern JS_PUBLIC_API bool JS_HasProperty(JSContext* cx, JS::HandleObject obj,
-                                         const char* name, bool* foundp);
-
-extern JS_PUBLIC_API bool JS_HasUCProperty(JSContext* cx, JS::HandleObject obj,
-                                           const char16_t* name, size_t namelen,
-                                           bool* vp);
-
-extern JS_PUBLIC_API bool JS_HasElement(JSContext* cx, JS::HandleObject obj,
-                                        uint32_t index, bool* foundp);
-
-/**
- * Determine whether obj has an own property with the key `id`.
- *
- * Implements: ES6 7.3.11 HasOwnProperty(O, P).
- */
-extern JS_PUBLIC_API bool JS_HasOwnPropertyById(JSContext* cx,
-                                                JS::HandleObject obj,
-                                                JS::HandleId id, bool* foundp);
-
-extern JS_PUBLIC_API bool JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name, bool* foundp);
-
-/**
- * Get the value of the property `obj[id]`, or undefined if no such property
- * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`.
- *
- * Most callers don't need the `receiver` argument. Consider using
- * JS_GetProperty instead. (But if you're implementing a proxy handler's set()
- * method, it's often correct to call this function and pass the receiver
- * through.)
- *
- * Implements: ES6 [[Get]] internal method.
- */
-extern JS_PUBLIC_API bool JS_ForwardGetPropertyTo(JSContext* cx,
-                                                  JS::HandleObject obj,
-                                                  JS::HandleId id,
-                                                  JS::HandleValue receiver,
-                                                  JS::MutableHandleValue vp);
-
-extern JS_PUBLIC_API bool JS_ForwardGetElementTo(JSContext* cx,
-                                                 JS::HandleObject obj,
-                                                 uint32_t index,
-                                                 JS::HandleObject receiver,
-                                                 JS::MutableHandleValue vp);
-
-/**
- * Get the value of the property `obj[id]`, or undefined if no such property
- * exists. The result is stored in vp.
- *
- * Implements: ES6 7.3.1 Get(O, P).
- */
-extern JS_PUBLIC_API bool JS_GetPropertyById(JSContext* cx,
-                                             JS::HandleObject obj,
-                                             JS::HandleId id,
-                                             JS::MutableHandleValue vp);
-
-extern JS_PUBLIC_API bool JS_GetProperty(JSContext* cx, JS::HandleObject obj,
-                                         const char* name,
-                                         JS::MutableHandleValue vp);
-
-extern JS_PUBLIC_API bool JS_GetUCProperty(JSContext* cx, JS::HandleObject obj,
-                                           const char16_t* name, size_t namelen,
-                                           JS::MutableHandleValue vp);
-
-extern JS_PUBLIC_API bool JS_GetElement(JSContext* cx, JS::HandleObject obj,
-                                        uint32_t index,
-                                        JS::MutableHandleValue vp);
-
-/**
- * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`.
- *
- * This function has a `receiver` argument that most callers don't need.
- * Consider using JS_SetProperty instead.
- *
- * Implements: ES6 [[Set]] internal method.
- */
-extern JS_PUBLIC_API bool JS_ForwardSetPropertyTo(
-    JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
-    JS::HandleValue receiver, JS::ObjectOpResult& result);
-
-/**
- * Perform the assignment `obj[id] = v`.
- *
- * This function performs non-strict assignment, so if the property is
- * read-only, nothing happens and no error is thrown.
- */
-extern JS_PUBLIC_API bool JS_SetPropertyById(JSContext* cx,
-                                             JS::HandleObject obj,
-                                             JS::HandleId id,
-                                             JS::HandleValue v);
-
-extern JS_PUBLIC_API bool JS_SetProperty(JSContext* cx, JS::HandleObject obj,
-                                         const char* name, JS::HandleValue v);
-
-extern JS_PUBLIC_API bool JS_SetUCProperty(JSContext* cx, JS::HandleObject obj,
-                                           const char16_t* name, size_t namelen,
-                                           JS::HandleValue v);
-
-extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
-                                        uint32_t index, JS::HandleValue v);
-
-extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
-                                        uint32_t index, JS::HandleObject v);
-
-extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
-                                        uint32_t index, JS::HandleString v);
-
-extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
-                                        uint32_t index, int32_t v);
-
-extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
-                                        uint32_t index, uint32_t v);
-
-extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::HandleObject obj,
-                                        uint32_t index, double v);
-
-/**
- * Delete a property. This is the C++ equivalent of
- * `result = Reflect.deleteProperty(obj, id)`.
- *
- * This function has a `result` out parameter that most callers don't need.
- * Unless you can pass through an ObjectOpResult provided by your caller, it's
- * probably best to use the JS_DeletePropertyById signature with just 3
- * arguments.
- *
- * Implements: ES6 [[Delete]] internal method.
- */
-extern JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx,
-                                                JS::HandleObject obj,
-                                                JS::HandleId id,
-                                                JS::ObjectOpResult& result);
-
-extern JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name,
-                                            JS::ObjectOpResult& result);
-
-extern JS_PUBLIC_API bool JS_DeleteUCProperty(JSContext* cx,
-                                              JS::HandleObject obj,
-                                              const char16_t* name,
-                                              size_t namelen,
-                                              JS::ObjectOpResult& result);
-
-extern JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index,
-                                           JS::ObjectOpResult& result);
-
-/**
- * Delete a property, ignoring strict failures. This is the C++ equivalent of
- * the JS `delete obj[id]` in non-strict mode code.
- */
-extern JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx,
-                                                JS::HandleObject obj, jsid id);
-
-extern JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, JS::HandleObject obj,
-                                            const char* name);
-
-extern JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, JS::HandleObject obj,
-                                           uint32_t index);
-
-/**
- * Get an array of the non-symbol enumerable properties of obj.
- * This function is roughly equivalent to:
- *
- *     var result = [];
- *     for (key in obj) {
- *         result.push(key);
- *     }
- *     return result;
- *
- * This is the closest thing we currently have to the ES6 [[Enumerate]]
- * internal method.
- *
- * The array of ids returned by JS_Enumerate must be rooted to protect its
- * contents from garbage collection. Use JS::Rooted<JS::IdVector>.
- */
-extern JS_PUBLIC_API bool JS_Enumerate(JSContext* cx, JS::HandleObject obj,
-                                       JS::MutableHandle<JS::IdVector> props);
-
-/**
  * Equivalent to `Object.assign(target, src)`: Copies the properties from the
  * `src` object (which must not be null) to `target` (which also must not be
  * null).
  */
 extern JS_PUBLIC_API bool JS_AssignObject(JSContext* cx,
                                           JS::HandleObject target,
                                           JS::HandleObject src);
 
@@ -1156,50 +790,16 @@ extern JS_PUBLIC_API bool Construct(JSCo
  * newTarget is omitted.
  */
 extern JS_PUBLIC_API bool Construct(JSContext* cx, JS::HandleValue fun,
                                     const JS::HandleValueArray& args,
                                     MutableHandleObject objp);
 
 } /* namespace JS */
 
-/*** Other property-defining functions **************************************/
-
-extern JS_PUBLIC_API JSObject* JS_DefineObject(JSContext* cx,
-                                               JS::HandleObject obj,
-                                               const char* name,
-                                               const JSClass* clasp = nullptr,
-                                               unsigned attrs = 0);
-
-extern JS_PUBLIC_API bool JS_DefineProperties(JSContext* cx,
-                                              JS::HandleObject obj,
-                                              const JSPropertySpec* ps);
-
-/* * */
-
-extern JS_PUBLIC_API bool JS_AlreadyHasOwnPropertyById(JSContext* cx,
-                                                       JS::HandleObject obj,
-                                                       JS::HandleId id,
-                                                       bool* foundp);
-
-extern JS_PUBLIC_API bool JS_AlreadyHasOwnProperty(JSContext* cx,
-                                                   JS::HandleObject obj,
-                                                   const char* name,
-                                                   bool* foundp);
-
-extern JS_PUBLIC_API bool JS_AlreadyHasOwnUCProperty(JSContext* cx,
-                                                     JS::HandleObject obj,
-                                                     const char16_t* name,
-                                                     size_t namelen,
-                                                     bool* foundp);
-
-extern JS_PUBLIC_API bool JS_AlreadyHasOwnElement(JSContext* cx,
-                                                  JS::HandleObject obj,
-                                                  uint32_t index, bool* foundp);
-
 namespace JS {
 
 /**
  * On success, returns true, setting |*isMap| to true if |obj| is a Map object
  * or a wrapper around one, or to false if not.  Returns false on failure.
  *
  * This method returns true with |*isMap == false| when passed an ES6 proxy
  * whose target is a Map, or when passed a revoked proxy.
@@ -1326,32 +926,16 @@ JS_PUBLIC_API bool JS_GetFunctionLength(
  */
 extern JS_PUBLIC_API bool JS_ObjectIsFunction(JSObject* obj);
 
 extern JS_PUBLIC_API bool JS_IsNativeFunction(JSObject* funobj, JSNative call);
 
 /** Return whether the given function is a valid constructor. */
 extern JS_PUBLIC_API bool JS_IsConstructor(JSFunction* fun);
 
-extern JS_PUBLIC_API bool JS_DefineFunctions(JSContext* cx,
-                                             JS::Handle<JSObject*> obj,
-                                             const JSFunctionSpec* fs);
-
-extern JS_PUBLIC_API JSFunction* JS_DefineFunction(
-    JSContext* cx, JS::Handle<JSObject*> obj, const char* name, JSNative call,
-    unsigned nargs, unsigned attrs);
-
-extern JS_PUBLIC_API JSFunction* JS_DefineUCFunction(
-    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
-    size_t namelen, JSNative call, unsigned nargs, unsigned attrs);
-
-extern JS_PUBLIC_API JSFunction* JS_DefineFunctionById(
-    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
-    JSNative call, unsigned nargs, unsigned attrs);
-
 extern JS_PUBLIC_API bool JS_IsFunctionBound(JSFunction* fun);
 
 extern JS_PUBLIC_API JSObject* JS_GetBoundFunctionTarget(JSFunction* fun);
 
 extern JS_PUBLIC_API JSObject* JS_GetGlobalFromScript(JSScript* script);
 
 extern JS_PUBLIC_API const char* JS_GetScriptFilename(JSScript* script);
 
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -29,16 +29,17 @@
 #include "js/CharacterEncoding.h"
 #include "js/Class.h"
 #include "js/Conversions.h"
 #include "js/ErrorReport.h"             // JS::PrintError
 #include "js/Exception.h"               // JS::ExceptionStack
 #include "js/experimental/TypedData.h"  // JS_IsArrayBufferViewObject
 #include "js/friend/ErrorMessages.h"  // JSErrNum, js::GetErrorMessage, JSMSG_*
 #include "js/Object.h"                // JS::GetBuiltinClass
+#include "js/PropertyAndElement.h"    // JS_GetProperty, JS_HasProperty
 #include "js/SavedFrameAPI.h"
 #include "js/UniquePtr.h"
 #include "js/Value.h"
 #include "js/Warnings.h"  // JS::{,Set}WarningReporter
 #include "js/Wrapper.h"
 #include "util/Memory.h"
 #include "util/StringBuffer.h"
 #include "vm/Compartment.h"
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -23,16 +23,17 @@
 #include "js/experimental/CodeCoverage.h"
 #include "js/experimental/CTypes.h"  // JS::AutoCTypesActivityCallback, JS::SetCTypesActivityCallback
 #include "js/experimental/Intl.h"  // JS::AddMoz{DateTimeFormat,DisplayNames}Constructor
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/friend/StackLimits.h"    // JS_STACK_GROWTH_DIRECTION
 #include "js/friend/WindowProxy.h"    // js::ToWindowIfWindowProxy
 #include "js/Object.h"                // JS::GetClass
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/Proxy.h"
 #include "js/shadow/Object.h"  // JS::shadow::Object
 #include "js/String.h"         // JS::detail::StringToLinearStringSlow
 #include "js/Wrapper.h"
 #include "proxy/DeadObjectProxy.h"
 #include "util/Poison.h"
 #include "vm/ArgumentsObject.h"
 #include "vm/BooleanObject.h"
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -29,16 +29,17 @@
 #include "frontend/ParserAtom.h"  // frontend::{ParserAtomsTable, TaggedParserAtomIndex}
 #include "jit/InlinableNatives.h"
 #include "js/CharacterEncoding.h"
 #include "js/Conversions.h"
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #if !JS_HAS_INTL_API
 #  include "js/LocaleSensitive.h"
 #endif
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions
 #include "js/PropertySpec.h"
 #include "util/DoubleToString.h"
 #include "util/Memory.h"
 #include "util/StringBuffer.h"
 #include "vm/BigIntType.h"
 #include "vm/GlobalObject.h"
 #include "vm/JSAtom.h"
 #include "vm/JSContext.h"
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -170,16 +170,17 @@ EXPORTS.js += [
     "../public/Object.h",
     "../public/OffThreadScriptCompilation.h",
     "../public/Principals.h",
     "../public/Printf.h",
     "../public/ProfilingCategory.h",
     "../public/ProfilingFrameIterator.h",
     "../public/ProfilingStack.h",
     "../public/Promise.h",
+    "../public/PropertyAndElement.h",
     "../public/PropertyDescriptor.h",
     "../public/PropertySpec.h",
     "../public/ProtoKey.h",
     "../public/Proxy.h",
     "../public/Realm.h",
     "../public/RealmIterators.h",
     "../public/RealmOptions.h",
     "../public/RefCounted.h",
@@ -413,16 +414,17 @@ UNIFIED_SOURCES += [
     "vm/NativeObject.cpp",
     "vm/OffThreadPromiseRuntimeState.cpp",
     "vm/OffThreadScriptCompilation.cpp",
     "vm/PIC.cpp",
     "vm/PlainObject.cpp",
     "vm/Printer.cpp",
     "vm/Probes.cpp",
     "vm/PromiseLookup.cpp",
+    "vm/PropertyAndElement.cpp",
     "vm/PropertyDescriptor.cpp",
     "vm/PropMap.cpp",
     "vm/ProxyObject.cpp",
     "vm/Realm.cpp",
     "vm/RegExpObject.cpp",
     "vm/RegExpStatics.cpp",
     "vm/Runtime.cpp",
     "vm/SavedStacks.cpp",
--- a/js/src/shell/ModuleLoader.cpp
+++ b/js/src/shell/ModuleLoader.cpp
@@ -7,16 +7,17 @@
 #include "shell/ModuleLoader.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/TextUtils.h"
 
 #include "NamespaceImports.h"
 
 #include "js/Modules.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty
 #include "js/SourceText.h"
 #include "js/StableStringChars.h"
 #include "shell/jsshell.h"
 #include "shell/OSObject.h"
 #include "shell/StringUtils.h"
 #include "util/Text.h"
 #include "vm/JSAtom.h"
 #include "vm/JSContext.h"
--- a/js/src/shell/OSObject.cpp
+++ b/js/src/shell/OSObject.cpp
@@ -33,16 +33,17 @@
 // For JSFunctionSpecWithHelp
 #include "jsfriendapi.h"
 
 #include "gc/FreeOp.h"
 #include "js/CharacterEncoding.h"
 #include "js/Conversions.h"
 #include "js/experimental/TypedData.h"  // JS_NewUint8Array
 #include "js/Object.h"                  // JS::GetReservedSlot
+#include "js/PropertyAndElement.h"      // JS_DefineProperty
 #include "js/PropertySpec.h"
 #include "js/Value.h"  // JS::Value
 #include "js/Wrapper.h"
 #include "shell/jsshell.h"
 #include "shell/StringUtils.h"
 #include "util/GetPidProvider.h"  // getpid()
 #include "util/StringBuffer.h"
 #include "util/Text.h"
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -130,16 +130,17 @@
 #include "js/GCVector.h"
 #include "js/Initialization.h"
 #include "js/JSON.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
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineFunction, JS_DefineFunctions, JS_DefineProperties, JS_DefineProperty, JS_GetElement, JS_GetProperty, JS_GetPropertyById, JS_HasProperty, JS_SetElement, JS_SetProperty, JS_SetPropertyById
 #include "js/PropertySpec.h"
 #include "js/Realm.h"
 #include "js/RegExp.h"  // JS::ObjectIsRegExp
 #include "js/SourceText.h"
 #include "js/StableStringChars.h"
 #include "js/StructuredClone.h"
 #include "js/SweepingAPI.h"
 #include "js/Transcoding.h"  // JS::TranscodeBuffer, JS::TranscodeRange
--- a/js/src/shell/jsrtfuzzing/jsrtfuzzing.cpp
+++ b/js/src/shell/jsrtfuzzing/jsrtfuzzing.cpp
@@ -8,26 +8,27 @@
 
 #include "mozilla/Assertions.h"  // MOZ_CRASH
 #include "mozilla/Utf8.h"        // mozilla::Utf8Unit
 
 #include <stdio.h>  // fflush, fprintf, fputs
 
 #include "FuzzerDefs.h"
 #include "FuzzingInterface.h"
-#include "jsapi.h"  // JS_ClearPendingException, JS_IsExceptionPending, JS_SetProperty
+#include "jsapi.h"  // JS_ClearPendingException, JS_IsExceptionPending
 
 #include "js/CompilationAndEvaluation.h"  // JS::Evaluate
 #include "js/CompileOptions.h"            // JS::CompileOptions
 #include "js/ErrorReport.h"               // JS::PrintError
 #include "js/Exception.h"                 // JS::StealPendingExceptionStack
 #include "js/experimental/TypedData.h"  // JS_GetUint8ClampedArrayData, JS_NewUint8ClampedArray
-#include "js/RootingAPI.h"  // JS::Rooted
-#include "js/SourceText.h"  // JS::Source{Ownership,Text}
-#include "js/Value.h"       // JS::Value
+#include "js/PropertyAndElement.h"  // JS_SetProperty
+#include "js/RootingAPI.h"          // JS::Rooted
+#include "js/SourceText.h"          // JS::Source{Ownership,Text}
+#include "js/Value.h"               // JS::Value
 #include "shell/jsshell.h"  // js::shell::{reportWarnings,PrintStackTrace,sArg{c,v}}
 #include "util/Text.h"
 #include "vm/Interpreter.h"
 #include "vm/TypedArrayObject.h"
 
 #include "vm/ArrayBufferObject-inl.h"
 #include "vm/JSContext-inl.h"
 
--- 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/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty, JS_GetPropertyById
 #include "util/StringBuffer.h"
 
 using namespace JS;
 
 namespace js {
 namespace shell {
 
 // Generate 'usage' and 'help' properties for the given object.
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -8,16 +8,17 @@
 
 #include "mozilla/Maybe.h"
 
 #include "builtin/ModuleObject.h"
 #include "gc/Policy.h"
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/friend/StackLimits.h"    // js::AutoCheckRecursionLimit
 #include "js/friend/WindowProxy.h"    // js::IsWindow, js::IsWindowProxy
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById, JS_HasProperty, JS_HasPropertyById
 #include "vm/ArgumentsObject.h"
 #include "vm/AsyncFunction.h"
 #include "vm/BytecodeIterator.h"
 #include "vm/BytecodeLocation.h"
 #include "vm/GeneratorObject.h"  // js::GetGeneratorObjectForEnvironment
 #include "vm/GlobalObject.h"
 #include "vm/Iteration.h"
 #include "vm/JSObject.h"
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -42,16 +42,17 @@
 #include "builtin/WeakMapObject.h"
 #include "builtin/WeakRefObject.h"
 #include "builtin/WeakSetObject.h"
 #include "debugger/DebugAPI.h"
 #include "gc/FreeOp.h"
 #include "js/friend/ErrorMessages.h"        // js::GetErrorMessage, JSMSG_*
 #include "js/friend/WindowProxy.h"          // js::ToWindowProxyIfWindow
 #include "js/OffThreadScriptCompilation.h"  // js::UseOffThreadParseGlobal
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions, JS_DefineProperties
 #include "js/ProtoKey.h"
 #include "vm/AsyncFunction.h"
 #include "vm/AsyncIteration.h"
 #include "vm/BooleanObject.h"
 #include "vm/DateObject.h"
 #include "vm/EnvironmentObject.h"
 #include "vm/ErrorObject.h"
 #include "vm/GeneratorObject.h"
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -40,16 +40,17 @@
 #include "jit/Ion.h"
 #include "jit/PcScriptCache.h"
 #include "jit/Simulator.h"
 #include "js/CharacterEncoding.h"
 #include "js/ContextOptions.h"        // JS::ContextOptions
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/friend/StackLimits.h"    // js::ReportOverRecursed
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 #include "util/DiagnosticAssertions.h"
 #include "util/DifferentialTesting.h"
 #include "util/DoubleToString.h"
 #include "util/NativeStack.h"
 #include "util/Text.h"
 #include "util/Windows.h"
 #include "vm/BytecodeUtil.h"  // JSDVG_IGNORE_STACK
 #include "vm/ErrorObject.h"
new file mode 100644
--- /dev/null
+++ b/js/src/vm/PropertyAndElement.cpp
@@ -0,0 +1,996 @@
+/* -*- 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/PropertyAndElement.h"
+
+#include "mozilla/Assertions.h"  // MOZ_ASSERT
+
+#include <stddef.h>  // size_t
+#include <stdint.h>  // uint32_t
+
+#include "jsapi.h"        // JS::IdVector
+#include "jsfriendapi.h"  // js::GetPropertyKeys, JSITER_OWNONLY
+#include "jstypes.h"      // JS_PUBLIC_API
+
+#include "js/CallArgs.h"            // JSNative
+#include "js/Class.h"               // JS::ObjectOpResult
+#include "js/Context.h"             // AssertHeapIsIdle
+#include "js/GCVector.h"            // JS::GCVector, JS::RootedVector
+#include "js/Id.h"                  // JS::PropertyKey, jsid
+#include "js/PropertyDescriptor.h"  // JS::PropertyDescriptor, JSPROP_READONLY
+#include "js/PropertySpec.h"        // JSNativeWrapper
+#include "js/RootingAPI.h"          // JS::Rooted, JS::Handle, JS::MutableHandle
+#include "js/Value.h"               // JS::Value, JS::*Value
+#include "vm/FunctionPrefixKind.h"  // js::FunctionPrefixKind
+#include "vm/GlobalObject.h"        // js::GlobalObject
+#include "vm/JSAtom.h"              // JSAtom, js::Atomize, js::AtomizeChars
+#include "vm/JSContext.h"           // JSContext, CHECK_THREAD
+#include "vm/JSFunction.h"          // js::IdToFunctionName, js::DefineFunction
+#include "vm/JSObject.h"            // JSObject, js::DefineFunctions
+#include "vm/ObjectOperations.h"  // js::DefineProperty, js::DefineDataProperty, js::HasOwnProperty
+#include "vm/PropertyResult.h"  // js::PropertyResult
+#include "vm/StringType.h"      // js::PropertyName
+
+#include "vm/JSAtom-inl.h"            // js::AtomToId, js::IndexToId
+#include "vm/JSContext-inl.h"         // JSContext::check
+#include "vm/JSFunction-inl.h"        // js::NewNativeFunction
+#include "vm/JSObject-inl.h"          // js::NewBuiltinClassInstance
+#include "vm/NativeObject-inl.h"      // js::NativeLookupOwnPropertyNoResolve
+#include "vm/ObjectOperations-inl.h"  // js::GetProperty, js::GetElement, js::SetProperty, js::HasProperty, js::DeleteProperty, js::DeleteElement
+
+using namespace js;
+
+static bool DefinePropertyByDescriptor(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       JS::Handle<jsid> id,
+                                       JS::Handle<JS::PropertyDescriptor> desc,
+                                       JS::ObjectOpResult& result) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id, desc);
+  return js::DefineProperty(cx, obj, id, desc, result);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& result) {
+  return ::DefinePropertyByDescriptor(cx, obj, id, desc, result);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(
+    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
+    JS::Handle<JS::PropertyDescriptor> desc) {
+  JS::ObjectOpResult result;
+  return ::DefinePropertyByDescriptor(cx, obj, id, desc, result) &&
+         result.checkStrict(cx, obj, id);
+}
+
+static bool DefineDataPropertyById(JSContext* cx, JS::Handle<JSObject*> obj,
+                                   JS::Handle<jsid> id,
+                                   JS::Handle<JS::Value> value,
+                                   unsigned attrs) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id, value);
+
+  return js::DefineDataProperty(cx, obj, id, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id,
+                                         JS::Handle<JS::Value> value,
+                                         unsigned attrs) {
+  return ::DefineDataPropertyById(cx, obj, id, value, attrs);
+}
+
+static bool DefineAccessorPropertyById(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       JS::Handle<jsid> id,
+                                       JS::Handle<JSObject*> getter,
+                                       JS::Handle<JSObject*> setter,
+                                       unsigned attrs) {
+  // JSPROP_READONLY has no meaning when accessors are involved. Ideally we'd
+  // throw if this happens, but we've accepted it for long enough that it's
+  // not worth trying to make callers change their ways. Just flip it off on
+  // its way through the API layer so that we can enforce this internally.
+  attrs &= ~JSPROP_READONLY;
+
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id, getter, setter);
+
+  return js::DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
+}
+
+static bool DefineAccessorPropertyById(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       JS::Handle<jsid> id,
+                                       const JSNativeWrapper& get,
+                                       const JSNativeWrapper& set,
+                                       unsigned attrs) {
+  // Getter/setter are both possibly-null JSNatives. Wrap them in JSFunctions.
+
+  JS::Rooted<JSFunction*> getter(cx);
+  if (get.op) {
+    JS::Rooted<JSAtom*> atom(cx,
+                             IdToFunctionName(cx, id, FunctionPrefixKind::Get));
+    if (!atom) {
+      return false;
+    }
+    getter = NewNativeFunction(cx, get.op, 0, atom);
+    if (!getter) {
+      return false;
+    }
+
+    if (get.info) {
+      getter->setJitInfo(get.info);
+    }
+  }
+
+  JS::Rooted<JSFunction*> setter(cx);
+  if (set.op) {
+    JS::Rooted<JSAtom*> atom(cx,
+                             IdToFunctionName(cx, id, FunctionPrefixKind::Set));
+    if (!atom) {
+      return false;
+    }
+    setter = NewNativeFunction(cx, set.op, 1, atom);
+    if (!setter) {
+      return false;
+    }
+
+    if (set.info) {
+      setter->setJitInfo(set.info);
+    }
+  }
+
+  return ::DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
+}
+
+/*
+ * Wrapper functions to create wrappers with no corresponding JSJitInfo from API
+ * function arguments.
+ */
+static JSNativeWrapper NativeOpWrapper(Native native) {
+  JSNativeWrapper ret;
+  ret.op = native;
+  ret.info = nullptr;
+  return ret;
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id, JSNative getter,
+                                         JSNative setter, unsigned attrs) {
+  return ::DefineAccessorPropertyById(cx, obj, id, ::NativeOpWrapper(getter),
+                                      ::NativeOpWrapper(setter), attrs);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id,
+                                         JS::Handle<JSObject*> getter,
+                                         JS::Handle<JSObject*> setter,
+                                         unsigned attrs) {
+  return ::DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id,
+                                         JS::Handle<JSObject*> valueArg,
+                                         unsigned attrs) {
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*valueArg));
+  return ::DefineDataPropertyById(cx, obj, id, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id,
+                                         HandleString valueArg,
+                                         unsigned attrs) {
+  JS::Rooted<JS::Value> value(cx, JS::StringValue(valueArg));
+  return ::DefineDataPropertyById(cx, obj, id, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id, int32_t valueArg,
+                                         unsigned attrs) {
+  JS::Value value = JS::Int32Value(valueArg);
+  return ::DefineDataPropertyById(
+      cx, obj, id, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id, uint32_t valueArg,
+                                         unsigned attrs) {
+  JS::Value value = JS::NumberValue(valueArg);
+  return ::DefineDataPropertyById(
+      cx, obj, id, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id, double valueArg,
+                                         unsigned attrs) {
+  JS::Value value = JS::NumberValue(valueArg);
+  return ::DefineDataPropertyById(
+      cx, obj, id, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+static bool DefineDataProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                               const char* name, JS::Handle<JS::Value> value,
+                               unsigned attrs) {
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+
+  return ::DefineDataPropertyById(cx, obj, id, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name,
+                                     JS::Handle<JS::Value> value,
+                                     unsigned attrs) {
+  return ::DefineDataProperty(cx, obj, name, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name, JSNative getter,
+                                     JSNative setter, unsigned attrs) {
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return ::DefineAccessorPropertyById(cx, obj, id, ::NativeOpWrapper(getter),
+                                      ::NativeOpWrapper(setter), attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name,
+                                     JS::Handle<JSObject*> getter,
+                                     JS::Handle<JSObject*> setter,
+                                     unsigned attrs) {
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+
+  return ::DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name,
+                                     JS::Handle<JSObject*> valueArg,
+                                     unsigned attrs) {
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*valueArg));
+  return ::DefineDataProperty(cx, obj, name, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name, HandleString valueArg,
+                                     unsigned attrs) {
+  JS::Rooted<JS::Value> value(cx, JS::StringValue(valueArg));
+  return ::DefineDataProperty(cx, obj, name, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name, int32_t valueArg,
+                                     unsigned attrs) {
+  JS::Value value = JS::Int32Value(valueArg);
+  return ::DefineDataProperty(
+      cx, obj, name, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name, uint32_t valueArg,
+                                     unsigned attrs) {
+  JS::Value value = JS::NumberValue(valueArg);
+  return ::DefineDataProperty(
+      cx, obj, name, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name, double valueArg,
+                                     unsigned attrs) {
+  JS::Value value = JS::NumberValue(valueArg);
+  return ::DefineDataProperty(
+      cx, obj, name, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+#define AUTO_NAMELEN(s, n) (((n) == (size_t)-1) ? js_strlen(s) : (n))
+
+JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       JS::Handle<JS::PropertyDescriptor> desc,
+                                       JS::ObjectOpResult& result) {
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return ::DefinePropertyByDescriptor(cx, obj, id, desc, result);
+}
+
+JS_PUBLIC_API bool JS_DefineUCProperty(
+    JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name,
+    size_t namelen, JS::Handle<JS::PropertyDescriptor> desc) {
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  JS::ObjectOpResult result;
+  return ::DefinePropertyByDescriptor(cx, obj, id, desc, result) &&
+         result.checkStrict(cx, obj, id);
+}
+
+static bool DefineUCDataProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                 const char16_t* name, size_t namelen,
+                                 JS::Handle<JS::Value> value, unsigned attrs) {
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return ::DefineDataPropertyById(cx, obj, id, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       JS::Handle<JS::Value> value,
+                                       unsigned attrs) {
+  return ::DefineUCDataProperty(cx, obj, name, namelen, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       JS::Handle<JSObject*> getter,
+                                       JS::Handle<JSObject*> setter,
+                                       unsigned attrs) {
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return ::DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       JS::Handle<JSObject*> valueArg,
+                                       unsigned attrs) {
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*valueArg));
+  return ::DefineUCDataProperty(cx, obj, name, namelen, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       HandleString valueArg, unsigned attrs) {
+  JS::Rooted<JS::Value> value(cx, JS::StringValue(valueArg));
+  return ::DefineUCDataProperty(cx, obj, name, namelen, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       int32_t valueArg, unsigned attrs) {
+  JS::Value value = JS::Int32Value(valueArg);
+  return ::DefineUCDataProperty(
+      cx, obj, name, namelen, JS::Handle<JS::Value>::fromMarkedLocation(&value),
+      attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       uint32_t valueArg, unsigned attrs) {
+  JS::Value value = JS::NumberValue(valueArg);
+  return ::DefineUCDataProperty(
+      cx, obj, name, namelen, JS::Handle<JS::Value>::fromMarkedLocation(&value),
+      attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       double valueArg, unsigned attrs) {
+  JS::Value value = JS::NumberValue(valueArg);
+  return ::DefineUCDataProperty(
+      cx, obj, name, namelen, JS::Handle<JS::Value>::fromMarkedLocation(&value),
+      attrs);
+}
+
+extern bool PropertySpecNameToId(JSContext* cx, JSPropertySpec::Name name,
+                                 MutableHandleId id,
+                                 js::PinningBehavior pin = js::DoNotPinAtom);
+
+static bool DefineSelfHostedProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     JS::Handle<jsid> id,
+                                     const char* getterName,
+                                     const char* setterName, unsigned attrs) {
+  JSAtom* getterNameAtom = Atomize(cx, getterName, strlen(getterName));
+  if (!getterNameAtom) {
+    return false;
+  }
+  JS::Rooted<PropertyName*> getterNameName(cx,
+                                           getterNameAtom->asPropertyName());
+
+  JS::Rooted<JSAtom*> name(cx, IdToFunctionName(cx, id));
+  if (!name) {
+    return false;
+  }
+
+  JS::Rooted<JS::Value> getterValue(cx);
+  if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), getterNameName,
+                                           name, 0, &getterValue)) {
+    return false;
+  }
+  MOZ_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>());
+  JS::Rooted<JSFunction*> getterFunc(cx,
+                                     &getterValue.toObject().as<JSFunction>());
+
+  JS::Rooted<JSFunction*> setterFunc(cx);
+  if (setterName) {
+    JSAtom* setterNameAtom = Atomize(cx, setterName, strlen(setterName));
+    if (!setterNameAtom) {
+      return false;
+    }
+    JS::Rooted<PropertyName*> setterNameName(cx,
+                                             setterNameAtom->asPropertyName());
+
+    JS::Rooted<JS::Value> setterValue(cx);
+    if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), setterNameName,
+                                             name, 1, &setterValue)) {
+      return false;
+    }
+    MOZ_ASSERT(setterValue.isObject() &&
+               setterValue.toObject().is<JSFunction>());
+    setterFunc = &setterValue.toObject().as<JSFunction>();
+  }
+
+  return ::DefineAccessorPropertyById(cx, obj, id, getterFunc, setterFunc,
+                                      attrs);
+}
+
+static bool DefineDataElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                              uint32_t index, JS::Handle<JS::Value> value,
+                              unsigned attrs) {
+  cx->check(obj, value);
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  JS::Rooted<jsid> id(cx);
+  if (!IndexToId(cx, index, &id)) {
+    return false;
+  }
+  return ::DefineDataPropertyById(cx, obj, id, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index, JS::Handle<JS::Value> value,
+                                    unsigned attrs) {
+  return ::DefineDataElement(cx, obj, index, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index,
+                                    JS::Handle<JSObject*> getter,
+                                    JS::Handle<JSObject*> setter,
+                                    unsigned attrs) {
+  JS::Rooted<jsid> id(cx);
+  if (!IndexToId(cx, index, &id)) {
+    return false;
+  }
+  return ::DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index,
+                                    JS::Handle<JSObject*> valueArg,
+                                    unsigned attrs) {
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*valueArg));
+  return ::DefineDataElement(cx, obj, index, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index, HandleString valueArg,
+                                    unsigned attrs) {
+  JS::Rooted<JS::Value> value(cx, JS::StringValue(valueArg));
+  return ::DefineDataElement(cx, obj, index, value, attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index, int32_t valueArg,
+                                    unsigned attrs) {
+  JS::Value value = JS::Int32Value(valueArg);
+  return ::DefineDataElement(
+      cx, obj, index, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index, uint32_t valueArg,
+                                    unsigned attrs) {
+  JS::Value value = JS::NumberValue(valueArg);
+  return ::DefineDataElement(
+      cx, obj, index, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index, double valueArg,
+                                    unsigned attrs) {
+  JS::Value value = JS::NumberValue(valueArg);
+  return ::DefineDataElement(
+      cx, obj, index, JS::Handle<JS::Value>::fromMarkedLocation(&value), attrs);
+}
+
+JS_PUBLIC_API bool JS_HasPropertyById(JSContext* cx, JS::Handle<JSObject*> obj,
+                                      JS::Handle<jsid> id, bool* foundp) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id);
+
+  return js::HasProperty(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_HasProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                  const char* name, bool* foundp) {
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_HasPropertyById(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_HasUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    const char16_t* name, size_t namelen,
+                                    bool* foundp) {
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_HasPropertyById(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_HasElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                 uint32_t index, bool* foundp) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  JS::Rooted<jsid> id(cx);
+  if (!IndexToId(cx, index, &id)) {
+    return false;
+  }
+  return JS_HasPropertyById(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_HasOwnPropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id, bool* foundp) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id);
+
+  return js::HasOwnProperty(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_HasOwnProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name, bool* foundp) {
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_HasOwnPropertyById(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_ForwardGetPropertyTo(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           JS::Handle<jsid> id,
+                                           JS::Handle<JS::Value> receiver,
+                                           JS::MutableHandle<JS::Value> vp) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id, receiver);
+
+  return js::GetProperty(cx, obj, receiver, id, vp);
+}
+
+JS_PUBLIC_API bool JS_ForwardGetElementTo(JSContext* cx,
+                                          JS::Handle<JSObject*> obj,
+                                          uint32_t index,
+                                          JS::Handle<JSObject*> receiver,
+                                          JS::MutableHandle<JS::Value> vp) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj);
+
+  return js::GetElement(cx, obj, receiver, index, vp);
+}
+
+JS_PUBLIC_API bool JS_GetPropertyById(JSContext* cx, JS::Handle<JSObject*> obj,
+                                      JS::Handle<jsid> id,
+                                      JS::MutableHandle<JS::Value> vp) {
+  JS::Rooted<JS::Value> receiver(cx, JS::ObjectValue(*obj));
+  return JS_ForwardGetPropertyTo(cx, obj, id, receiver, vp);
+}
+
+JS_PUBLIC_API bool JS_GetProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                  const char* name,
+                                  JS::MutableHandle<JS::Value> vp) {
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_GetPropertyById(cx, obj, id, vp);
+}
+
+JS_PUBLIC_API bool JS_GetUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    const char16_t* name, size_t namelen,
+                                    JS::MutableHandle<JS::Value> vp) {
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_GetPropertyById(cx, obj, id, vp);
+}
+
+JS_PUBLIC_API bool JS_GetElement(JSContext* cx, JS::Handle<JSObject*> objArg,
+                                 uint32_t index,
+                                 JS::MutableHandle<JS::Value> vp) {
+  return JS_ForwardGetElementTo(cx, objArg, index, objArg, vp);
+}
+
+JS_PUBLIC_API bool JS_ForwardSetPropertyTo(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           JS::Handle<jsid> id,
+                                           JS::Handle<JS::Value> v,
+                                           JS::Handle<JS::Value> receiver,
+                                           JS::ObjectOpResult& result) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id, v, receiver);
+
+  return js::SetProperty(cx, obj, id, v, receiver, result);
+}
+
+JS_PUBLIC_API bool JS_SetPropertyById(JSContext* cx, JS::Handle<JSObject*> obj,
+                                      JS::Handle<jsid> id,
+                                      JS::Handle<JS::Value> v) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id, v);
+
+  JS::Rooted<JS::Value> receiver(cx, JS::ObjectValue(*obj));
+  JS::ObjectOpResult ignored;
+  return js::SetProperty(cx, obj, id, v, receiver, ignored);
+}
+
+JS_PUBLIC_API bool JS_SetProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                  const char* name, JS::Handle<JS::Value> v) {
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_SetPropertyById(cx, obj, id, v);
+}
+
+JS_PUBLIC_API bool JS_SetUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    const char16_t* name, size_t namelen,
+                                    JS::Handle<JS::Value> v) {
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_SetPropertyById(cx, obj, id, v);
+}
+
+static bool SetElement(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t index,
+                       JS::Handle<JS::Value> v) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, v);
+
+  JS::Rooted<JS::Value> receiver(cx, JS::ObjectValue(*obj));
+  JS::ObjectOpResult ignored;
+  return js::SetElement(cx, obj, index, v, receiver, ignored);
+}
+
+JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                 uint32_t index, JS::Handle<JS::Value> v) {
+  return ::SetElement(cx, obj, index, v);
+}
+
+JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                 uint32_t index, JS::Handle<JSObject*> v) {
+  JS::Rooted<JS::Value> value(cx, JS::ObjectOrNullValue(v));
+  return ::SetElement(cx, obj, index, value);
+}
+
+JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                 uint32_t index, HandleString v) {
+  JS::Rooted<JS::Value> value(cx, JS::StringValue(v));
+  return ::SetElement(cx, obj, index, value);
+}
+
+JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                 uint32_t index, int32_t v) {
+  JS::Rooted<JS::Value> value(cx, JS::NumberValue(v));
+  return ::SetElement(cx, obj, index, value);
+}
+
+JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                 uint32_t index, uint32_t v) {
+  JS::Rooted<JS::Value> value(cx, JS::NumberValue(v));
+  return ::SetElement(cx, obj, index, value);
+}
+
+JS_PUBLIC_API bool JS_SetElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                 uint32_t index, double v) {
+  JS::Rooted<JS::Value> value(cx, JS::NumberValue(v));
+  return ::SetElement(cx, obj, index, value);
+}
+
+JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id,
+                                         JS::ObjectOpResult& result) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id);
+
+  return js::DeleteProperty(cx, obj, id, result);
+}
+
+JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name,
+                                     JS::ObjectOpResult& result) {
+  CHECK_THREAD(cx);
+  cx->check(obj);
+
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return js::DeleteProperty(cx, obj, id, result);
+}
+
+JS_PUBLIC_API bool JS_DeleteUCProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const char16_t* name, size_t namelen,
+                                       JS::ObjectOpResult& result) {
+  CHECK_THREAD(cx);
+  cx->check(obj);
+
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return js::DeleteProperty(cx, obj, id, result);
+}
+
+JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index,
+                                    JS::ObjectOpResult& result) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj);
+
+  return js::DeleteElement(cx, obj, index, result);
+}
+
+JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx,
+                                         JS::Handle<JSObject*> obj,
+                                         JS::Handle<jsid> id) {
+  JS::ObjectOpResult ignored;
+  return JS_DeletePropertyById(cx, obj, id, ignored);
+}
+
+JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, JS::Handle<JSObject*> obj,
+                                     const char* name) {
+  JS::ObjectOpResult ignored;
+  return JS_DeleteProperty(cx, obj, name, ignored);
+}
+
+JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, JS::Handle<JSObject*> obj,
+                                    uint32_t index) {
+  JS::ObjectOpResult ignored;
+  return JS_DeleteElement(cx, obj, index, ignored);
+}
+
+JS_PUBLIC_API bool JS_Enumerate(JSContext* cx, JS::Handle<JSObject*> obj,
+                                JS::MutableHandle<IdVector> props) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, props);
+  MOZ_ASSERT(props.empty());
+
+  JS::RootedVector<JS::PropertyKey> ids(cx);
+  if (!js::GetPropertyKeys(cx, obj, JSITER_OWNONLY, &ids)) {
+    return false;
+  }
+
+  return props.append(ids.begin(), ids.end());
+}
+
+JS_PUBLIC_API JSObject* JS_DefineObject(JSContext* cx,
+                                        JS::Handle<JSObject*> obj,
+                                        const char* name, const JSClass* clasp,
+                                        unsigned attrs) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj);
+
+  if (!clasp) {
+    clasp = &PlainObject::class_; /* default class is Object */
+  }
+
+  JS::Rooted<JSObject*> nobj(cx, NewBuiltinClassInstance(cx, clasp));
+  if (!nobj) {
+    return nullptr;
+  }
+
+  JS::Rooted<JS::Value> nobjValue(cx, JS::ObjectValue(*nobj));
+  if (!::DefineDataProperty(cx, obj, name, nobjValue, attrs)) {
+    return nullptr;
+  }
+
+  return nobj;
+}
+
+JS_PUBLIC_API bool JS_DefineProperties(JSContext* cx, JS::Handle<JSObject*> obj,
+                                       const JSPropertySpec* ps) {
+  JS::Rooted<jsid> id(cx);
+
+  for (; ps->name; ps++) {
+    if (!PropertySpecNameToId(cx, ps->name, &id)) {
+      return false;
+    }
+
+    if (ps->isAccessor()) {
+      if (ps->isSelfHosted()) {
+        if (!::DefineSelfHostedProperty(
+                cx, obj, id, ps->u.accessors.getter.selfHosted.funname,
+                ps->u.accessors.setter.selfHosted.funname, ps->attributes())) {
+          return false;
+        }
+      } else {
+        if (!::DefineAccessorPropertyById(
+                cx, obj, id, ps->u.accessors.getter.native,
+                ps->u.accessors.setter.native, ps->attributes())) {
+          return false;
+        }
+      }
+    } else {
+      JS::Rooted<JS::Value> v(cx);
+      if (!ps->getValue(cx, &v)) {
+        return false;
+      }
+
+      if (!::DefineDataPropertyById(cx, obj, id, v, ps->attributes())) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+JS_PUBLIC_API bool JS_AlreadyHasOwnPropertyById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                bool* foundp) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id);
+
+  if (!obj->is<NativeObject>()) {
+    return js::HasOwnProperty(cx, obj, id, foundp);
+  }
+
+  PropertyResult prop;
+  if (!NativeLookupOwnPropertyNoResolve(cx, &obj->as<NativeObject>(), id,
+                                        &prop)) {
+    return false;
+  }
+  *foundp = prop.isFound();
+  return true;
+}
+
+JS_PUBLIC_API bool JS_AlreadyHasOwnProperty(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name, bool* foundp) {
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_AlreadyHasOwnUCProperty(JSContext* cx,
+                                              JS::Handle<JSObject*> obj,
+                                              const char16_t* name,
+                                              size_t namelen, bool* foundp) {
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return false;
+  }
+  JS::Rooted<jsid> id(cx, AtomToId(atom));
+  return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_AlreadyHasOwnElement(JSContext* cx,
+                                           JS::Handle<JSObject*> obj,
+                                           uint32_t index, bool* foundp) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  JS::Rooted<jsid> id(cx);
+  if (!IndexToId(cx, index, &id)) {
+    return false;
+  }
+  return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
+}
+
+JS_PUBLIC_API bool JS_DefineFunctions(JSContext* cx, JS::Handle<JSObject*> obj,
+                                      const JSFunctionSpec* fs) {
+  MOZ_ASSERT(!cx->zone()->isAtomsZone());
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj);
+
+  return js::DefineFunctions(cx, obj, fs, NotIntrinsic);
+}
+
+JS_PUBLIC_API JSFunction* JS_DefineFunction(JSContext* cx,
+                                            JS::Handle<JSObject*> obj,
+                                            const char* name, JSNative call,
+                                            unsigned nargs, unsigned attrs) {
+  MOZ_ASSERT(!cx->zone()->isAtomsZone());
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj);
+  JSAtom* atom = Atomize(cx, name, strlen(name));
+  if (!atom) {
+    return nullptr;
+  }
+  Rooted<jsid> id(cx, AtomToId(atom));
+  return js::DefineFunction(cx, obj, id, call, nargs, attrs);
+}
+
+JS_PUBLIC_API JSFunction* JS_DefineUCFunction(JSContext* cx,
+                                              JS::Handle<JSObject*> obj,
+                                              const char16_t* name,
+                                              size_t namelen, JSNative call,
+                                              unsigned nargs, unsigned attrs) {
+  MOZ_ASSERT(!cx->zone()->isAtomsZone());
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj);
+  JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
+  if (!atom) {
+    return nullptr;
+  }
+  Rooted<jsid> id(cx, AtomToId(atom));
+  return js::DefineFunction(cx, obj, id, call, nargs, attrs);
+}
+
+JS_PUBLIC_API JSFunction* JS_DefineFunctionById(JSContext* cx,
+                                                JS::Handle<JSObject*> obj,
+                                                JS::Handle<jsid> id,
+                                                JSNative call, unsigned nargs,
+                                                unsigned attrs) {
+  MOZ_ASSERT(!cx->zone()->isAtomsZone());
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(obj, id);
+  return js::DefineFunction(cx, obj, id, call, nargs, attrs);
+}
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -20,16 +20,17 @@
 
 #include "gc/FreeOp.h"
 #include "gc/HashUtil.h"
 #include "gc/Marking.h"
 #include "gc/Policy.h"
 #include "gc/Rooting.h"
 #include "js/CharacterEncoding.h"
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
+#include "js/PropertyAndElement.h"    // JS_DefineProperty, JS_GetProperty
 #include "js/PropertySpec.h"
 #include "js/SavedFrameAPI.h"
 #include "js/Vector.h"
 #include "util/DifferentialTesting.h"
 #include "util/StringBuffer.h"
 #include "vm/GeckoProfiler.h"
 #include "vm/JSScript.h"
 #include "vm/Realm.h"
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -52,16 +52,17 @@
 #include "js/CompilationAndEvaluation.h"
 #include "js/Conversions.h"
 #include "js/Date.h"
 #include "js/ErrorReport.h"  // JS::PrintError
 #include "js/Exception.h"
 #include "js/experimental/TypedData.h"  // JS_GetArrayBufferViewType
 #include "js/friend/ErrorMessages.h"    // js::GetErrorMessage, JSMSG_*
 #include "js/Modules.h"                 // JS::GetModulePrivate
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById
 #include "js/PropertySpec.h"
 #include "js/ScalarType.h"  // js::Scalar::Type
 #include "js/SourceText.h"  // JS::SourceText
 #include "js/StableStringChars.h"
 #include "js/Transcoding.h"
 #include "js/Warnings.h"  // JS::{,Set}WarningReporter
 #include "js/Wrapper.h"
 #include "util/StringBuffer.h"
@@ -2381,17 +2382,17 @@ static const JSFunctionSpec intrinsic_fu
     JS_INLINABLE_FN("UnsafeGetReservedSlot", intrinsic_UnsafeGetReservedSlot, 2,
                     0, IntrinsicUnsafeGetReservedSlot),
     JS_INLINABLE_FN("UnsafeGetStringFromReservedSlot",
                     intrinsic_UnsafeGetStringFromReservedSlot, 2, 0,
                     IntrinsicUnsafeGetStringFromReservedSlot),
     JS_INLINABLE_FN("UnsafeSetReservedSlot", intrinsic_UnsafeSetReservedSlot, 3,
                     0, IntrinsicUnsafeSetReservedSlot),
 
-    // Intrinsics and standard functions used by Intl API implementation.
+// Intrinsics and standard functions used by Intl API implementation.
 #ifdef JS_HAS_INTL_API
     JS_FN("intl_BestAvailableLocale", intl_BestAvailableLocale, 3, 0),
     JS_FN("intl_CallCollatorMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<CollatorObject>>, 2, 0),
     JS_FN("intl_CallDateTimeFormatMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<DateTimeFormatObject>>, 2, 0),
     JS_FN("intl_CallDisplayNamesMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<DisplayNamesObject>>, 2, 0),
--- a/js/src/vm/StringType.cpp
+++ b/js/src/vm/StringType.cpp
@@ -28,16 +28,17 @@
 
 #include "builtin/Boolean.h"
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/ParserAtom.h"
 #include "gc/MaybeRooted.h"
 #include "gc/Nursery.h"
 #include "js/CharacterEncoding.h"
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
+#include "js/PropertyAndElement.h"    // JS_DefineElement
 #include "js/StableStringChars.h"
 #include "js/Symbol.h"
 #include "js/UbiNode.h"
 #include "util/StringBuffer.h"
 #include "util/Unicode.h"
 #include "vm/GeckoProfiler.h"
 #include "vm/ToSource.h"  // js::ValueToSource
 
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -45,20 +45,21 @@
 #include "builtin/DataViewObject.h"
 #include "builtin/MapObject.h"
 #include "js/Array.h"        // JS::GetArrayLength, JS::IsArrayObject
 #include "js/ArrayBuffer.h"  // JS::{ArrayBufferHasData,DetachArrayBuffer,IsArrayBufferObject,New{,Mapped}ArrayBufferWithContents,ReleaseMappedArrayBufferContents}
 #include "js/Date.h"
 #include "js/experimental/TypedData.h"  // JS_NewDataView, JS_New{{Ui,I}nt{8,16,32},Float{32,64},Uint8Clamped,Big{Ui,I}nt64}ArrayWithBuffer
 #include "js/friend/ErrorMessages.h"    // js::GetErrorMessage, JSMSG_*
 #include "js/GCHashTable.h"
-#include "js/Object.h"             // JS::GetBuiltinClass
-#include "js/RegExpFlags.h"        // JS::RegExpFlag, JS::RegExpFlags
-#include "js/ScalarType.h"         // js::Scalar::Type
-#include "js/SharedArrayBuffer.h"  // JS::IsSharedArrayBufferObject
+#include "js/Object.h"              // JS::GetBuiltinClass
+#include "js/PropertyAndElement.h"  // JS_GetElement
+#include "js/RegExpFlags.h"         // JS::RegExpFlag, JS::RegExpFlags
+#include "js/ScalarType.h"          // js::Scalar::Type
+#include "js/SharedArrayBuffer.h"   // JS::IsSharedArrayBufferObject
 #include "js/Wrapper.h"
 #include "vm/BigIntType.h"
 #include "vm/JSContext.h"
 #include "vm/PlainObject.h"  // js::PlainObject
 #include "vm/RegExpObject.h"
 #include "vm/SavedFrame.h"
 #include "vm/SharedArrayObject.h"
 #include "vm/TypedArrayObject.h"
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -33,17 +33,18 @@
 #include "jit/Simulator.h"
 #if defined(JS_CODEGEN_X64)  // Assembler::HasSSE41
 #  include "jit/x64/Assembler-x64.h"
 #  include "jit/x86-shared/Architecture-x86-shared.h"
 #  include "jit/x86-shared/Assembler-x86-shared.h"
 #endif
 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
 #include "js/Printf.h"
-#include "js/PropertySpec.h"  // JS_{PS,FN}{,_END}
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty
+#include "js/PropertySpec.h"        // JS_{PS,FN}{,_END}
 #include "util/StringBuffer.h"
 #include "util/Text.h"
 #include "vm/ErrorObject.h"
 #include "vm/FunctionFlags.h"      // js::FunctionFlags
 #include "vm/GlobalObject.h"       // js::GlobalObject
 #include "vm/HelperThreadState.h"  // js::PromiseHelperTask
 #include "vm/Interpreter.h"
 #include "vm/PlainObject.h"    // js::PlainObject
--- a/js/src/wasm/WasmModule.cpp
+++ b/js/src/wasm/WasmModule.cpp
@@ -19,16 +19,17 @@
 #include "wasm/WasmModule.h"
 
 #include <chrono>
 
 #include "jit/JitOptions.h"
 #include "js/BuildId.h"                 // JS::BuildIdCharVector
 #include "js/experimental/TypedData.h"  // JS_NewUint8Array
 #include "js/friend/ErrorMessages.h"    // js::GetErrorMessage, JSMSG_*
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById
 #include "threading/LockGuard.h"
 #include "vm/HelperThreadState.h"  // Tier2GeneratorTask
 #include "vm/PlainObject.h"        // js::PlainObject
 #include "wasm/WasmBaselineCompile.h"
 #include "wasm/WasmCompile.h"
 #include "wasm/WasmInstance.h"
 #include "wasm/WasmIonCompile.h"
 #include "wasm/WasmJS.h"
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -20,16 +20,17 @@
 #include "jsapi.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
 #include "js/CharacterEncoding.h"
 #include "js/CompilationAndEvaluation.h"
 #include "js/CompileOptions.h"         // JS::CompileOptions
 #include "js/friend/JSMEnvironment.h"  // JS::ExecuteInJSMEnvironment, JS::GetJSMEnvironmentOfScriptedCaller, JS::NewJSMEnvironment
 #include "js/Object.h"                 // JS::GetCompartment
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions, JS_DefineProperty, JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById, JS_HasOwnProperty, JS_HasOwnPropertyById, JS_SetProperty, JS_SetPropertyById
 #include "js/PropertySpec.h"
 #include "js/SourceText.h"  // JS::SourceText
 #include "nsCOMPtr.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsExceptionHandler.h"
 #include "nsIComponentManager.h"
 #include "mozilla/Module.h"
--- a/js/xpconnect/loader/nsImportModule.cpp
+++ b/js/xpconnect/loader/nsImportModule.cpp
@@ -6,16 +6,17 @@
 
 #include "nsImportModule.h"
 
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozJSComponentLoader.h"
 #include "xpcpublic.h"
 #include "xpcprivate.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 
 using mozilla::dom::AutoJSAPI;
 
 namespace mozilla {
 namespace loader {
 
 nsresult ImportModule(const char* aURI, const char* aExportName,
                       const nsIID& aIID, void** aResult) {
--- a/js/xpconnect/src/ExportHelpers.cpp
+++ b/js/xpconnect/src/ExportHelpers.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 "xpcprivate.h"
 #include "WrapperFactory.h"
 #include "AccessCheck.h"
 #include "jsfriendapi.h"
 #include "js/Exception.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById
 #include "js/Proxy.h"
 #include "js/Wrapper.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/Unused.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/BlobBinding.h"
 #include "mozilla/dom/BlobImpl.h"
 #include "mozilla/dom/File.h"
--- a/js/xpconnect/src/JSServices.cpp
+++ b/js/xpconnect/src/JSServices.cpp
@@ -3,17 +3,18 @@
 /* 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 "xpcprivate.h"
 #include "StaticComponents.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/ProfilerLabels.h"
-#include "js/String.h"  // JS::LinearStringHasLatin1Chars
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById
+#include "js/String.h"              // JS::LinearStringHasLatin1Chars
 #include "nsJSUtils.h"
 
 using namespace mozilla;
 using namespace JS;
 
 namespace xpc {
 
 static bool Services_NewEnumerate(JSContext* cx, HandleObject obj,
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -9,16 +9,17 @@
  */
 
 #include "AccessCheck.h"
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
 #include "js/CharacterEncoding.h"
 #include "js/CompilationAndEvaluation.h"
 #include "js/Object.h"  // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot
+#include "js/PropertyAndElement.h"  // JS_DefineFunction, JS_DefineFunctions, JS_DefineProperty, JS_GetElement, JS_GetProperty, JS_HasProperty, JS_SetProperty, JS_SetPropertyById
 #include "js/PropertyDescriptor.h"  // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById, JS_GetPropertyDescriptorById
 #include "js/PropertySpec.h"
 #include "js/Proxy.h"
 #include "js/SourceText.h"
 #include "js/StructuredClone.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsIException.h"  // for nsIStackFrame
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -16,16 +16,17 @@
 #include "nsContentUtils.h"
 #include "nsCycleCollector.h"
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::IsArrayObject
 #include "js/CharacterEncoding.h"
 #include "js/ContextOptions.h"
 #include "js/friend/WindowProxy.h"  // js::ToWindowProxyIfWindow
 #include "js/Object.h"              // JS::GetClass, JS::GetCompartment
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById, JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_HasProperty, JS_SetProperty, JS_SetPropertyById
 #include "js/SavedFrameAPI.h"
 #include "js/StructuredClone.h"
 #include "mozilla/AppShutdown.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/Preferences.h"
 #include "nsJSEnvironment.h"
 #include "mozilla/BasePrincipal.h"
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -22,18 +22,19 @@
 #include "nsWrapperCacheInlines.h"
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
 #include "js/CharacterEncoding.h"
 #include "js/experimental/TypedData.h"  // JS_GetArrayBufferViewType, JS_GetArrayBufferViewData, JS_GetTypedArrayLength, JS_IsTypedArrayObject
 #include "js/MemoryFunctions.h"
-#include "js/Object.h"  // JS::GetClass
-#include "js/String.h"  // JS::StringHasLatin1Chars
+#include "js/Object.h"              // JS::GetClass
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_GetElement
+#include "js/String.h"              // JS::StringHasLatin1Chars
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/PrimitiveConversions.h"
 #include "mozilla/dom/Promise.h"
 
 using namespace xpc;
 using namespace mozilla;
--- a/js/xpconnect/src/XPCInlines.h
+++ b/js/xpconnect/src/XPCInlines.h
@@ -6,16 +6,18 @@
 
 /* private inline methods (#include'd by xpcprivate.h). */
 
 #ifndef xpcinlines_h___
 #define xpcinlines_h___
 
 #include <algorithm>
 
+#include "js/PropertyAndElement.h"  // JS_HasProperty, JS_HasPropertyById
+
 /***************************************************************************/
 
 inline void XPCJSRuntime::AddVariantRoot(XPCTraceableVariant* variant) {
   variant->AddToRootSet(&mVariantRoots);
 }
 
 inline void XPCJSRuntime::AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS) {
   wrappedJS->AddToRootSet(&mWrappedJSRoots);
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -4,17 +4,18 @@
  * 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/. */
 
 /* An xpcom implementation of the JavaScript nsIID and nsCID objects. */
 
 #include "xpcprivate.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Attributes.h"
-#include "js/Object.h"  // JS::GetClass, JS::GetReservedSlot
+#include "js/Object.h"              // JS::GetClass, JS::GetReservedSlot
+#include "js/PropertyAndElement.h"  // JS_DefineFunction, JS_DefineFunctionById, JS_DefineProperty, JS_DefinePropertyById
 #include "js/Symbol.h"
 #include "nsContentUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace JS;
 
 namespace xpc {
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -7,16 +7,17 @@
 #include "nsXULAppAPI.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::NewArrayObject
 #include "js/CharacterEncoding.h"
 #include "js/CompilationAndEvaluation.h"  // JS::Evaluate
 #include "js/ContextOptions.h"
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineFunctions, JS_DefineProperty
 #include "js/PropertySpec.h"
 #include "js/SourceText.h"  // JS::SourceText
 #include "mozilla/ChaosMode.h"
 #include "mozilla/dom/AutoEntryScript.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/IOInterposer.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/Range.h"
 
 #include "xpcprivate.h"
 
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
 #include "js/friend/StackLimits.h"  // js::AutoCheckRecursionLimit
 #include "js/friend/WindowProxy.h"  // js::ToWindowIfWindowProxy
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "js/Wrapper.h"
 
 using namespace JS;
 using namespace mozilla;
 
 NS_IMPL_CLASSINFO(XPCVariant, nullptr, 0, XPCVARIANT_CID)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCVariant)
   NS_INTERFACE_MAP_ENTRY(XPCVariant)
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.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/. */
 
 /* Sharable code and data for wrapper around JSObjects. */
 
 #include "xpcprivate.h"
 #include "js/Object.h"  // JS::GetClass
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_HasProperty, JS_HasPropertyById, JS_SetProperty, JS_SetPropertyById
 #include "nsArrayEnumerator.h"
 #include "nsINamed.h"
 #include "nsIScriptError.h"
 #include "nsWrapperCache.h"
 #include "AccessCheck.h"
 #include "nsJSUtils.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Attributes.h"
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -9,16 +9,17 @@
 #include "xpcprivate.h"
 #include "nsWrapperCacheInlines.h"
 #include "XPCLog.h"
 #include "js/Array.h"                   // JS::GetArrayLength, JS::IsArrayObject
 #include "js/experimental/TypedData.h"  // JS_GetTypedArrayLength, JS_IsTypedArrayObject
 #include "js/MemoryFunctions.h"
 #include "js/Object.h"  // JS::GetPrivate, JS::SetPrivate, JS::SetReservedSlot
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_GetPropertyById, JS_SetProperty, JS_SetPropertyById
 #include "jsfriendapi.h"
 #include "AccessCheck.h"
 #include "WrapperFactory.h"
 #include "XrayWrapper.h"
 
 #include "nsContentUtils.h"
 #include "nsCycleCollectionNoteRootCallback.h"
 
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -9,16 +9,17 @@
 #include "xpcprivate.h"
 #include "xpc_make_class.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Preferences.h"
 #include "js/CharacterEncoding.h"
 #include "js/Class.h"
 #include "js/Object.h"  // JS::GetClass
 #include "js/Printf.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById, JS_GetProperty, JS_GetPropertyById
 #include "js/Symbol.h"
 
 using namespace mozilla;
 using namespace JS;
 
 /***************************************************************************/
 
 // All of the exceptions thrown into JS from this file go through here.
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -12,17 +12,18 @@
 #include "nsContentUtils.h"
 #include "nsCycleCollectionNoteRootCallback.h"
 #include "ExpandedPrincipal.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Unused.h"
 #include "mozJSComponentLoader.h"
-#include "js/Object.h"  // JS::GetCompartment
+#include "js/Object.h"              // JS::GetCompartment
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById
 
 #include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla;
 using namespace xpc;
 using namespace JS;
 
 /***************************************************************************/
--- a/js/xpconnect/src/XPCWrapper.cpp
+++ b/js/xpconnect/src/XPCWrapper.cpp
@@ -4,16 +4,18 @@
  * 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 "xpcprivate.h"
 #include "XPCWrapper.h"
 #include "WrapperFactory.h"
 #include "AccessCheck.h"
 
+#include "js/PropertyAndElement.h"  // JS_DefineFunction
+
 using namespace xpc;
 using namespace mozilla;
 using namespace JS;
 
 namespace XPCNativeWrapper {
 
 static inline bool ThrowException(nsresult ex, JSContext* cx) {
   XPCThrower::Throw(ex, cx);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -91,16 +91,17 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "xpcpublic.h"
 #include "js/HashTable.h"
 #include "js/GCHashTable.h"
 #include "js/Object.h"  // JS::GetClass, JS::GetCompartment, JS::GetPrivate
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "js/TracingAPI.h"
 #include "js/WeakMapPtr.h"
 #include "PLDHashTable.h"
 #include "nscore.h"
 #include "nsXPCOM.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
 #include "nsISupports.h"
--- a/js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.cpp
+++ b/js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.cpp
@@ -7,27 +7,28 @@
 #include "xpcrtfuzzing/xpcrtfuzzing.h"
 
 #include "mozilla/Assertions.h"  // MOZ_CRASH
 #include "mozilla/Utf8.h"        // mozilla::Utf8Unit
 
 #include <stdio.h>  // fflush, fprintf, fputs
 
 #include "FuzzingInterface.h"
-#include "jsapi.h"  // JS_ClearPendingException, JS_IsExceptionPending, JS_SetProperty
+#include "jsapi.h"  // JS_SetProperty
 
 #include "js/CompilationAndEvaluation.h"  // JS::Evaluate
 #include "js/CompileOptions.h"            // JS::CompileOptions
 #include "js/Conversions.h"               // JS::Conversions
 #include "js/ErrorReport.h"               // JS::PrintError
 #include "js/Exception.h"                 // JS::StealPendingExceptionStack
 #include "js/experimental/TypedData.h"  // JS_GetUint8ClampedArrayData, JS_NewUint8ClampedArray
-#include "js/RootingAPI.h"  // JS::Rooted
-#include "js/SourceText.h"  // JS::Source{Ownership,Text}
-#include "js/Value.h"       // JS::Value
+#include "js/PropertyAndElement.h"  // JS_SetProperty
+#include "js/RootingAPI.h"          // JS::Rooted
+#include "js/SourceText.h"          // JS::Source{Ownership,Text}
+#include "js/Value.h"               // JS::Value
 
 using mozilla::dom::AutoJSAPI;
 
 static AutoJSAPI* gJsapi = nullptr;
 static std::string gFuzzModuleName;
 
 static void CrashOnPendingException() {
   if (gJsapi->HasException()) {
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -18,16 +18,17 @@
 #include "XPCWrapper.h"
 #include "xpcprivate.h"
 
 #include "jsapi.h"
 #include "js/experimental/TypedData.h"  // JS_GetTypedArrayLength
 #include "js/friend/WindowProxy.h"      // js::IsWindowProxy
 #include "js/friend/XrayJitInfo.h"      // JS::XrayJitInfo
 #include "js/Object.h"  // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot, JS::SetReservedSlot
+#include "js/PropertyAndElement.h"  // JS_AlreadyHasOwnPropertyById, JS_DefineProperty, JS_DefinePropertyById, JS_DeleteProperty, JS_DeletePropertyById, JS_HasProperty, JS_HasPropertyById
 #include "js/PropertyDescriptor.h"  // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById, JS_GetPropertyDescriptorById
 #include "js/PropertySpec.h"
 #include "nsJSUtils.h"
 #include "nsPrintfCString.h"
 
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/BrowsingContext.h"
--- a/mobile/android/components/geckoview/GeckoViewHistory.cpp
+++ b/mobile/android/components/geckoview/GeckoViewHistory.cpp
@@ -1,17 +1,18 @@
 /* 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 "GeckoViewHistory.h"
 
 #include "JavaBuiltins.h"
 #include "jsapi.h"
-#include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
+#include "js/Array.h"               // JS::GetArrayLength, JS::IsArrayObject
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "nsIURI.h"
 #include "nsXULAppAPI.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/StaticPrefs_layout.h"
 
 #include "mozilla/dom/ContentParent.h"
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -1,17 +1,18 @@
 /* -*- 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 "mozilla/LoadInfo.h"
 
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement
 #include "mozilla/Assertions.h"
 #include "mozilla/ExpandedPrincipal.h"
 #include "mozilla/dom/CanonicalBrowsingContext.h"
 #include "mozilla/dom/ClientIPCTypes.h"
 #include "mozilla/dom/ClientSource.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/PerformanceStorage.h"
 #include "mozilla/dom/BrowserChild.h"
--- a/netwerk/base/ProxyAutoConfig.cpp
+++ b/netwerk/base/ProxyAutoConfig.cpp
@@ -13,16 +13,17 @@
 #include "nsThreadUtils.h"
 #include "nsIConsoleService.h"
 #include "nsIURLParser.h"
 #include "nsJSUtils.h"
 #include "jsfriendapi.h"
 #include "js/CompilationAndEvaluation.h"  // JS::Compile
 #include "js/ContextOptions.h"
 #include "js/Initialization.h"
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions, JS_GetProperty
 #include "js/PropertySpec.h"
 #include "js/SourceText.h"  // JS::Source{Ownership,Text}
 #include "js/Utility.h"
 #include "js/Warnings.h"  // JS::SetWarningReporter
 #include "prnetdb.h"
 #include "nsITimer.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/SpinEventLoopUntil.h"
--- a/storage/mozStorageAsyncStatementJSHelper.cpp
+++ b/storage/mozStorageAsyncStatementJSHelper.cpp
@@ -12,16 +12,17 @@
 #include "nsString.h"
 #include "nsServiceManagerUtils.h"
 
 #include "mozStorageAsyncStatementJSHelper.h"
 
 #include "mozStorageAsyncStatementParams.h"
 
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefinePropertyById
 
 #include "xpc_make_class.h"
 
 namespace mozilla {
 namespace storage {
 
 ////////////////////////////////////////////////////////////////////////////////
 //// AsyncStatementJSHelper
--- a/storage/mozStorageStatementJSHelper.cpp
+++ b/storage/mozStorageStatementJSHelper.cpp
@@ -13,16 +13,17 @@
 #include "nsServiceManagerUtils.h"
 
 #include "mozStorageStatementJSHelper.h"
 
 #include "mozStorageStatementRow.h"
 #include "mozStorageStatementParams.h"
 
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_DefineFunction, JS_DefineProperty, JS_DefinePropertyById
 #include "js/Value.h"
 
 #include "xpc_make_class.h"
 
 namespace mozilla {
 namespace storage {
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/storage/mozStorageStatementRow.cpp
+++ b/storage/mozStorageStatementRow.cpp
@@ -8,17 +8,18 @@
 #include "nsString.h"
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/MozStorageStatementRowBinding.h"
 #include "mozStorageStatementRow.h"
 #include "mozStorageStatement.h"
 
 #include "jsapi.h"
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement
 #include "js/Value.h"
 
 #include "xpc_make_class.h"
 
 namespace mozilla {
 namespace storage {
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/toolkit/components/backgroundhangmonitor/HangDetails.cpp
+++ b/toolkit/components/backgroundhangmonitor/HangDetails.cpp
@@ -2,17 +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/. */
 
 #include "HangDetails.h"
 #include "nsIHangDetails.h"
 #include "nsPrintfCString.h"
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement
 #include "mozilla/gfx/GPUParent.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"  // For RemoteTypePrefix
 #include "mozilla/SchedulerGroup.h"
 #include "mozilla/Unused.h"
 #include "mozilla/GfxMessageUtils.h"  // For ParamTraits<GeckoProcessType>
 #include "mozilla/ResultExtensions.h"
 
--- a/toolkit/components/ctypes/ctypes.cpp
+++ b/toolkit/components/ctypes/ctypes.cpp
@@ -2,16 +2,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 "ctypes.h"
 #include "jsapi.h"
 #include "js/experimental/CTypes.h"  // JS::CTypesCallbacks, JS::InitCTypesClass, JS::SetCTypesCallbacks
 #include "js/MemoryFunctions.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 #include "nsMemory.h"
 #include "nsString.h"
 #include "nsNativeCharsetUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozJSComponentLoader.h"
 #include "nsZipArchive.h"
 #include "xpc_make_class.h"
 
--- a/toolkit/components/extensions/ExtensionsParent.cpp
+++ b/toolkit/components/extensions/ExtensionsParent.cpp
@@ -5,16 +5,17 @@
 
 #include "extIWebNavigation.h"
 #include "mozilla/extensions/ExtensionsParent.h"
 #include "mozilla/dom/BrowsingContext.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/RefPtr.h"
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_SetProperty
 #include "nsImportModule.h"
 #include "xpcpublic.h"
 
 namespace mozilla {
 namespace extensions {
 
 ExtensionsParent::ExtensionsParent() {}
 ExtensionsParent::~ExtensionsParent() {}
--- a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp
+++ b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp
@@ -2,16 +2,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 "ExtensionAPIRequestForwarder.h"
 #include "ExtensionEventListener.h"
 
 #include "js/Promise.h"
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "mozilla/dom/Client.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/ClonedErrorHolder.h"
 #include "mozilla/dom/ClonedErrorHolderBinding.h"
 #include "mozilla/dom/ExtensionBrowserBinding.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/SerializedStackHolder.h"
--- a/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
+++ b/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
@@ -2,17 +2,18 @@
  * 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 "FinalizationWitnessService.h"
 
 #include "nsString.h"
 #include "jsapi.h"
 #include "js/CallNonGenericMethod.h"
-#include "js/Object.h"  // JS::GetClass, JS::GetReservedSlot
+#include "js/Object.h"              // JS::GetClass, JS::GetReservedSlot
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions
 #include "js/PropertySpec.h"
 #include "mozJSComponentLoader.h"
 #include "nsIThread.h"
 #include "nsZipArchive.h"
 
 #include "mozilla/Scoped.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
--- a/toolkit/components/glean/bindings/Glean.cpp
+++ b/toolkit/components/glean/bindings/Glean.cpp
@@ -6,16 +6,17 @@
 
 #include "mozilla/dom/DOMJSClass.h"
 #include "mozilla/dom/GleanBinding.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/glean/bindings/Glean.h"
 #include "mozilla/glean/bindings/Category.h"
 #include "mozilla/glean/bindings/GleanJSMetricsLookup.h"
 #include "MainThreadUtils.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 
 namespace mozilla::glean {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(Glean)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Glean)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Glean)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Glean)
--- a/toolkit/components/glean/bindings/GleanPings.cpp
+++ b/toolkit/components/glean/bindings/GleanPings.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/glean/bindings/GleanPings.h"
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DOMJSClass.h"
 #include "mozilla/dom/GleanPingsBinding.h"
 #include "mozilla/glean/bindings/GleanJSPingsLookup.h"
 #include "mozilla/glean/bindings/Ping.h"
 #include "MainThreadUtils.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 
 namespace mozilla::glean {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(GleanPings)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(GleanPings)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(GleanPings)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GleanPings)
--- a/toolkit/components/glean/bindings/private/CustomDistribution.cpp
+++ b/toolkit/components/glean/bindings/private/CustomDistribution.cpp
@@ -10,16 +10,17 @@
 #include "mozilla/Components.h"
 #include "mozilla/ResultVariant.h"
 #include "mozilla/glean/bindings/HistogramGIFFTMap.h"
 #include "mozilla/glean/fog_ffi_generated.h"
 #include "nsIClassInfoImpl.h"
 #include "nsJSUtils.h"
 #include "nsPrintfCString.h"
 #include "nsString.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 
 namespace mozilla::glean {
 
 namespace impl {
 
 void CustomDistributionMetric::AccumulateSamples(
     const nsTArray<uint64_t>& aSamples) const {
   auto hgramId = HistogramIdForMetric(mId);
--- a/toolkit/components/glean/bindings/private/Event.cpp
+++ b/toolkit/components/glean/bindings/private/Event.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/glean/bindings/Event.h"
 
 #include "Common.h"
 #include "nsString.h"
 #include "mozilla/Components.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "nsIClassInfoImpl.h"
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty, JS_Enumerate, JS_GetProperty, JS_GetPropertyById
 #include "nsIScriptError.h"
 
 namespace mozilla::glean {
 
 NS_IMPL_CLASSINFO(GleanEvent, nullptr, 0, {0})
 NS_IMPL_ISUPPORTS_CI(GleanEvent, nsIGleanEvent)
 
 NS_IMETHODIMP
--- a/toolkit/components/glean/bindings/private/MemoryDistribution.cpp
+++ b/toolkit/components/glean/bindings/private/MemoryDistribution.cpp
@@ -8,16 +8,17 @@
 
 #include "mozilla/Components.h"
 #include "mozilla/glean/bindings/HistogramGIFFTMap.h"
 #include "mozilla/glean/fog_ffi_generated.h"
 #include "nsIClassInfoImpl.h"
 #include "nsJSUtils.h"
 #include "nsPrintfCString.h"
 #include "nsString.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 
 namespace mozilla::glean {
 
 namespace impl {
 
 void MemoryDistributionMetric::Accumulate(uint64_t aSample) const {
   auto hgramId = HistogramIdForMetric(mId);
   if (hgramId) {
--- a/toolkit/components/glean/bindings/private/TimingDistribution.cpp
+++ b/toolkit/components/glean/bindings/private/TimingDistribution.cpp
@@ -11,16 +11,17 @@
 #include "mozilla/ResultVariant.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/glean/bindings/HistogramGIFFTMap.h"
 #include "mozilla/glean/fog_ffi_generated.h"
 #include "nsIClassInfoImpl.h"
 #include "nsJSUtils.h"
 #include "nsPrintfCString.h"
 #include "nsString.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 
 namespace mozilla::glean {
 
 namespace impl {
 
 #ifdef MOZ_GLEAN_ANDROID
 // No Glean around to generate these for us.
 static Atomic<uint64_t> gNextTimerId(1);
--- a/toolkit/components/mozintl/MozIntlHelper.cpp
+++ b/toolkit/components/mozintl/MozIntlHelper.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
 /* 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 "MozIntlHelper.h"
 #include "jsapi.h"
-#include "js/experimental/Intl.h"  // JS::AddMozDateTimeFormatConstructor
+#include "js/experimental/Intl.h"   // JS::AddMozDateTimeFormatConstructor
+#include "js/PropertyAndElement.h"  // JS_DefineFunctions
 #include "js/PropertySpec.h"
 #include "js/Wrapper.h"
 
 using namespace mozilla;
 
 NS_IMPL_ISUPPORTS(MozIntlHelper, mozIMozIntlHelper)
 
 MozIntlHelper::MozIntlHelper() = default;
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -34,16 +34,17 @@
 #include "mozilla/Unused.h"
 #include "nsContentUtils.h"  // for nsAutoScriptBlocker
 #include "nsJSUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "nsPrintfCString.h"
 #include "nsTHashtable.h"
 #include "jsapi.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_GetElement, JS_GetProperty
 #include "mozilla/StaticPrefs_layout.h"
 #include "mozilla/dom/ContentProcessMessageManager.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/PlacesObservers.h"
 #include "mozilla/dom/PlacesVisit.h"
 #include "mozilla/dom/PlacesVisitTitle.h"
 #include "mozilla/dom/ScriptSettings.h"
 
--- a/toolkit/components/places/PlaceInfo.cpp
+++ b/toolkit/components/places/PlaceInfo.cpp
@@ -3,17 +3,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PlaceInfo.h"
 #include "VisitInfo.h"
 #include "nsIURI.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement
 
 namespace mozilla {
 namespace places {
 
 ////////////////////////////////////////////////////////////////////////////////
 //// PlaceInfo
 
 PlaceInfo::PlaceInfo(int64_t aId, const nsCString& aGUID,
--- a/toolkit/components/sessionstore/SessionStoreUtils.cpp
+++ b/toolkit/components/sessionstore/SessionStoreUtils.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/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
 #include "js/JSON.h"
+#include "js/PropertyAndElement.h"  // JS_GetElement
 #include "jsapi.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/dom/AutocompleteInfoBinding.h"
 #include "mozilla/dom/CanonicalBrowsingContext.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/DocumentInlines.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLSelectElement.h"
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
@@ -33,16 +33,17 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsWidgetsCID.h"
 #include "nsAppRunner.h"
 #include "nsAppShellCID.h"
 #include "nsXPCOMCIDInternal.h"
 #include "mozilla/Services.h"
 #include "jsapi.h"
 #include "js/Date.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "prenv.h"
 #include "nsAppDirectoryServiceDefs.h"
 
 #if defined(XP_WIN)
 // Prevent collisions with nsAppStartup::GetStartupInfo()
 #  undef GetStartupInfo
 
 #  include <windows.h>
--- a/toolkit/components/telemetry/core/Telemetry.cpp
+++ b/toolkit/components/telemetry/core/Telemetry.cpp
@@ -19,16 +19,17 @@
 #if defined(MOZ_TELEMETRY_GECKOVIEW)
 #  include "geckoview/TelemetryGeckoViewPersistence.h"
 #endif
 #include "ipc/TelemetryIPCAccumulator.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::NewArrayObject
 #include "js/GCAPI.h"
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/BackgroundHangMonitor.h"
 #include "mozilla/Components.h"
 #include "mozilla/DataMutex.h"
 #include "mozilla/DebugOnly.h"
--- a/toolkit/components/telemetry/core/TelemetryEvent.cpp
+++ b/toolkit/components/telemetry/core/TelemetryEvent.cpp
@@ -6,16 +6,17 @@
 
 #include "Telemetry.h"
 #include "TelemetryEvent.h"
 #include <prtime.h>
 #include <limits>
 #include "ipc/TelemetryIPCAccumulator.h"
 #include "jsapi.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty, JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById, JS_HasProperty
 #include "mozilla/Maybe.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Unused.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "nsIObserverService.h"
--- a/toolkit/components/telemetry/core/TelemetryHistogram.cpp
+++ b/toolkit/components/telemetry/core/TelemetryHistogram.cpp
@@ -10,16 +10,17 @@
 #include "base/histogram.h"
 #include "geckoview/streaming/GeckoViewStreamingTelemetry.h"
 #include "ipc/TelemetryIPCAccumulator.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
 #include "js/GCAPI.h"
 #include "js/Object.h"  // JS::GetClass, JS::GetPrivate, JS::SetPrivate
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineFunction, JS_DefineProperty, JS_DefineUCProperty, JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/JSONWriter.h"
 #include "mozilla/StartupTimeline.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/Unused.h"
 #include "nsClassHashtable.h"
--- a/toolkit/components/telemetry/core/TelemetryOrigin.cpp
+++ b/toolkit/components/telemetry/core/TelemetryOrigin.cpp
@@ -9,17 +9,18 @@
 
 #include "nsTHashMap.h"
 #include "nsIObserverService.h"
 #include "nsPrintfCString.h"
 #include "nsTArray.h"
 #include "TelemetryCommon.h"
 #include "TelemetryOriginEnums.h"
 
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty
 #include "mozilla/Atomics.h"
 #include "mozilla/Base64.h"
 #include "mozilla/dom/PrioEncoder.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/Tuple.h"
 #include "mozilla/UniquePtr.h"
--- a/toolkit/components/telemetry/core/TelemetryScalar.cpp
+++ b/toolkit/components/telemetry/core/TelemetryScalar.cpp
@@ -4,17 +4,18 @@
  * 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 "TelemetryScalar.h"
 
 #include "geckoview/streaming/GeckoViewStreamingTelemetry.h"
 #include "ipc/TelemetryComms.h"
 #include "ipc/TelemetryIPCAccumulator.h"
-#include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
+#include "js/Array.h"               // JS::GetArrayLength, JS::IsArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_DefineUCProperty, JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById, JS_HasProperty
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/PContent.h"
 #include "mozilla/JSONWriter.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Unused.h"
 #include "nsBaseHashtable.h"
--- a/toolkit/components/telemetry/other/CombinedStacks.cpp
+++ b/toolkit/components/telemetry/other/CombinedStacks.cpp
@@ -2,17 +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/. */
 
 #include "CombinedStacks.h"
 
 #include "jsapi.h"
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty
 #include "mozilla/HangAnnotations.h"
 
 namespace mozilla::Telemetry {
 
 // The maximum number of chrome hangs stacks that we're keeping.
 const size_t kMaxChromeStacksKept = 50;
 
 CombinedStacks::CombinedStacks() : CombinedStacks(kMaxChromeStacksKept) {}
--- a/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp
+++ b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp
@@ -1,17 +1,18 @@
 /* -*- 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 "TelemetryIOInterposeObserver.h"
 #include "core/TelemetryCommon.h"
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineUCProperty
 #include "nsIFile.h"
 
 namespace mozilla::Telemetry {
 
 TelemetryIOInterposeObserver::TelemetryIOInterposeObserver(nsIFile* aXreDir)
     : mCurStage(STAGE_STARTUP) {
   nsAutoString xreDirPath;
   nsresult rv = aXreDir->GetPath(xreDirPath);
--- a/toolkit/components/telemetry/other/UntrustedModulesDataSerializer.cpp
+++ b/toolkit/components/telemetry/other/UntrustedModulesDataSerializer.cpp
@@ -2,17 +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/. */
 
 #include "UntrustedModulesDataSerializer.h"
 
 #include "core/TelemetryCommon.h"
-#include "js/Array.h"  // JS::NewArrayObject
+#include "js/Array.h"               // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_DefineElement, JS_DefineProperty, JS_GetProperty
 #include "jsapi.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "nsITelemetry.h"
 #include "nsUnicharUtils.h"
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace Telemetry {
--- a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp
+++ b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp
@@ -2,17 +2,18 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 #include "TelemetryTestHelpers.h"
 
 #include "core/TelemetryCommon.h"
 #include "core/TelemetryOrigin.h"
 #include "gtest/gtest.h"
-#include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
+#include "js/Array.h"               // JS::GetArrayLength, JS::IsArrayObject
+#include "js/PropertyAndElement.h"  // JS_Enumerate, JS_GetElement, JS_GetProperty
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/Unused.h"
 #include "nsPrintfCString.h"
 
 using namespace mozilla;
 
 // Helper methods provided to simplify writing tests and meant to be used in C++
 // Gtests.
--- a/toolkit/components/telemetry/tests/gtest/TestEvents.cpp
+++ b/toolkit/components/telemetry/tests/gtest/TestEvents.cpp
@@ -1,16 +1,17 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 #include "core/TelemetryEvent.h"
 #include "gtest/gtest.h"
-#include "js/Array.h"  // JS::GetArrayLength
+#include "js/Array.h"               // JS::GetArrayLength
+#include "js/PropertyAndElement.h"  // JS_GetElement, JS_GetProperty
 #include "mozilla/Maybe.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "TelemetryFixture.h"
 #include "TelemetryTestHelpers.h"
 
 using namespace mozilla;
 using namespace TelemetryTestHelpers;
--- a/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp
+++ b/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/ContentBlockingLog.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "nsIObserverService.h"
 #include "TelemetryFixture.h"
 #include "TelemetryTestHelpers.h"
+#include "js/PropertyAndElement.h"  // JS_Enumerate, JS_GetProperty
 
 using namespace mozilla;
 using namespace TelemetryTestHelpers;
 using mozilla::Telemetry::OriginMetricID;
 using ::testing::_;
 using ::testing::AtLeast;
 using ::testing::StrEq;
 
--- a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp
+++ b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp
@@ -1,16 +1,17 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 #include "core/TelemetryScalar.h"
 #include "gtest/gtest.h"
 #include "js/Conversions.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_HasProperty
 #include "mozilla/Telemetry.h"
 #include "mozilla/TelemetryProcessEnums.h"
 #include "mozilla/Unused.h"
 #include "nsJSUtils.h"  // nsAutoJSString
 #include "nsThreadUtils.h"
 #include "TelemetryFixture.h"
 #include "TelemetryTestHelpers.h"
 
--- a/toolkit/mozapps/extensions/AddonManagerStartup-inlines.h
+++ b/toolkit/mozapps/extensions/AddonManagerStartup-inlines.h
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AddonManagerStartup_inlines_h
 #define AddonManagerStartup_inlines_h
 
 #include <utility>
 
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject
+#include "js/PropertyAndElement.h"  // JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById
 #include "jsapi.h"
 #include "mozilla/Maybe.h"
 #include "nsJSUtils.h"
 
 namespace mozilla {
 
 class ArrayIterElem;
 class PropertyIterElem;
--- a/toolkit/mozapps/extensions/AddonManagerStartup.cpp
+++ b/toolkit/mozapps/extensions/AddonManagerStartup.cpp
@@ -6,16 +6,17 @@
 #include "AddonManagerStartup.h"
 #include "AddonManagerStartup-inlines.h"
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Array.h"  // JS::IsArrayObject
 #include "js/ArrayBuffer.h"
 #include "js/JSON.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_SetProperty
 #include "js/TracingAPI.h"
 #include "xpcpublic.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/EndianUtils.h"
 #include "mozilla/Components.h"
 #include "mozilla/Compression.h"
 #include "mozilla/LinkedList.h"
--- a/tools/fuzzing/messagemanager/MessageManagerFuzzer.cpp
+++ b/tools/fuzzing/messagemanager/MessageManagerFuzzer.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <climits>
 #include <cmath>
 #include "FuzzingTraits.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/CharacterEncoding.h"
+#include "js/PropertyAndElement.h"  // JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_SetProperty, JS_SetPropertyById
 #include "prenv.h"
 #include "MessageManagerFuzzer.h"
 #include "mozilla/ErrorResult.h"
 #include "nsComponentManagerUtils.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsFrameMessageManager.h"
 #include "nsJSUtils.h"
--- a/tools/profiler/gecko/nsProfiler.cpp
+++ b/tools/profiler/gecko/nsProfiler.cpp
@@ -9,16 +9,17 @@
 #include <sstream>
 #include <string>
 #include <utility>
 
 #include "GeckoProfiler.h"
 #include "ProfilerParent.h"
 #include "js/Array.h"  // JS::NewArrayObject
 #include "js/JSON.h"
+#include "js/PropertyAndElement.h"  // JS_SetElement
 #include "js/Value.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/SchedulerGroup.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/Preferences.h"
 #include "nsComponentManagerUtils.h"
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -7,17 +7,18 @@
 
 #include "mozilla/ArrayUtils.h"
 
 #include "GfxInfoBase.h"
 
 #include <mutex>  // std::call_once
 
 #include "GfxDriverInfo.h"
-#include "js/Array.h"  // JS::GetArrayLength, JS::NewArrayObject
+#include "js/Array.h"               // JS::GetArrayLength, JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_SetElement, JS_SetProperty
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
 #include "nsVersionComparator.h"
 #include "mozilla/Services.h"
 #include "mozilla/Observer.h"
 #include "nsIObserver.h"
--- a/widget/GfxInfoCollector.cpp
+++ b/widget/GfxInfoCollector.cpp
@@ -2,16 +2,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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 "GfxInfoCollector.h"
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
 #include "nsString.h"
 
 using namespace mozilla;
 using namespace widget;
 
 void InfoObject::DefineProperty(const char* name, int value) {
   if (!mOk) return;
 
--- a/widget/android/EventDispatcher.cpp
+++ b/widget/android/EventDispatcher.cpp
@@ -5,18 +5,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "EventDispatcher.h"
 
 #include "JavaBuiltins.h"
 #include "nsAppShell.h"
 #include "nsJSUtils.h"
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
-#include "js/String.h"    // JS::StringHasLatin1Chars
-#include "js/Warnings.h"  // JS::WarnUTF8
+#include "js/PropertyAndElement.h"  // JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById, JS_SetElement, JS_SetUCProperty
+#include "js/String.h"              // JS::StringHasLatin1Chars
+#include "js/Warnings.h"            // JS::WarnUTF8
 #include "xpcpublic.h"
 
 #include "mozilla/fallible.h"
 #include "mozilla/ScopeExit.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/java/EventCallbackWrappers.h"
 
 // Disable the C++ 2a warning. See bug #1509926
--- a/widget/cocoa/GfxInfo.mm
+++ b/widget/cocoa/GfxInfo.mm
@@ -9,16 +9,18 @@
 #include "mozilla/ArrayUtils.h"
 
 #include "GfxInfo.h"
 #include "nsUnicharUtils.h"
 #include "nsExceptionHandler.h"
 #include "nsCocoaFeatures.h"
 #include "nsCocoaUtils.h"
 #include "mozilla/Preferences.h"
+#include "js/PropertyAndElement.h"  // JS_SetElement, JS_SetProperty
+
 #include <algorithm>
 
 #import <Foundation/Foundation.h>
 #import <IOKit/IOKitLib.h>
 #import <Cocoa/Cocoa.h>
 
 #include "jsapi.h"
 
--- a/widget/cocoa/nsMacSharingService.mm
+++ b/widget/cocoa/nsMacSharingService.mm
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #import <Cocoa/Cocoa.h>
 
 #include "nsMacSharingService.h"
 
 #include "jsapi.h"
 #include "js/Array.h"  // JS::NewArrayObject
+#include "js/PropertyAndElement.h"  // JS_SetElement, JS_SetProperty
 #include "nsCocoaUtils.h"
 #include "mozilla/MacStringHelpers.h"
 
 NS_IMPL_ISUPPORTS(nsMacSharingService, nsIMacSharingService)
 
 NSString* const remindersServiceName = @"com.apple.reminders.RemindersShareExtension";
 
 // These are some undocumented constants also used by Safari
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GfxInfo.h"
 
 #include "gfxConfig.h"
 #include "GfxDriverInfo.h"
 #include "gfxWindowsPlatform.h"
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_SetElement, JS_SetProperty
 #include "nsExceptionHandler.h"
 #include "nsPrintfCString.h"
 #include "nsUnicharUtils.h"
 #include "prenv.h"
 #include "prprf.h"
 #include "xpcpublic.h"
 
 #include "mozilla/Components.h"
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -57,18 +57,19 @@
 
 #include <algorithm>
 #include <utility>
 
 #include "js/Debug.h"
 #include "js/friend/DumpFunctions.h"  // js::DumpHeap
 #include "js/GCAPI.h"
 #include "js/HeapAPI.h"
-#include "js/Object.h"    // JS::GetClass, JS::GetCompartment, JS::GetPrivate
-#include "js/Warnings.h"  // JS::SetWarningReporter
+#include "js/Object.h"  // JS::GetClass, JS::GetCompartment, JS::GetPrivate
+#include "js/PropertyAndElement.h"  // JS_DefineProperty
+#include "js/Warnings.h"            // JS::SetWarningReporter
 #include "jsfriendapi.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/DebuggerOnGCRunnable.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ProfilerLabels.h"
 #include "mozilla/ProfilerMarkers.h"
--- a/xpcom/base/nsSystemInfo.cpp
+++ b/xpcom/base/nsSystemInfo.cpp
@@ -10,16 +10,17 @@
 #include "nsSystemInfo.h"
 #include "prsystem.h"
 #include "prio.h"
 #include "mozilla/SSE.h"
 #include "mozilla/arm.h"
 #include "mozilla/LazyIdleThread.h"
 #include "mozilla/Sprintf.h"
 #include "jsapi.h"
+#include "js/PropertyAndElement.h"  // JS_SetProperty
 #include "mozilla/dom/Promise.h"
 
 #ifdef XP_WIN
 #  include <comutil.h>
 #  include <time.h>
 #  ifndef __MINGW32__
 #    include <iwscapi.h>
 #  endif  // __MINGW32__
--- a/xpcom/components/StaticComponents.cpp.in
+++ b/xpcom/components/StaticComponents.cpp.in
@@ -22,16 +22,17 @@
 #include "nsIFactory.h"
 #include "nsISupports.h"
 #include "nsIXPConnect.h"
 #include "nsString.h"
 #include "nsStringEnumerator.h"
 #include "nsTArray.h"
 #include "xptdata.h"
 #include "xptinfo.h"
+#include "js/PropertyAndElement.h"  // JS_GetProperty
 
 // Cleanup pollution from zipstruct.h
 #undef UNSUPPORTED
 
 // Public includes
 //# @includes@
 
 // Relative includes
--- a/xpcom/tests/gtest/TestGCPostBarriers.cpp
+++ b/xpcom/tests/gtest/TestGCPostBarriers.cpp
@@ -11,16 +11,17 @@
 
 #include "mozilla/UniquePtr.h"
 
 #include "jsapi.h"
 #include "nsTArray.h"
 
 #include "gtest/gtest.h"
 
+#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_SetProperty
 #include "js/TracingAPI.h"
 #include "js/HeapAPI.h"
 
 #include "mozilla/CycleCollectedJSContext.h"
 
 using namespace JS;
 using namespace mozilla;