Bug 1394835 part 4 - Split js::DefineProperty/DefineElement in separate accessor vs data functions. r=anba
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 07 Sep 2017 14:59:24 +0200
changeset 379552 5eb5af7c30a9
parent 379551 6aa1cc819058
child 379553 8b1881ead0b6
push id32456
push userarchaeopteryx@coole-files.de
push dateThu, 07 Sep 2017 22:00:40 +0000
treeherdermozilla-central@b4c1ad9565ee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanba
bugs1394835
milestone57.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 1394835 part 4 - Split js::DefineProperty/DefineElement in separate accessor vs data functions. r=anba
js/src/builtin/AtomicsObject.cpp
js/src/builtin/Intl.cpp
js/src/builtin/Promise.cpp
js/src/builtin/Reflect.cpp
js/src/builtin/ReflectParse.cpp
js/src/builtin/SIMD.cpp
js/src/builtin/TypedObject.cpp
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jscntxt.cpp
js/src/jscompartment.cpp
js/src/jsfun.cpp
js/src/jsiter.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/json.cpp
js/src/jsstr.cpp
js/src/proxy/BaseProxyHandler.cpp
js/src/proxy/ScriptedProxyHandler.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/DebuggerMemory.cpp
js/src/vm/ErrorObject.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/Interpreter-inl.h
js/src/vm/Interpreter.cpp
js/src/vm/NativeObject.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/StructuredClone.cpp
js/src/vm/UbiNodeCensus.cpp
js/src/wasm/WasmJS.cpp
--- a/js/src/builtin/AtomicsObject.cpp
+++ b/js/src/builtin/AtomicsObject.cpp
@@ -1124,21 +1124,18 @@ AtomicsObject::initClass(JSContext* cx, 
     if (!JS_DefineFunctions(cx, Atomics, AtomicsMethods))
         return nullptr;
     if (!DefineToStringTag(cx, Atomics, cx->names().Atomics))
         return nullptr;
 
     RootedValue AtomicsValue(cx, ObjectValue(*Atomics));
 
     // Everything is set up, install Atomics on the global object.
-    if (!DefineProperty(cx, global, cx->names().Atomics, AtomicsValue, nullptr, nullptr,
-                        JSPROP_RESOLVING))
-    {
+    if (!DefineDataProperty(cx, global, cx->names().Atomics, AtomicsValue, JSPROP_RESOLVING))
         return nullptr;
-    }
 
     global->setConstructor(JSProto_Atomics, AtomicsValue);
     return Atomics;
 }
 
 JSObject*
 js::InitAtomicsClass(JSContext* cx, HandleObject obj)
 {
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -820,21 +820,18 @@ intl_availableLocales(JSContext* cx, Cou
         if (!lang)
             return false;
         char* p;
         while ((p = strchr(lang.get(), '_')))
             *p = '-';
         a = Atomize(cx, lang.get(), strlen(lang.get()));
         if (!a)
             return false;
-        if (!DefineProperty(cx, locales, a->asPropertyName(), TrueHandleValue, nullptr, nullptr,
-                            JSPROP_ENUMERATE))
-        {
+        if (!DefineDataProperty(cx, locales, a->asPropertyName(), TrueHandleValue))
             return false;
-        }
     }
 #endif
     result.setObject(*locales);
     return true;
 }
 
 /**
  * Returns the object holding the internal properties for obj.
@@ -1065,17 +1062,17 @@ CreateCollatorPrototype(JSContext* cx, H
         return nullptr;
 
     // 10.3.2 and 10.3.3
     if (!JS_DefineProperties(cx, proto, collator_properties))
         return nullptr;
 
     // 8.1
     RootedValue ctorValue(cx, ObjectValue(*ctor));
-    if (!DefineProperty(cx, Intl, cx->names().Collator, ctorValue, nullptr, nullptr, 0))
+    if (!DefineDataProperty(cx, Intl, cx->names().Collator, ctorValue, 0))
         return nullptr;
 
     return proto;
 }
 
 bool
 js::intl_Collator_availableLocales(JSContext* cx, unsigned argc, Value* vp)
 {
@@ -1116,17 +1113,17 @@ js::intl_availableCollations(JSContext* 
     RootedObject collations(cx, NewDenseEmptyArray(cx));
     if (!collations)
         return false;
 
     uint32_t index = 0;
 
     // The first element of the collations array must be |null| per
     // ES2017 Intl, 10.2.3 Internal Slots.
-    if (!DefineElement(cx, collations, index++, NullHandleValue))
+    if (!DefineDataElement(cx, collations, index++, NullHandleValue))
         return false;
 
     RootedValue element(cx);
     for (uint32_t i = 0; i < count; i++) {
         const char* collation = uenum_next(values, nullptr, &status);
         if (U_FAILURE(status)) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
             return false;
@@ -1139,17 +1136,17 @@ js::intl_availableCollations(JSContext* 
         if (equal(collation, "standard") || equal(collation, "search"))
             continue;
 
         // ICU returns old-style keyword values; map them to BCP 47 equivalents.
         JSString* jscollation = JS_NewStringCopyZ(cx, uloc_toUnicodeLocaleType("co", collation));
         if (!jscollation)
             return false;
         element = StringValue(jscollation);
-        if (!DefineElement(cx, collations, index++, element))
+        if (!DefineDataElement(cx, collations, index++, element))
             return false;
     }
 
     args.rval().setObject(*collations);
     return true;
 }
 
 /**
@@ -1644,23 +1641,23 @@ CreateNumberFormatPrototype(JSContext* c
         HandlePropertyName name = cx->names().formatToParts;
         if (!GlobalObject::getSelfHostedFunction(cx, cx->global(),
                                                  cx->names().NumberFormatFormatToParts,
                                                  name, 1, &ftp))
         {
             return nullptr;
         }
 
-        if (!DefineProperty(cx, proto, cx->names().formatToParts, ftp, nullptr, nullptr, 0))
+        if (!DefineDataProperty(cx, proto, cx->names().formatToParts, ftp, 0))
             return nullptr;
     }
 
     // 8.1
     RootedValue ctorValue(cx, ObjectValue(*ctor));
-    if (!DefineProperty(cx, Intl, cx->names().NumberFormat, ctorValue, nullptr, nullptr, 0))
+    if (!DefineDataProperty(cx, Intl, cx->names().NumberFormat, ctorValue, 0))
         return nullptr;
 
     constructor.set(ctor);
     return proto;
 }
 
 bool
 js::intl_NumberFormat_availableLocales(JSContext* cx, unsigned argc, Value* vp)
@@ -2303,30 +2300,30 @@ intl_FormatNumberToParts(JSContext* cx, 
 
         MOZ_ASSERT(lastEndIndex < endIndex);
 
         singlePart = NewBuiltinClassInstance<PlainObject>(cx);
         if (!singlePart)
             return false;
 
         propVal.setString(cx->names().*type);
-        if (!DefineProperty(cx, singlePart, cx->names().type, propVal))
+        if (!DefineDataProperty(cx, singlePart, cx->names().type, propVal))
             return false;
 
         JSLinearString* partSubstr =
             NewDependentString(cx, overallResult, lastEndIndex, endIndex - lastEndIndex);
         if (!partSubstr)
             return false;
 
         propVal.setString(partSubstr);
-        if (!DefineProperty(cx, singlePart, cx->names().value, propVal))
+        if (!DefineDataProperty(cx, singlePart, cx->names().value, propVal))
             return false;
 
         propVal.setObject(*singlePart);
-        if (!DefineElement(cx, partsArray, partIndex, propVal))
+        if (!DefineDataElement(cx, partsArray, partIndex, propVal))
             return false;
 
         lastEndIndex = endIndex;
         partIndex++;
     } while (true);
 
     MOZ_ASSERT(lastEndIndex == overallResult->length(),
                "result array must partition the entire string");
@@ -2524,17 +2521,17 @@ CreateDateTimeFormatPrototype(JSContext*
         return nullptr;
 
     // 12.4.2 and 12.4.3
     if (!JS_DefineProperties(cx, proto, dateTimeFormat_properties))
         return nullptr;
 
     // 8.1
     RootedValue ctorValue(cx, ObjectValue(*ctor));
-    if (!DefineProperty(cx, Intl, cx->names().DateTimeFormat, ctorValue, nullptr, nullptr, 0))
+    if (!DefineDataProperty(cx, Intl, cx->names().DateTimeFormat, ctorValue, 0))
         return nullptr;
 
     constructor.set(ctor);
     return proto;
 }
 
 bool
 js::AddMozDateTimeFormatConstructor(JSContext* cx, JS::Handle<JSObject*> intl)
@@ -2611,17 +2608,17 @@ js::intl_availableCalendars(JSContext* c
         return false;
     uint32_t index = 0;
 
     // We need the default calendar for the locale as the first result.
     RootedValue element(cx);
     if (!DefaultCalendar(cx, locale, &element))
         return false;
 
-    if (!DefineElement(cx, calendars, index++, element))
+    if (!DefineDataElement(cx, calendars, index++, element))
         return false;
 
     // Now get the calendars that "would make a difference", i.e., not the default.
     UErrorCode status = U_ZERO_ERROR;
     UEnumeration* values = ucal_getKeywordValuesForLocale("ca", locale.ptr(), false, &status);
     if (U_FAILURE(status)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
@@ -2643,27 +2640,27 @@ js::intl_availableCalendars(JSContext* c
 
         // ICU returns old-style keyword values; map them to BCP 47 equivalents
         calendar = uloc_toUnicodeLocaleType("ca", calendar);
 
         JSString* jscalendar = JS_NewStringCopyZ(cx, calendar);
         if (!jscalendar)
             return false;
         element = StringValue(jscalendar);
-        if (!DefineElement(cx, calendars, index++, element))
+        if (!DefineDataElement(cx, calendars, index++, element))
             return false;
 
         // ICU doesn't return calendar aliases, append them here.
         for (const auto& calendarAlias : calendarAliases) {
             if (equal(calendar, calendarAlias.calendar)) {
                 JSString* jscalendar = JS_NewStringCopyZ(cx, calendarAlias.alias);
                 if (!jscalendar)
                     return false;
                 element = StringValue(jscalendar);
-                if (!DefineElement(cx, calendars, index++, element))
+                if (!DefineDataElement(cx, calendars, index++, element))
                     return false;
             }
         }
     }
 
     args.rval().setObject(*calendars);
     return true;
 }
@@ -3380,30 +3377,30 @@ intl_FormatToPartsDateTime(JSContext* cx
     RootedValue val(cx);
 
     auto AppendPart = [&](FieldType type, size_t beginIndex, size_t endIndex) {
         singlePart = NewBuiltinClassInstance<PlainObject>(cx);
         if (!singlePart)
             return false;
 
         partType = StringValue(cx->names().*type);
-        if (!DefineProperty(cx, singlePart, cx->names().type, partType))
+        if (!DefineDataProperty(cx, singlePart, cx->names().type, partType))
             return false;
 
         JSLinearString* partSubstr =
             NewDependentString(cx, overallResult, beginIndex, endIndex - beginIndex);
         if (!partSubstr)
             return false;
 
         val = StringValue(partSubstr);
-        if (!DefineProperty(cx, singlePart, cx->names().value, val))
+        if (!DefineDataProperty(cx, singlePart, cx->names().value, val))
             return false;
 
         val = ObjectValue(*singlePart);
-        if (!DefineElement(cx, partsArray, partIndex, val))
+        if (!DefineDataElement(cx, partsArray, partIndex, val))
             return false;
 
         lastEndIndex = endIndex;
         partIndex++;
         return true;
     };
 
     int32_t fieldInt, beginIndexInt, endIndexInt;
@@ -3588,17 +3585,17 @@ CreatePluralRulesPrototype(JSContext* cx
 
     if (!JS_DefineFunctions(cx, ctor, pluralRules_static_methods))
         return nullptr;
 
     if (!JS_DefineFunctions(cx, proto, pluralRules_methods))
         return nullptr;
 
     RootedValue ctorValue(cx, ObjectValue(*ctor));
-    if (!DefineProperty(cx, Intl, cx->names().PluralRules, ctorValue, nullptr, nullptr, 0))
+    if (!DefineDataProperty(cx, Intl, cx->names().PluralRules, ctorValue, 0))
         return nullptr;
 
     return proto;
 }
 
 /* static */ bool
 js::GlobalObject::addPluralRulesConstructor(JSContext* cx, HandleObject intl)
 {
@@ -3761,17 +3758,17 @@ js::intl_GetPluralCategories(JSContext* 
             break;
 
         MOZ_ASSERT(catSize >= 0);
         JSString* str = NewStringCopyN<CanGC>(cx, cat, catSize);
         if (!str)
             return false;
 
         element.setString(str);
-        if (!DefineElement(cx, res, i++, element))
+        if (!DefineDataElement(cx, res, i++, element))
             return false;
     } while (true);
 
     args.rval().setObject(*res);
     return true;
 }
 
 
@@ -3921,22 +3918,22 @@ js::intl_GetCalendarInfo(JSContext* cx, 
     RootedObject info(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!info)
         return false;
 
     RootedValue v(cx);
     int32_t firstDayOfWeek = ucal_getAttribute(cal, UCAL_FIRST_DAY_OF_WEEK);
     v.setInt32(firstDayOfWeek);
 
-    if (!DefineProperty(cx, info, cx->names().firstDayOfWeek, v))
+    if (!DefineDataProperty(cx, info, cx->names().firstDayOfWeek, v))
         return false;
 
     int32_t minDays = ucal_getAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK);
     v.setInt32(minDays);
-    if (!DefineProperty(cx, info, cx->names().minDays, v))
+    if (!DefineDataProperty(cx, info, cx->names().minDays, v))
         return false;
 
     UCalendarWeekdayType prevDayType = ucal_getDayOfWeekType(cal, UCAL_SATURDAY, &status);
     if (U_FAILURE(status)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
 
@@ -3974,20 +3971,20 @@ js::intl_GetCalendarInfo(JSContext* cx, 
         }
 
         prevDayType = type;
     }
 
     MOZ_ASSERT(weekendStart.isInt32());
     MOZ_ASSERT(weekendEnd.isInt32());
 
-    if (!DefineProperty(cx, info, cx->names().weekendStart, weekendStart))
+    if (!DefineDataProperty(cx, info, cx->names().weekendStart, weekendStart))
         return false;
 
-    if (!DefineProperty(cx, info, cx->names().weekendEnd, weekendEnd))
+    if (!DefineDataProperty(cx, info, cx->names().weekendEnd, weekendEnd))
         return false;
 
     args.rval().setObject(*info);
     return true;
 }
 
 static void
 ReportBadKey(JSContext* cx, const Range<const JS::Latin1Char>& range)
@@ -4301,17 +4298,17 @@ js::intl_ComputeDisplayNames(JSContext* 
                                        stablePatternChars.latin1Range())
             : ComputeSingleDisplayName(cx, fmt, dtpg, dnStyle, chars,
                                        stablePatternChars.twoByteRange());
         if (!displayName)
             return false;
 
         // 5.b. Append the result string to result.
         v.setString(displayName);
-        if (!DefineElement(cx, result, i, v))
+        if (!DefineDataElement(cx, result, i, v))
             return false;
     }
 
     // 6. Return result.
     args.rval().setObject(*result);
     return true;
 }
 
@@ -4324,24 +4321,24 @@ js::intl_GetLocaleInfo(JSContext* cx, un
     JSAutoByteString locale(cx, args[0].toString());
     if (!locale)
         return false;
 
     RootedObject info(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!info)
         return false;
 
-    if (!DefineProperty(cx, info, cx->names().locale, args[0]))
+    if (!DefineDataProperty(cx, info, cx->names().locale, args[0]))
         return false;
 
     bool rtl = uloc_isRightToLeft(icuLocale(locale.ptr()));
 
     RootedValue dir(cx, StringValue(rtl ? cx->names().rtl : cx->names().ltr));
 
-    if (!DefineProperty(cx, info, cx->names().direction, dir))
+    if (!DefineDataProperty(cx, info, cx->names().direction, dir))
         return false;
 
     args.rval().setObject(*info);
     return true;
 }
 
 const Class js::IntlClass = {
     js_Object_str,
@@ -4398,21 +4395,18 @@ GlobalObject::initIntlObject(JSContext* 
         return false;
     RootedObject numberFormatProto(cx), numberFormat(cx);
     numberFormatProto = CreateNumberFormatPrototype(cx, intl, global, &numberFormat);
     if (!numberFormatProto)
         return false;
 
     // The |Intl| object is fully set up now, so define the global property.
     RootedValue intlValue(cx, ObjectValue(*intl));
-    if (!DefineProperty(cx, global, cx->names().Intl, intlValue, nullptr, nullptr,
-                        JSPROP_RESOLVING))
-    {
+    if (!DefineDataProperty(cx, global, cx->names().Intl, intlValue, JSPROP_RESOLVING))
         return false;
-    }
 
     // Now that the |Intl| object is successfully added, we can OOM-safely fill
     // in all relevant reserved global slots.
 
     // Cache the various prototypes, for use in creating instances of these
     // objects with the proper [[Prototype]] as "the original value of
     // |Intl.Collator.prototype|" and similar.  For builtin classes like
     // |String.prototype| we have |JSProto_*| that enables
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -1984,17 +1984,17 @@ PerformPromiseAll(JSContext *cx, JS::For
         }
 
         // Step h.
         { // Scope for the JSAutoCompartment we need to work with valuesArray.  We
             // mostly do this for performance; we could go ahead and do the define via
             // a cross-compartment proxy instead...
             JSAutoCompartment ac(cx, valuesArray);
             indexId = INT_TO_JSID(index);
-            if (!DefineProperty(cx, valuesArray, indexId, UndefinedHandleValue))
+            if (!DefineDataProperty(cx, valuesArray, indexId, UndefinedHandleValue))
                 return false;
         }
 
         // Step i.
         // Sadly, because someone could have overridden
         // "resolve" on the canonical Promise constructor.
         RootedValue nextPromise(cx);
         RootedValue staticResolve(cx);
--- a/js/src/builtin/Reflect.cpp
+++ b/js/src/builtin/Reflect.cpp
@@ -235,15 +235,15 @@ js::InitReflect(JSContext* cx, HandleObj
 
     RootedObject reflect(cx, NewObjectWithGivenProto<PlainObject>(cx, proto, SingletonObject));
     if (!reflect)
         return nullptr;
     if (!JS_DefineFunctions(cx, reflect, methods))
         return nullptr;
 
     RootedValue value(cx, ObjectValue(*reflect));
-    if (!DefineProperty(cx, obj, cx->names().Reflect, value, nullptr, nullptr, JSPROP_RESOLVING))
+    if (!DefineDataProperty(cx, obj, cx->names().Reflect, value, JSPROP_RESOLVING))
         return nullptr;
 
     obj->as<GlobalObject>().setConstructor(JSProto_Reflect, value);
 
     return reflect;
 }
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -433,17 +433,17 @@ class NodeBuilder
          * Bug 575416: instead of Atomize, lookup constant atoms in tbl file
          */
         RootedAtom atom(cx, Atomize(cx, name, strlen(name)));
         if (!atom)
             return false;
 
         /* Represent "no node" as null and ensure users are not exposed to magic values. */
         RootedValue optVal(cx, val.isMagic(JS_SERIALIZE_NO_NODE) ? NullValue() : val);
-        return DefineProperty(cx, obj, atom->asPropertyName(), optVal);
+        return DefineDataProperty(cx, obj, atom->asPropertyName(), optVal);
     }
 
     MOZ_MUST_USE bool newNodeLoc(TokenPos* pos, MutableHandleValue dst);
 
     MOZ_MUST_USE bool setNodeLoc(HandleObject node, TokenPos* pos);
 
   public:
     /*
@@ -674,17 +674,17 @@ NodeBuilder::newArray(NodeVector& elts, 
         RootedValue val(cx, elts[i]);
 
         MOZ_ASSERT_IF(val.isMagic(), val.whyMagic() == JS_SERIALIZE_NO_NODE);
 
         /* Represent "no node" as an array hole by not adding the value. */
         if (val.isMagic(JS_SERIALIZE_NO_NODE))
             continue;
 
-        if (!DefineElement(cx, array, i, val))
+        if (!DefineDataElement(cx, array, i, val))
             return false;
     }
 
     dst.setObject(*array);
     return true;
 }
 
 bool
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -556,21 +556,18 @@ GlobalObject::initSimdObject(JSContext* 
     if (!objProto)
         return false;
 
     globalSimdObject = NewObjectWithGivenProto(cx, &SimdObject::class_, objProto, SingletonObject);
     if (!globalSimdObject)
         return false;
 
     RootedValue globalSimdValue(cx, ObjectValue(*globalSimdObject));
-    if (!DefineProperty(cx, global, cx->names().SIMD, globalSimdValue, nullptr, nullptr,
-                        JSPROP_RESOLVING))
-    {
+    if (!DefineDataProperty(cx, global, cx->names().SIMD, globalSimdValue, JSPROP_RESOLVING))
         return false;
-    }
 
     global->setConstructor(JSProto_SIMD, globalSimdValue);
     return true;
 }
 
 static bool
 CreateSimdType(JSContext* cx, Handle<GlobalObject*> global, HandlePropertyName stringRepr,
                SimdType simdType, const JSFunctionSpec* methods)
@@ -616,18 +613,18 @@ CreateSimdType(JSContext* cx, Handle<Glo
     }
 
     // Bind type descriptor to the global SIMD object
     RootedObject globalSimdObject(cx, GlobalObject::getOrCreateSimdGlobalObject(cx, global));
     MOZ_ASSERT(globalSimdObject);
 
     RootedValue typeValue(cx, ObjectValue(*typeDescr));
     if (!JS_DefineFunctions(cx, typeDescr, methods) ||
-        !DefineProperty(cx, globalSimdObject, stringRepr, typeValue, nullptr, nullptr,
-                        JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_RESOLVING))
+        !DefineDataProperty(cx, globalSimdObject, stringRepr, typeValue,
+                            JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_RESOLVING))
     {
         return false;
     }
 
     uint32_t slot = uint32_t(typeDescr->type());
     MOZ_ASSERT(globalSimdObject->as<NativeObject>().getReservedSlot(slot).isUndefined());
     globalSimdObject->as<NativeObject>().setReservedSlot(slot, ObjectValue(*typeDescr));
     return !!typeDescr;
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -550,40 +550,40 @@ const JSFunctionSpec ArrayMetaTypeDescr:
 
 bool
 js::CreateUserSizeAndAlignmentProperties(JSContext* cx, HandleTypeDescr descr)
 {
     // If data is transparent, also store the public slots.
     if (descr->transparent()) {
         // byteLength
         RootedValue typeByteLength(cx, Int32Value(AssertedCast<int32_t>(descr->size())));
-        if (!DefineProperty(cx, descr, cx->names().byteLength, typeByteLength,
-                            nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+        if (!DefineDataProperty(cx, descr, cx->names().byteLength, typeByteLength,
+                                JSPROP_READONLY | JSPROP_PERMANENT))
         {
             return false;
         }
 
         // byteAlignment
         RootedValue typeByteAlignment(cx, Int32Value(descr->alignment()));
-        if (!DefineProperty(cx, descr, cx->names().byteAlignment, typeByteAlignment,
-                            nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+        if (!DefineDataProperty(cx, descr, cx->names().byteAlignment, typeByteAlignment,
+                                JSPROP_READONLY | JSPROP_PERMANENT))
         {
             return false;
         }
     } else {
         // byteLength
-        if (!DefineProperty(cx, descr, cx->names().byteLength, UndefinedHandleValue,
-                            nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+        if (!DefineDataProperty(cx, descr, cx->names().byteLength, UndefinedHandleValue,
+                                JSPROP_READONLY | JSPROP_PERMANENT))
         {
             return false;
         }
 
         // byteAlignment
-        if (!DefineProperty(cx, descr, cx->names().byteAlignment, UndefinedHandleValue,
-                            nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+        if (!DefineDataProperty(cx, descr, cx->names().byteAlignment, UndefinedHandleValue,
+                                JSPROP_READONLY | JSPROP_PERMANENT))
         {
             return false;
         }
     }
 
     return true;
 }
 
@@ -608,25 +608,25 @@ ArrayMetaTypeDescr::create(JSContext* cx
     obj->initReservedSlot(JS_DESCR_SLOT_STRING_REPR, StringValue(stringRepr));
     obj->initReservedSlot(JS_DESCR_SLOT_ALIGNMENT, Int32Value(elementType->alignment()));
     obj->initReservedSlot(JS_DESCR_SLOT_SIZE, Int32Value(size));
     obj->initReservedSlot(JS_DESCR_SLOT_OPAQUE, BooleanValue(elementType->opaque()));
     obj->initReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE, ObjectValue(*elementType));
     obj->initReservedSlot(JS_DESCR_SLOT_ARRAY_LENGTH, Int32Value(length));
 
     RootedValue elementTypeVal(cx, ObjectValue(*elementType));
-    if (!DefineProperty(cx, obj, cx->names().elementType, elementTypeVal,
-                        nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+    if (!DefineDataProperty(cx, obj, cx->names().elementType, elementTypeVal,
+                            JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return nullptr;
     }
 
     RootedValue lengthValue(cx, NumberValue(length));
-    if (!DefineProperty(cx, obj, cx->names().length, lengthValue,
-                        nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+    if (!DefineDataProperty(cx, obj, cx->names().length, lengthValue,
+                            JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return nullptr;
     }
 
     if (!CreateUserSizeAndAlignmentProperties(cx, obj))
         return nullptr;
 
     // All arrays with the same element type have the same prototype. This
@@ -838,18 +838,18 @@ StructMetaTypeDescr::create(JSContext* c
         // Collect field name and type object
         RootedValue fieldName(cx, IdToValue(id));
         if (!fieldNames.append(fieldName))
             return nullptr;
         if (!fieldTypeObjs.append(ObjectValue(*fieldType)))
             return nullptr;
 
         // userFieldTypes[id] = typeObj
-        if (!DefineProperty(cx, userFieldTypes, id, fieldTypeObjs[i], nullptr, nullptr,
-                            JSPROP_READONLY | JSPROP_PERMANENT))
+        if (!DefineDataProperty(cx, userFieldTypes, id, fieldTypeObjs[i],
+                                JSPROP_READONLY | JSPROP_PERMANENT))
         {
             return nullptr;
         }
 
         // Append "f:Type" to the string repr
         if (i > 0 && !stringBuffer.append(", "))
             return nullptr;
         if (!stringBuffer.append(JSID_TO_ATOM(id)))
@@ -867,18 +867,18 @@ StructMetaTypeDescr::create(JSContext* c
             return nullptr;
         }
         MOZ_ASSERT(offset.value() >= 0);
         if (!fieldOffsets.append(Int32Value(offset.value())))
             return nullptr;
 
         // userFieldOffsets[id] = offset
         RootedValue offsetValue(cx, Int32Value(offset.value()));
-        if (!DefineProperty(cx, userFieldOffsets, id, offsetValue, nullptr, nullptr,
-                            JSPROP_READONLY | JSPROP_PERMANENT))
+        if (!DefineDataProperty(cx, userFieldOffsets, id, offsetValue,
+                                JSPROP_READONLY | JSPROP_PERMANENT))
         {
             return nullptr;
         }
 
         // Add space for this field to the total struct size.
         sizeSoFar = offset + fieldType->size();
         if (!sizeSoFar.isValid()) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_TOO_BIG);
@@ -956,24 +956,24 @@ StructMetaTypeDescr::create(JSContext* c
     }
 
     // Create data properties fieldOffsets and fieldTypes
     if (!FreezeObject(cx, userFieldOffsets))
         return nullptr;
     if (!FreezeObject(cx, userFieldTypes))
         return nullptr;
     RootedValue userFieldOffsetsValue(cx, ObjectValue(*userFieldOffsets));
-    if (!DefineProperty(cx, descr, cx->names().fieldOffsets, userFieldOffsetsValue,
-                        nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+    if (!DefineDataProperty(cx, descr, cx->names().fieldOffsets, userFieldOffsetsValue,
+                            JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return nullptr;
     }
     RootedValue userFieldTypesValue(cx, ObjectValue(*userFieldTypes));
-    if (!DefineProperty(cx, descr, cx->names().fieldTypes, userFieldTypesValue,
-                        nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+    if (!DefineDataProperty(cx, descr, cx->names().fieldTypes, userFieldTypesValue,
+                            JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return nullptr;
     }
 
     if (!CreateUserSizeAndAlignmentProperties(cx, descr))
         return nullptr;
 
     Rooted<TypedProto*> prototypeObj(cx);
@@ -1150,17 +1150,17 @@ DefineSimpleTypeDescr(JSContext* cx,
     // not being user accessible, but we still create one for consistency.
     Rooted<TypedProto*> proto(cx);
     proto = NewObjectWithGivenProto<TypedProto>(cx, objProto, TenuredObject);
     if (!proto)
         return false;
     descr->initReservedSlot(JS_DESCR_SLOT_TYPROTO, ObjectValue(*proto));
 
     RootedValue descrValue(cx, ObjectValue(*descr));
-    if (!DefineProperty(cx, module, className, descrValue, nullptr, nullptr, 0))
+    if (!DefineDataProperty(cx, module, className, descrValue, 0))
         return false;
 
     if (!CreateTraceList(cx, descr))
         return false;
 
     if (!cx->zone()->addTypeDescrObject(cx, descr))
         return false;
 
@@ -1197,18 +1197,18 @@ DefineMetaTypeDescr(JSContext* cx,
     if (!objProto)
         return nullptr;
     RootedObject protoProto(cx);
     protoProto = NewObjectWithGivenProto<PlainObject>(cx, objProto, SingletonObject);
     if (!protoProto)
         return nullptr;
 
     RootedValue protoProtoValue(cx, ObjectValue(*protoProto));
-    if (!DefineProperty(cx, proto, cx->names().prototype, protoProtoValue,
-                        nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+    if (!DefineDataProperty(cx, proto, cx->names().prototype, protoProtoValue,
+                            JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return nullptr;
     }
 
     // Create ctor itself
 
     const int constructorLength = 2;
     RootedFunction ctor(cx);
@@ -1271,41 +1271,41 @@ GlobalObject::initTypedObjectModule(JSCo
 
     RootedObject arrayType(cx);
     arrayType = DefineMetaTypeDescr<ArrayMetaTypeDescr>(
         cx, "ArrayType", global, module, TypedObjectModuleObject::ArrayTypePrototype);
     if (!arrayType)
         return false;
 
     RootedValue arrayTypeValue(cx, ObjectValue(*arrayType));
-    if (!DefineProperty(cx, module, cx->names().ArrayType, arrayTypeValue,
-                        nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+    if (!DefineDataProperty(cx, module, cx->names().ArrayType, arrayTypeValue,
+                            JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return false;
     }
 
     // StructType.
 
     RootedObject structType(cx);
     structType = DefineMetaTypeDescr<StructMetaTypeDescr>(
         cx, "StructType", global, module, TypedObjectModuleObject::StructTypePrototype);
     if (!structType)
         return false;
 
     RootedValue structTypeValue(cx, ObjectValue(*structType));
-    if (!DefineProperty(cx, module, cx->names().StructType, structTypeValue,
-                        nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
+    if (!DefineDataProperty(cx, module, cx->names().StructType, structTypeValue,
+                            JSPROP_READONLY | JSPROP_PERMANENT))
     {
         return false;
     }
 
     // Everything is setup, install module on the global object:
     RootedValue moduleValue(cx, ObjectValue(*module));
-    if (!DefineProperty(cx, global, cx->names().TypedObject, moduleValue, nullptr, nullptr,
-                        JSPROP_RESOLVING))
+    if (!DefineDataProperty(cx, global, cx->names().TypedObject, moduleValue,
+                            JSPROP_RESOLVING))
     {
         return false;
     }
 
     global->setConstructor(JSProto_TypedObject, moduleValue);
 
     return module;
 }
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1037,18 +1037,18 @@ JS_ResolveStandardClass(JSContext* cx, H
     if (!JSID_IS_ATOM(id))
         return true;
 
     /* Check whether we're resolving 'undefined', and define it if so. */
     JSAtom* idAtom = JSID_TO_ATOM(id);
     JSAtom* undefinedAtom = cx->names().undefined;
     if (idAtom == undefinedAtom) {
         *resolved = true;
-        return DefineProperty(cx, global, id, UndefinedHandleValue, nullptr, nullptr,
-                              JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_RESOLVING);
+        return DefineDataProperty(cx, global, id, UndefinedHandleValue,
+                                  JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_RESOLVING);
     }
 
     /* Try for class constructors/prototypes named by well-known atoms. */
     stdnm = LookupStdName(cx->names(), idAtom, standard_class_names);
 
     /* Try less frequently used top-level functions and constants. */
     if (!stdnm)
         stdnm = LookupStdName(cx->names(), idAtom, builtin_property_names);
@@ -2128,18 +2128,17 @@ JS_GetPropertyDescriptor(JSContext* cx, 
 
 static bool
 DefinePropertyByDescriptor(JSContext* cx, HandleObject obj, HandleId id,
                            Handle<PropertyDescriptor> desc, ObjectOpResult& result)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id, desc);
-    return DefineProperty(cx, obj, id, desc.value(), desc.getter(), desc.setter(),
-                          desc.attributes(), result);
+    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);
 }
@@ -2216,30 +2215,30 @@ DefineAccessorPropertyById(JSContext* cx
     assertSameCompartment(cx, obj, id,
                           (attrs & JSPROP_GETTER)
                           ? JS_FUNC_TO_DATA_PTR(JSObject*, getter)
                           : nullptr,
                           (attrs & JSPROP_SETTER)
                           ? JS_FUNC_TO_DATA_PTR(JSObject*, setter)
                           : nullptr);
 
-    return DefineProperty(cx, obj, id, UndefinedHandleValue, getter, setter, attrs);
+    return js::DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
 }
 
 static bool
 DefineDataPropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
                        unsigned attrs)
 {
     MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER | JSPROP_PROPOP_ACCESSORS)));
 
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id, value);
 
-    return DefineProperty(cx, obj, id, value, nullptr, nullptr, attrs);
+    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)
@@ -2526,64 +2525,64 @@ DefineDataElement(JSContext* cx, HandleO
         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);
+    return ::DefineDataElement(cx, obj, index, value, attrs);
 }
 
 JS_PUBLIC_API(bool)
 JS_DefineElement(JSContext* cx, HandleObject obj, uint32_t index, Native getter, Native setter,
                  unsigned attrs)
 {
     return DefineAccessorElement(cx, obj, index, attrs, getter, setter);
 }
 
 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);
+    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);
+    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);
+    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);
+    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);
+    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_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -351,17 +351,17 @@ ElementAdder::append(JSContext* cx, Hand
 {
     MOZ_ASSERT(index_ < length_);
     if (resObj_) {
         DenseElementResult result =
             SetOrExtendAnyBoxedOrUnboxedDenseElements(cx, resObj_, index_, v.address(), 1);
         if (result == DenseElementResult::Failure)
             return false;
         if (result == DenseElementResult::Incomplete) {
-            if (!DefineElement(cx, resObj_, index_, v))
+            if (!DefineDataElement(cx, resObj_, index_, v))
                 return false;
         }
     } else {
         vp_[index_] = v;
     }
     index_++;
     return true;
 }
@@ -489,17 +489,17 @@ GetArrayElement(JSContext* cx, HandleObj
 }
 
 static inline bool
 DefineArrayElement(JSContext* cx, HandleObject obj, uint64_t index, HandleValue value)
 {
     RootedId id(cx);
     if (!ToId(cx, index, &id))
         return false;
-    return DefineProperty(cx, obj, id, value);
+    return DefineDataProperty(cx, obj, id, value);
 }
 
 // Set the value of the property at the given index to v.
 static inline bool
 SetArrayElement(JSContext* cx, HandleObject obj, uint64_t index, HandleValue v)
 {
     RootedId id(cx);
     if (!ToId(cx, index, &id))
@@ -634,18 +634,17 @@ array_length_getter(JSContext* cx, Handl
 static bool
 array_length_setter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
                     ObjectOpResult& result)
 {
     if (!obj->is<ArrayObject>()) {
         // This array .length property was found on the prototype
         // chain. Ideally the setter should not have been called, but since
         // we're here, do an impression of SetPropertyByDefining.
-        return DefineProperty(cx, obj, cx->names().length, vp, nullptr, nullptr,
-                              JSPROP_ENUMERATE, result);
+        return DefineDataProperty(cx, obj, cx->names().length, vp, JSPROP_ENUMERATE, result);
     }
 
     Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
     MOZ_ASSERT(arr->lengthIsWritable(),
                "setter shouldn't be called if property is non-writable");
 
     return ArraySetLength(cx, arr, id, JSPROP_PERMANENT, vp, result);
 }
@@ -2744,17 +2743,17 @@ CopyArrayElements(JSContext* cx, HandleO
 
             if (!hole) {
                 DenseElementResult edResult = nresult->ensureDenseElements(cx, index, 1);
                 if (edResult != DenseElementResult::Success) {
                     if (edResult == DenseElementResult::Failure)
                         return false;
 
                     MOZ_ASSERT(edResult == DenseElementResult::Incomplete);
-                    if (!DefineElement(cx, nresult, index, value))
+                    if (!DefineDataElement(cx, nresult, index, value))
                         return false;
 
                     break;
                 }
                 nresult->setDenseElementWithType(cx, index, value);
             }
         }
 
@@ -3204,17 +3203,17 @@ SliceSparse(JSContext* cx, HandleObject 
     RootedValue value(cx);
     for (uint32_t index : indexes) {
         MOZ_ASSERT(begin <= index && index < end);
 
         bool hole;
         if (!HasAndGetElement(cx, obj, index, &hole, &value))
             return false;
 
-        if (!hole && !DefineElement(cx, result, index - uint32_t(begin), value))
+        if (!hole && !DefineDataElement(cx, result, index - uint32_t(begin), value))
             return false;
     }
 
     return true;
 }
 
 template <typename T, typename ArrayLength>
 static inline ArrayLength
@@ -3464,17 +3463,17 @@ array_of(JSContext* cx, unsigned argc, V
         cargs[0].setNumber(args.length());
 
         if (!Construct(cx, args.thisv(), cargs, args.thisv(), &obj))
             return false;
     }
 
     // Step 8.
     for (unsigned k = 0; k < args.length(); k++) {
-        if (!DefineElement(cx, obj, k, args[k]))
+        if (!DefineDataElement(cx, obj, k, args[k]))
             return false;
     }
 
     // Steps 9-10.
     if (!SetLengthProperty(cx, obj, args.length()))
         return false;
 
     // Step 11.
@@ -3692,31 +3691,31 @@ static bool
 array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto)
 {
     // Add Array.prototype[@@unscopables]. ECMA-262 draft (2016 Mar 19) 22.1.3.32.
     RootedObject unscopables(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr, TenuredObject));
     if (!unscopables)
         return false;
 
     RootedValue value(cx, BooleanValue(true));
-    if (!DefineProperty(cx, unscopables, cx->names().copyWithin, value) ||
-        !DefineProperty(cx, unscopables, cx->names().entries, value) ||
-        !DefineProperty(cx, unscopables, cx->names().fill, value) ||
-        !DefineProperty(cx, unscopables, cx->names().find, value) ||
-        !DefineProperty(cx, unscopables, cx->names().findIndex, value) ||
-        !DefineProperty(cx, unscopables, cx->names().includes, value) ||
-        !DefineProperty(cx, unscopables, cx->names().keys, value) ||
-        !DefineProperty(cx, unscopables, cx->names().values, value))
+    if (!DefineDataProperty(cx, unscopables, cx->names().copyWithin, value) ||
+        !DefineDataProperty(cx, unscopables, cx->names().entries, value) ||
+        !DefineDataProperty(cx, unscopables, cx->names().fill, value) ||
+        !DefineDataProperty(cx, unscopables, cx->names().find, value) ||
+        !DefineDataProperty(cx, unscopables, cx->names().findIndex, value) ||
+        !DefineDataProperty(cx, unscopables, cx->names().includes, value) ||
+        !DefineDataProperty(cx, unscopables, cx->names().keys, value) ||
+        !DefineDataProperty(cx, unscopables, cx->names().values, value))
     {
         return false;
     }
 
     RootedId id(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().get(JS::SymbolCode::unscopables)));
     value.setObject(*unscopables);
-    return DefineProperty(cx, proto, id, value, nullptr, nullptr, JSPROP_READONLY);
+    return DefineDataProperty(cx, proto, id, value, JSPROP_READONLY);
 }
 
 static const ClassOps ArrayObjectClassOps = {
     array_addProperty,
     nullptr, /* delProperty */
     nullptr, /* enumerate */
     nullptr, /* resolve */
     nullptr, /* mayResolve */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1051,34 +1051,34 @@ js::CreateErrorNotesArray(JSContext* cx,
         RootedPlainObject noteObj(cx, NewBuiltinClassInstance<PlainObject>(cx));
         if (!noteObj)
             return nullptr;
 
         RootedString messageStr(cx, note->newMessageString(cx));
         if (!messageStr)
             return nullptr;
         RootedValue messageVal(cx, StringValue(messageStr));
-        if (!DefineProperty(cx, noteObj, cx->names().message, messageVal))
+        if (!DefineDataProperty(cx, noteObj, cx->names().message, messageVal))
             return nullptr;
 
         RootedValue filenameVal(cx);
         if (note->filename) {
             RootedString filenameStr(cx, NewStringCopyZ<CanGC>(cx, note->filename));
             if (!filenameStr)
                 return nullptr;
             filenameVal = StringValue(filenameStr);
         }
-        if (!DefineProperty(cx, noteObj, cx->names().fileName, filenameVal))
+        if (!DefineDataProperty(cx, noteObj, cx->names().fileName, filenameVal))
             return nullptr;
 
         RootedValue linenoVal(cx, Int32Value(note->lineno));
-        if (!DefineProperty(cx, noteObj, cx->names().lineNumber, linenoVal))
+        if (!DefineDataProperty(cx, noteObj, cx->names().lineNumber, linenoVal))
             return nullptr;
         RootedValue columnVal(cx, Int32Value(note->column));
-        if (!DefineProperty(cx, noteObj, cx->names().columnNumber, columnVal))
+        if (!DefineDataProperty(cx, noteObj, cx->names().columnNumber, columnVal))
             return nullptr;
 
         if (!NewbornArrayPush(cx, notesArray, ObjectValue(*noteObj)))
             return nullptr;
     }
 
     return notesArray;
 }
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -660,17 +660,17 @@ JSCompartment::getTemplateLiteralObject(
         templateObj.set(p->value());
 
         // The template object must have been frozen when it was added to the
         // registry.
         MOZ_ASSERT(!templateObj->nonProxyIsExtensible());
     } else {
         MOZ_ASSERT(templateObj->nonProxyIsExtensible());
         RootedValue rawValue(cx, ObjectValue(*rawStrings));
-        if (!DefineProperty(cx, templateObj, cx->names().raw, rawValue, nullptr, nullptr, 0))
+        if (!DefineDataProperty(cx, templateObj, cx->names().raw, rawValue, 0))
             return false;
         if (!FreezeObject(cx, rawStrings))
             return false;
         if (!FreezeObject(cx, templateObj))
             return false;
 
         if (!templateLiteralMap_.relookupOrAdd(p, rawStrings, templateObj))
             return false;
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -433,25 +433,24 @@ ResolveInterpretedFunctionPrototype(JSCo
         return false;
 
     // Per ES5 13.2 the prototype's .constructor property is configurable,
     // non-enumerable, and writable.  However, per the 15 July 2013 ES6 draft,
     // section 15.19.3, the .prototype of a generator function does not link
     // back with a .constructor.
     if (!isStarGenerator && !isAsyncGenerator) {
         RootedValue objVal(cx, ObjectValue(*fun));
-        if (!DefineProperty(cx, proto, cx->names().constructor, objVal, nullptr, nullptr, 0))
+        if (!DefineDataProperty(cx, proto, cx->names().constructor, objVal, 0))
             return false;
     }
 
     // Per ES5 15.3.5.2 a user-defined function's .prototype property is
     // initially non-configurable, non-enumerable, and writable.
     RootedValue protoVal(cx, ObjectValue(*proto));
-    return DefineProperty(cx, fun, id, protoVal, nullptr, nullptr,
-                          JSPROP_PERMANENT | JSPROP_RESOLVING);
+    return DefineDataProperty(cx, fun, id, protoVal, JSPROP_PERMANENT | JSPROP_RESOLVING);
 }
 
 bool
 JSFunction::needsPrototypeProperty()
 {
     /*
      * Built-in functions do not have a .prototype property per ECMA-262,
      * or (Object.prototype, Function.prototype, etc.) have that property
@@ -2436,17 +2435,17 @@ js::DefineFunction(JSContext* cx, Handle
         fun = NewNativeConstructor(cx, native, nargs, atom, allocKind);
     else
         fun = NewNativeFunction(cx, native, nargs, atom, allocKind);
 
     if (!fun)
         return nullptr;
 
     RootedValue funVal(cx, ObjectValue(*fun));
-    if (!DefineProperty(cx, obj, id, funVal, nullptr, nullptr, flags & ~JSFUN_FLAGS_MASK))
+    if (!DefineDataProperty(cx, obj, id, funVal, flags & ~JSFUN_FLAGS_MASK))
         return nullptr;
 
     return fun;
 }
 
 void
 js::ReportIncompatibleMethod(JSContext* cx, const CallArgs& args, const Class* clasp)
 {
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -584,17 +584,17 @@ NewPropertyIteratorObject(JSContext* cx,
         // We don't have to do this for JSITER_ENUMERATE because that object always
         // takes an optimized path.
         RootedFunction next(cx, NewNativeFunction(cx, legacy_iterator_next, 0,
                                                   HandlePropertyName(cx->names().next)));
         if (!next)
             return nullptr;
 
         RootedValue value(cx, ObjectValue(*next));
-        if (!DefineProperty(cx, res, cx->names().next, value))
+        if (!DefineDataProperty(cx, res, cx->names().next, value))
             return nullptr;
     }
 
     return res;
 }
 
 NativeIterator*
 NativeIterator::allocateIterator(JSContext* cx, uint32_t numGuards, uint32_t plength)
@@ -988,22 +988,22 @@ js::CreateIterResultObject(JSContext* cx
     // Step 1 (implicit).
 
     // Step 2.
     RootedObject resultObj(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!resultObj)
         return nullptr;
 
     // Step 3.
-    if (!DefineProperty(cx, resultObj, cx->names().value, value))
+    if (!DefineDataProperty(cx, resultObj, cx->names().value, value))
         return nullptr;
 
     // Step 4.
-    if (!DefineProperty(cx, resultObj, cx->names().done,
-                        done ? TrueHandleValue : FalseHandleValue))
+    if (!DefineDataProperty(cx, resultObj, cx->names().done,
+                            done ? TrueHandleValue : FalseHandleValue))
     {
         return nullptr;
     }
 
     // Step 5.
     return resultObj;
 }
 
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -1258,27 +1258,27 @@ js::InitNumberClass(JSContext* cx, Handl
 
     /* Number.parseInt should be the same function object as global parseInt. */
     RootedId parseIntId(cx, NameToId(cx->names().parseInt));
     JSFunction* parseInt = DefineFunction(cx, global, parseIntId, num_parseInt, 2,
                                           JSPROP_RESOLVING);
     if (!parseInt)
         return nullptr;
     RootedValue parseIntValue(cx, ObjectValue(*parseInt));
-    if (!DefineProperty(cx, ctor, parseIntId, parseIntValue, nullptr, nullptr, 0))
+    if (!DefineDataProperty(cx, ctor, parseIntId, parseIntValue, 0))
         return nullptr;
 
     /* Number.parseFloat should be the same function object as global parseFloat. */
     RootedId parseFloatId(cx, NameToId(cx->names().parseFloat));
     JSFunction* parseFloat = DefineFunction(cx, global, parseFloatId, num_parseFloat, 1,
                                             JSPROP_RESOLVING);
     if (!parseFloat)
         return nullptr;
     RootedValue parseFloatValue(cx, ObjectValue(*parseFloat));
-    if (!DefineProperty(cx, ctor, parseFloatId, parseFloatValue, nullptr, nullptr, 0))
+    if (!DefineDataProperty(cx, ctor, parseFloatId, parseFloatValue, 0))
         return nullptr;
 
     RootedValue valueNaN(cx, cx->runtime()->NaNValue);
     RootedValue valueInfinity(cx, cx->runtime()->positiveInfinityValue);
 
     /* ES5 15.1.1.1, 15.1.1.2 */
     if (!NativeDefineProperty(cx, global, cx->names().NaN, valueNaN, nullptr, nullptr,
                               JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_RESOLVING) ||
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -156,59 +156,59 @@ js::FromPropertyDescriptorToObject(JSCon
     RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!obj)
         return false;
 
     const JSAtomState& names = cx->names();
 
     // Step 4.
     if (desc.hasValue()) {
-        if (!DefineProperty(cx, obj, names.value, desc.value()))
+        if (!DefineDataProperty(cx, obj, names.value, desc.value()))
             return false;
     }
 
     // Step 5.
     RootedValue v(cx);
     if (desc.hasWritable()) {
         v.setBoolean(desc.writable());
-        if (!DefineProperty(cx, obj, names.writable, v))
+        if (!DefineDataProperty(cx, obj, names.writable, v))
             return false;
     }
 
     // Step 6.
     if (desc.hasGetterObject()) {
         if (JSObject* get = desc.getterObject())
             v.setObject(*get);
         else
             v.setUndefined();
-        if (!DefineProperty(cx, obj, names.get, v))
+        if (!DefineDataProperty(cx, obj, names.get, v))
             return false;
     }
 
     // Step 7.
     if (desc.hasSetterObject()) {
         if (JSObject* set = desc.setterObject())
             v.setObject(*set);
         else
             v.setUndefined();
-        if (!DefineProperty(cx, obj, names.set, v))
+        if (!DefineDataProperty(cx, obj, names.set, v))
             return false;
     }
 
     // Step 8.
     if (desc.hasEnumerable()) {
         v.setBoolean(desc.enumerable());
-        if (!DefineProperty(cx, obj, names.enumerable, v))
+        if (!DefineDataProperty(cx, obj, names.enumerable, v))
             return false;
     }
 
     // Step 9.
     if (desc.hasConfigurable()) {
         v.setBoolean(desc.configurable());
-        if (!DefineProperty(cx, obj, names.configurable, v))
+        if (!DefineDataProperty(cx, obj, names.configurable, v))
             return false;
     }
 
     vp.setObject(*obj);
     return true;
 }
 
 bool
@@ -1744,17 +1744,17 @@ JSObject::swap(JSContext* cx, HandleObje
     return true;
 }
 
 static bool
 DefineStandardSlot(JSContext* cx, HandleObject obj, JSProtoKey key, JSAtom* atom,
                    HandleValue v, uint32_t attrs, bool& named)
 {
     RootedId id(cx, AtomToId(atom));
-    named = DefineProperty(cx, obj, id, v, nullptr, nullptr, attrs);
+    named = DefineDataProperty(cx, obj, id, v, attrs);
     return named;
 }
 
 static void
 SetClassObject(JSObject* obj, JSProtoKey key, JSObject* cobj, JSObject* proto)
 {
     if (!obj->is<GlobalObject>())
         return;
@@ -2781,84 +2781,147 @@ js::DefineProperty(JSContext* cx, Handle
 {
     desc.assertValid();
     if (DefinePropertyOp op = obj->getOpsDefineProperty())
         return op(cx, obj, id, desc, result);
     return NativeDefineProperty(cx, obj.as<NativeObject>(), id, desc, result);
 }
 
 bool
-js::DefineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
-                   JSGetterOp getter, JSSetterOp setter, unsigned attrs,
-                   ObjectOpResult& result)
+js::DefineAccessorProperty(JSContext* cx, HandleObject obj, HandleId id,
+                           JSGetterOp getter, JSSetterOp setter, unsigned attrs,
+                           ObjectOpResult& result)
 {
     MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
 
     Rooted<PropertyDescriptor> desc(cx);
-    desc.initFields(nullptr, value, attrs, getter, setter);
+    desc.initFields(nullptr, UndefinedHandleValue, attrs, getter, setter);
+    if (DefinePropertyOp op = obj->getOpsDefineProperty()) {
+        MOZ_ASSERT(!cx->helperThread());
+        return op(cx, obj, id, desc, result);
+    }
+    return NativeDefineProperty(cx, obj.as<NativeObject>(), id, desc, result);
+}
+
+bool
+js::DefineDataProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
+                       unsigned attrs, ObjectOpResult& result)
+{
+    Rooted<PropertyDescriptor> desc(cx);
+    desc.initFields(nullptr, value, attrs, nullptr, nullptr);
     if (DefinePropertyOp op = obj->getOpsDefineProperty()) {
         MOZ_ASSERT(!cx->helperThread());
         return op(cx, obj, id, desc, result);
     }
     return NativeDefineProperty(cx, obj.as<NativeObject>(), id, desc, result);
 }
 
 bool
-js::DefineProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
-                   JSGetterOp getter, JSSetterOp setter, unsigned attrs,
-                   ObjectOpResult& result)
+js::DefineAccessorProperty(JSContext* cx, HandleObject obj, PropertyName* name,
+                           JSGetterOp getter, JSSetterOp setter, unsigned attrs,
+                           ObjectOpResult& result)
 {
     RootedId id(cx, NameToId(name));
-    return DefineProperty(cx, obj, id, value, getter, setter, attrs, result);
+    return DefineAccessorProperty(cx, obj, id, getter, setter, attrs, result);
 }
 
 bool
-js::DefineElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
-                  JSGetterOp getter, JSSetterOp setter, unsigned attrs,
-                  ObjectOpResult& result)
+js::DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
+                       unsigned attrs, ObjectOpResult& result)
+{
+    RootedId id(cx, NameToId(name));
+    return DefineDataProperty(cx, obj, id, value, attrs, result);
+}
+
+bool
+js::DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index,
+                          JSGetterOp getter, JSSetterOp setter, unsigned attrs,
+                          ObjectOpResult& result)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, &id))
         return false;
-    return DefineProperty(cx, obj, id, value, getter, setter, attrs, result);
+    return DefineAccessorProperty(cx, obj, id, getter, setter, attrs, result);
 }
 
 bool
-js::DefineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
-                   JSGetterOp getter, JSSetterOp setter, unsigned attrs)
+js::DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
+                      unsigned attrs, ObjectOpResult& result)
+{
+    RootedId id(cx);
+    if (!IndexToId(cx, index, &id))
+        return false;
+    return DefineDataProperty(cx, obj, id, value, attrs, result);
+}
+
+bool
+js::DefineAccessorProperty(JSContext* cx, HandleObject obj, HandleId id,
+                           JSGetterOp getter, JSSetterOp setter, unsigned attrs)
 {
     ObjectOpResult result;
-    if (!DefineProperty(cx, obj, id, value, getter, setter, attrs, result))
+    if (!DefineAccessorProperty(cx, obj, id, getter, setter, attrs, result))
         return false;
     if (!result) {
         MOZ_ASSERT(!cx->helperThread());
         result.reportError(cx, obj, id);
         return false;
     }
     return true;
 }
 
 bool
-js::DefineProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
-                   JSGetterOp getter, JSSetterOp setter, unsigned attrs)
+js::DefineDataProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
+                       unsigned attrs)
 {
-    RootedId id(cx, NameToId(name));
-    return DefineProperty(cx, obj, id, value, getter, setter, attrs);
+    ObjectOpResult result;
+    if (!DefineDataProperty(cx, obj, id, value, attrs, result))
+        return false;
+    if (!result) {
+        MOZ_ASSERT(!cx->helperThread());
+        result.reportError(cx, obj, id);
+        return false;
+    }
+    return true;
 }
 
 bool
-js::DefineElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
-                  JSGetterOp getter, JSSetterOp setter, unsigned attrs)
+js::DefineAccessorProperty(JSContext* cx, HandleObject obj, PropertyName* name,
+                           JSGetterOp getter, JSSetterOp setter, unsigned attrs)
+{
+    RootedId id(cx, NameToId(name));
+    return DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
+}
+
+bool
+js::DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
+                       unsigned attrs)
+{
+    RootedId id(cx, NameToId(name));
+    return DefineDataProperty(cx, obj, id, value, attrs);
+}
+
+bool
+js::DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index,
+                          JSGetterOp getter, JSSetterOp setter, unsigned attrs)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, &id))
         return false;
-    return DefineProperty(cx, obj, id, value, getter, setter, attrs);
+    return DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
 }
 
+bool
+js::DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
+                      unsigned attrs)
+{
+    RootedId id(cx);
+    if (!IndexToId(cx, index, &id))
+        return false;
+    return DefineDataProperty(cx, obj, id, value, attrs);
+}
 
 /*** SpiderMonkey nonstandard internal methods ***************************************************/
 
 bool
 js::SetImmutablePrototype(JSContext* cx, HandleObject obj, bool* succeeded)
 {
     if (obj->hasDynamicPrototype()) {
         MOZ_ASSERT(!cx->helperThread());
@@ -2978,17 +3041,17 @@ DefineFunctionFromSpec(JSContext* cx, Ha
     JSFunction* fun = NewFunctionFromSpec(cx, fs, id);
     if (!fun)
         return false;
 
     if (intrinsic == AsIntrinsic)
         fun->setIsIntrinsic();
 
     RootedValue funVal(cx, ObjectValue(*fun));
-    return DefineProperty(cx, obj, id, funVal, nullptr, nullptr, flags & ~JSFUN_FLAGS_MASK);
+    return DefineDataProperty(cx, obj, id, funVal, flags & ~JSFUN_FLAGS_MASK);
 }
 
 bool
 js::DefineFunctions(JSContext* cx, HandleObject obj, const JSFunctionSpec* fs,
                     DefineAsIntrinsic intrinsic)
 {
     for (; fs->name; fs++) {
         if (!DefineFunctionFromSpec(cx, obj, fs, fs->flags, intrinsic))
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -765,51 +765,72 @@ GetOwnPropertyDescriptor(JSContext* cx, 
                          MutableHandle<JS::PropertyDescriptor> desc);
 
 /* ES6 [[DefineOwnProperty]]. Define a property on obj. */
 extern bool
 DefineProperty(JSContext* cx, HandleObject obj, HandleId id,
                Handle<JS::PropertyDescriptor> desc, ObjectOpResult& result);
 
 extern bool
-DefineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
-               JSGetterOp getter, JSSetterOp setter, unsigned attrs, ObjectOpResult& result);
+DefineAccessorProperty(JSContext* cx, HandleObject obj, HandleId id,
+                       JSGetterOp getter, JSSetterOp setter, unsigned attrs,
+                       ObjectOpResult& result);
+
+extern bool
+DefineDataProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
+                   unsigned attrs, ObjectOpResult& result);
 
 extern bool
-DefineProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
-               JSGetterOp getter, JSSetterOp setter, unsigned attrs, ObjectOpResult& result);
+DefineAccessorProperty(JSContext* cx, HandleObject obj, PropertyName* name,
+                       JSGetterOp getter, JSSetterOp setter, unsigned attrs,
+                       ObjectOpResult& result);
 
 extern bool
-DefineElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
-              JSGetterOp getter, JSSetterOp setter, unsigned attrs, ObjectOpResult& result);
+DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
+                   unsigned attrs, ObjectOpResult& result);
+
+extern bool
+DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index,
+                      JSGetterOp getter, JSSetterOp setter, unsigned attrs,
+                      ObjectOpResult& result);
+
+extern bool
+DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
+                  unsigned attrs, ObjectOpResult& result);
 
 /*
  * When the 'result' out-param is omitted, the behavior is the same as above, except
  * that any failure results in a TypeError.
  */
 extern bool
 DefineProperty(JSContext* cx, HandleObject obj, HandleId id, Handle<JS::PropertyDescriptor> desc);
 
 extern bool
-DefineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
-               JSGetterOp getter = nullptr,
-               JSSetterOp setter = nullptr,
-               unsigned attrs = JSPROP_ENUMERATE);
+DefineAccessorProperty(JSContext* cx, HandleObject obj, HandleId id,
+                       JSGetterOp getter, JSSetterOp setter, unsigned attrs = JSPROP_ENUMERATE);
+
+extern bool
+DefineDataProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
+                   unsigned attrs = JSPROP_ENUMERATE);
 
 extern bool
-DefineProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
-               JSGetterOp getter = nullptr,
-               JSSetterOp setter = nullptr,
-               unsigned attrs = JSPROP_ENUMERATE);
+DefineAccessorProperty(JSContext* cx, HandleObject obj, PropertyName* name,
+                       JSGetterOp getter, JSSetterOp setter, unsigned attrs = JSPROP_ENUMERATE);
 
 extern bool
-DefineElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
-              JSGetterOp getter = nullptr,
-              JSSetterOp setter = nullptr,
-              unsigned attrs = JSPROP_ENUMERATE);
+DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
+                   unsigned attrs = JSPROP_ENUMERATE);
+
+extern bool
+DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index,
+                      JSGetterOp getter, JSSetterOp setter, unsigned attrs = JSPROP_ENUMERATE);
+
+extern bool
+DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
+                  unsigned attrs = JSPROP_ENUMERATE);
 
 /*
  * ES6 [[Has]]. Set *foundp to true if `id in obj` (that is, if obj has an own
  * or inherited property obj[id]), false otherwise.
  */
 inline bool
 HasProperty(JSContext* cx, HandleObject obj, HandleId id, bool* foundp);
 
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -867,17 +867,17 @@ Walk(JSContext* cx, HandleObject holder,
 
 static bool
 Revive(JSContext* cx, HandleValue reviver, MutableHandleValue vp)
 {
     RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!obj)
         return false;
 
-    if (!DefineProperty(cx, obj, cx->names().empty, vp))
+    if (!DefineDataProperty(cx, obj, cx->names().empty, vp))
         return false;
 
     Rooted<jsid> id(cx, NameToId(cx->names().empty));
     return Walk(cx, obj, id, reviver, vp);
 }
 
 template <typename CharT>
 bool
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -523,21 +523,18 @@ str_enumerate(JSContext* cx, HandleObjec
 {
     RootedString str(cx, obj->as<StringObject>().unbox());
     RootedValue value(cx);
     for (size_t i = 0, length = str->length(); i < length; i++) {
         JSString* str1 = NewDependentString(cx, str, i, 1);
         if (!str1)
             return false;
         value.setString(str1);
-        if (!DefineElement(cx, obj, i, value, nullptr, nullptr,
-                           STRING_ELEMENT_ATTRS | JSPROP_RESOLVING))
-        {
+        if (!DefineDataElement(cx, obj, i, value, STRING_ELEMENT_ATTRS | JSPROP_RESOLVING))
             return false;
-        }
     }
 
     return true;
 }
 
 static bool
 str_mayResolve(const JSAtomState&, jsid id, JSObject*)
 {
@@ -554,18 +551,18 @@ str_resolve(JSContext* cx, HandleObject 
     RootedString str(cx, obj->as<StringObject>().unbox());
 
     int32_t slot = JSID_TO_INT(id);
     if ((size_t)slot < str->length()) {
         JSString* str1 = cx->staticStrings().getUnitStringForElement(cx, str, size_t(slot));
         if (!str1)
             return false;
         RootedValue value(cx, StringValue(str1));
-        if (!DefineElement(cx, obj, uint32_t(slot), value, nullptr, nullptr,
-                           STRING_ELEMENT_ATTRS | JSPROP_RESOLVING))
+        if (!DefineDataElement(cx, obj, uint32_t(slot), value,
+                               STRING_ELEMENT_ATTRS | JSPROP_RESOLVING))
         {
             return false;
         }
         *resolvedp = true;
     }
     return true;
 }
 
--- a/js/src/proxy/BaseProxyHandler.cpp
+++ b/js/src/proxy/BaseProxyHandler.cpp
@@ -218,17 +218,17 @@ js::SetPropertyIgnoringNamedGetter(JSCon
 
 
         // Steps 5.e.iii-iv. and 5.f.i.
         unsigned attrs =
             existingDescriptor.object()
             ? JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_PERMANENT
             : JSPROP_ENUMERATE;
 
-        return DefineProperty(cx, receiverObj, id, v, nullptr, nullptr, attrs, result);
+        return DefineDataProperty(cx, receiverObj, id, v, attrs, result);
     }
 
     // Step 6.
     MOZ_ASSERT(ownDesc.isAccessorDescriptor());
     RootedObject setter(cx);
     if (ownDesc.hasSetterObject())
         setter = ownDesc.setterObject();
     if (!setter)
--- a/js/src/proxy/ScriptedProxyHandler.cpp
+++ b/js/src/proxy/ScriptedProxyHandler.cpp
@@ -1415,17 +1415,17 @@ js::proxy_revocable(JSContext* cx, unsig
 
     revoker->as<JSFunction>().initExtendedSlot(ScriptedProxyHandler::REVOKE_SLOT, proxyVal);
 
     RootedPlainObject result(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!result)
         return false;
 
     RootedValue revokeVal(cx, ObjectValue(*revoker));
-    if (!DefineProperty(cx, result, cx->names().proxy, proxyVal) ||
-        !DefineProperty(cx, result, cx->names().revoke, revokeVal))
+    if (!DefineDataProperty(cx, result, cx->names().proxy, proxyVal) ||
+        !DefineDataProperty(cx, result, cx->names().revoke, revokeVal))
     {
         return false;
     }
 
     args.rval().setObject(*result);
     return true;
 }
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -6940,40 +6940,40 @@ CreateLastWarningObject(JSContext* cx, J
     RootedString nameStr(cx);
     if (report->exnType == JSEXN_WARN)
         nameStr = JS_NewStringCopyZ(cx, "Warning");
     else
         nameStr = GetErrorTypeName(cx, report->exnType);
     if (!nameStr)
         return false;
     RootedValue nameVal(cx, StringValue(nameStr));
-    if (!DefineProperty(cx, warningObj, cx->names().name, nameVal))
+    if (!DefineDataProperty(cx, warningObj, cx->names().name, nameVal))
         return false;
 
     RootedString messageStr(cx, report->newMessageString(cx));
     if (!messageStr)
         return false;
     RootedValue messageVal(cx, StringValue(messageStr));
-    if (!DefineProperty(cx, warningObj, cx->names().message, messageVal))
+    if (!DefineDataProperty(cx, warningObj, cx->names().message, messageVal))
         return false;
 
     RootedValue linenoVal(cx, Int32Value(report->lineno));
-    if (!DefineProperty(cx, warningObj, cx->names().lineNumber, linenoVal))
+    if (!DefineDataProperty(cx, warningObj, cx->names().lineNumber, linenoVal))
         return false;
 
     RootedValue columnVal(cx, Int32Value(report->column));
-    if (!DefineProperty(cx, warningObj, cx->names().columnNumber, columnVal))
+    if (!DefineDataProperty(cx, warningObj, cx->names().columnNumber, columnVal))
         return false;
 
     RootedObject notesArray(cx, CreateErrorNotesArray(cx, report));
     if (!notesArray)
         return false;
 
     RootedValue notesArrayVal(cx, ObjectValue(*notesArray));
-    if (!DefineProperty(cx, warningObj, cx->names().notes, notesArrayVal))
+    if (!DefineDataProperty(cx, warningObj, cx->names().notes, notesArrayVal))
         return false;
 
     GetShellContext(cx)->lastWarning.setObject(*warningObj);
     return true;
 }
 
 static FILE*
 ErrorFilePointer()
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1188,17 +1188,17 @@ Debugger::wrapDebuggeeValue(JSContext* c
         switch (vp.whyMagic()) {
           case JS_OPTIMIZED_ARGUMENTS:   name = cx->names().missingArguments; break;
           case JS_OPTIMIZED_OUT:         name = cx->names().optimizedOut; break;
           case JS_UNINITIALIZED_LEXICAL: name = cx->names().uninitialized; break;
           default: MOZ_CRASH("Unsupported magic value escaped to Debugger");
         }
 
         RootedValue trueVal(cx, BooleanValue(true));
-        if (!DefineProperty(cx, optObj, name, trueVal))
+        if (!DefineDataProperty(cx, optObj, name, trueVal))
             return false;
 
         vp.setObject(*optObj);
     } else if (!cx->compartment()->wrap(cx, vp)) {
         vp.setUndefined();
         return false;
     }
 
@@ -5944,30 +5944,30 @@ class DebuggerScriptGetOffsetLocationMat
         } else {
             MOZ_ASSERT(flowData[r.frontOffset()].hasSingleEdge());
             lineno = flowData[r.frontOffset()].lineno();
             column = flowData[r.frontOffset()].column();
         }
 
         RootedId id(cx_, NameToId(cx_->names().lineNumber));
         RootedValue value(cx_, NumberValue(lineno));
-        if (!DefineProperty(cx_, result_, id, value))
+        if (!DefineDataProperty(cx_, result_, id, value))
             return false;
 
         value = NumberValue(column);
-        if (!DefineProperty(cx_, result_, cx_->names().columnNumber, value))
+        if (!DefineDataProperty(cx_, result_, cx_->names().columnNumber, value))
             return false;
 
         // The same entry point test that is used by getAllColumnOffsets.
         isEntryPoint = (isEntryPoint &&
                         !flowData[offset].hasNoEdges() &&
                         (flowData[offset].lineno() != r.frontLineNumber() ||
                          flowData[offset].column() != r.frontColumnNumber()));
         value.setBoolean(isEntryPoint);
-        if (!DefineProperty(cx_, result_, cx_->names().isEntryPoint, value))
+        if (!DefineDataProperty(cx_, result_, cx_->names().isEntryPoint, value))
             return false;
 
         return true;
     }
 
     ReturnType match(Handle<WasmInstanceObject*> instance) {
         size_t lineno;
         size_t column;
@@ -5981,25 +5981,25 @@ class DebuggerScriptGetOffsetLocationMat
         }
 
         result_.set(NewBuiltinClassInstance<PlainObject>(cx_));
         if (!result_)
             return false;
 
         RootedId id(cx_, NameToId(cx_->names().lineNumber));
         RootedValue value(cx_, NumberValue(lineno));
-        if (!DefineProperty(cx_, result_, id, value))
+        if (!DefineDataProperty(cx_, result_, id, value))
             return false;
 
         value = NumberValue(column);
-        if (!DefineProperty(cx_, result_, cx_->names().columnNumber, value))
+        if (!DefineDataProperty(cx_, result_, cx_->names().columnNumber, value))
             return false;
 
         value.setBoolean(true);
-        if (!DefineProperty(cx_, result_, cx_->names().isEntryPoint, value))
+        if (!DefineDataProperty(cx_, result_, cx_->names().isEntryPoint, value))
             return false;
 
         return true;
     }
 };
 
 static bool
 DebuggerScript_getOffsetLocation(JSContext* cx, unsigned argc, Value* vp)
@@ -6072,17 +6072,17 @@ DebuggerScript_getAllOffsets(JSContext* 
                 offsets = NewDenseEmptyArray(cx);
                 if (!offsets ||
                     !ValueToId<CanGC>(cx, v, &id))
                 {
                     return false;
                 }
 
                 RootedValue value(cx, ObjectValue(*offsets));
-                if (!DefineProperty(cx, result, id, value))
+                if (!DefineDataProperty(cx, result, id, value))
                     return false;
             }
 
             /* Append the current offset to the offsets array. */
             if (!NewbornArrayPush(cx, offsets, NumberValue(offset)))
                 return false;
         }
     }
@@ -6098,26 +6098,26 @@ class DebuggerScriptGetAllColumnOffsetsM
 
     bool appendColumnOffsetEntry(size_t lineno, size_t column, size_t offset) {
         RootedPlainObject entry(cx_, NewBuiltinClassInstance<PlainObject>(cx_));
         if (!entry)
             return false;
 
         RootedId id(cx_, NameToId(cx_->names().lineNumber));
         RootedValue value(cx_, NumberValue(lineno));
-        if (!DefineProperty(cx_, entry, id, value))
+        if (!DefineDataProperty(cx_, entry, id, value))
             return false;
 
         value = NumberValue(column);
-        if (!DefineProperty(cx_, entry, cx_->names().columnNumber, value))
+        if (!DefineDataProperty(cx_, entry, cx_->names().columnNumber, value))
             return false;
 
         id = NameToId(cx_->names().offset);
         value = NumberValue(offset);
-        if (!DefineProperty(cx_, entry, id, value))
+        if (!DefineDataProperty(cx_, entry, id, value))
             return false;
 
         return NewbornArrayPush(cx_, result_, ObjectValue(*entry));
     }
 
   public:
     explicit DebuggerScriptGetAllColumnOffsetsMatcher(JSContext* cx, MutableHandleObject result)
       : cx_(cx), result_(result) { }
@@ -6787,20 +6787,20 @@ DebuggerScript_getOffsetsCoverage(JSCont
         lineNumberValue.setNumber(double(r.frontLineNumber()));
         columnNumberValue.setNumber(double(r.frontColumnNumber()));
         countValue.setNumber(double(hits));
 
         // Create a new object with the offset, line number, column number, the
         // number of hit counts, and append it to the array.
         item = NewObjectWithGivenProto<PlainObject>(cx, nullptr);
         if (!item ||
-            !DefineProperty(cx, item, offsetId, offsetValue) ||
-            !DefineProperty(cx, item, lineNumberId, lineNumberValue) ||
-            !DefineProperty(cx, item, columnNumberId, columnNumberValue) ||
-            !DefineProperty(cx, item, countId, countValue) ||
+            !DefineDataProperty(cx, item, offsetId, offsetValue) ||
+            !DefineDataProperty(cx, item, lineNumberId, lineNumberValue) ||
+            !DefineDataProperty(cx, item, columnNumberId, columnNumberValue) ||
+            !DefineDataProperty(cx, item, countId, countValue) ||
             !NewbornArrayPush(cx, result, ObjectValue(*item)))
         {
             return false;
         }
 
         // If the current instruction has thrown, then decrement the hit counts
         // with the number of throws.
         counts = sc->maybeGetThrowCounts(offset);
@@ -11426,17 +11426,17 @@ Builder::Object::definePropertyToTrusted
     // We should have checked for false Objects before calling this.
     MOZ_ASSERT(value);
 
     JSAtom* atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
 
-    return DefineProperty(cx, value, id, trusted);
+    return DefineDataProperty(cx, value, id, trusted);
 }
 
 bool
 Builder::Object::defineProperty(JSContext* cx, const char* name, JS::HandleValue propval_)
 {
     AutoCompartment ac(cx, debuggerObject());
 
     RootedValue propval(cx, propval_);
@@ -11551,21 +11551,18 @@ JS_DefineDebuggerObject(JSContext* cx, H
         return false;
 
     debuggeeWouldRunProto =
         GlobalObject::getOrCreateCustomErrorPrototype(cx, global, JSEXN_DEBUGGEEWOULDRUN);
     if (!debuggeeWouldRunProto)
         return false;
     debuggeeWouldRunCtor = global->getConstructor(JSProto_DebuggeeWouldRun);
     RootedId debuggeeWouldRunId(cx, NameToId(ClassName(JSProto_DebuggeeWouldRun, cx)));
-    if (!DefineProperty(cx, debugCtor, debuggeeWouldRunId, debuggeeWouldRunCtor,
-                        nullptr, nullptr, 0))
-    {
-        return false;
-    }
+    if (!DefineDataProperty(cx, debugCtor, debuggeeWouldRunId, debuggeeWouldRunCtor, 0))
+        return false;
 
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_FRAME_PROTO, ObjectValue(*frameProto));
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_OBJECT_PROTO, ObjectValue(*objectProto));
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_SCRIPT_PROTO, ObjectValue(*scriptProto));
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_SOURCE_PROTO, ObjectValue(*sourceProto));
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_ENV_PROTO, ObjectValue(*envProto));
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_MEMORY_PROTO, ObjectValue(*memoryProto));
     return true;
@@ -11685,28 +11682,28 @@ DefineStringProperty(JSContext* cx, Hand
 {
     RootedValue val(cx, UndefinedValue());
     if (strVal) {
         JSAtom* atomized = Atomize(cx, strVal, strlen(strVal));
         if (!atomized)
             return false;
         val = StringValue(atomized);
     }
-    return DefineProperty(cx, obj, propName, val);
+    return DefineDataProperty(cx, obj, propName, val);
 }
 
 JSObject*
 GarbageCollectionEvent::toJSObject(JSContext* cx) const
 {
     RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
     RootedValue gcCycleNumberVal(cx, NumberValue(majorGCNumber_));
     if (!obj ||
         !DefineStringProperty(cx, obj, cx->names().nonincrementalReason, nonincrementalReason) ||
         !DefineStringProperty(cx, obj, cx->names().reason, reason) ||
-        !DefineProperty(cx, obj, cx->names().gcCycleNumber, gcCycleNumberVal))
+        !DefineDataProperty(cx, obj, cx->names().gcCycleNumber, gcCycleNumberVal))
     {
         return nullptr;
     }
 
     RootedArrayObject slicesArray(cx, NewDenseEmptyArray(cx));
     if (!slicesArray)
         return nullptr;
 
@@ -11716,29 +11713,29 @@ GarbageCollectionEvent::toJSObject(JSCon
     for (auto range = collections.all(); !range.empty(); range.popFront()) {
         RootedPlainObject collectionObj(cx, NewBuiltinClassInstance<PlainObject>(cx));
         if (!collectionObj)
             return nullptr;
 
         RootedValue start(cx), end(cx);
         start = NumberValue((range.front().startTimestamp - originTime).ToMilliseconds());
         end = NumberValue((range.front().endTimestamp - originTime).ToMilliseconds());
-        if (!DefineProperty(cx, collectionObj, cx->names().startTimestamp, start) ||
-            !DefineProperty(cx, collectionObj, cx->names().endTimestamp, end))
+        if (!DefineDataProperty(cx, collectionObj, cx->names().startTimestamp, start) ||
+            !DefineDataProperty(cx, collectionObj, cx->names().endTimestamp, end))
         {
             return nullptr;
         }
 
         RootedValue collectionVal(cx, ObjectValue(*collectionObj));
-        if (!DefineElement(cx, slicesArray, idx++, collectionVal))
+        if (!DefineDataElement(cx, slicesArray, idx++, collectionVal))
             return nullptr;
     }
 
     RootedValue slicesValue(cx, ObjectValue(*slicesArray));
-    if (!DefineProperty(cx, obj, cx->names().collections, slicesValue))
+    if (!DefineDataProperty(cx, obj, cx->names().collections, slicesValue))
         return nullptr;
 
     return obj;
 }
 
 JS_PUBLIC_API(bool)
 FireOnGarbageCollectionHookRequired(JSContext* cx)
 {
--- a/js/src/vm/DebuggerMemory.cpp
+++ b/js/src/vm/DebuggerMemory.cpp
@@ -198,44 +198,44 @@ DebuggerMemory::drainAllocationsLog(JSCo
 
         // Don't pop the AllocationsLogEntry yet. The queue's links are followed
         // by the GC to find the AllocationsLogEntry, but are not barriered, so
         // we must edit them with great care. Use the queue entry in place, and
         // then pop and delete together.
         Debugger::AllocationsLogEntry& entry = dbg->allocationsLog.front();
 
         RootedValue frame(cx, ObjectOrNullValue(entry.frame));
-        if (!DefineProperty(cx, obj, cx->names().frame, frame))
+        if (!DefineDataProperty(cx, obj, cx->names().frame, frame))
             return false;
 
         double when = (entry.when -
                        mozilla::TimeStamp::ProcessCreation()).ToMilliseconds();
         RootedValue timestampValue(cx, NumberValue(when));
-        if (!DefineProperty(cx, obj, cx->names().timestamp, timestampValue))
+        if (!DefineDataProperty(cx, obj, cx->names().timestamp, timestampValue))
             return false;
 
         RootedString className(cx, Atomize(cx, entry.className, strlen(entry.className)));
         if (!className)
             return false;
         RootedValue classNameValue(cx, StringValue(className));
-        if (!DefineProperty(cx, obj, cx->names().class_, classNameValue))
+        if (!DefineDataProperty(cx, obj, cx->names().class_, classNameValue))
             return false;
 
         RootedValue ctorName(cx, NullValue());
         if (entry.ctorName)
             ctorName.setString(entry.ctorName);
-        if (!DefineProperty(cx, obj, cx->names().constructor, ctorName))
+        if (!DefineDataProperty(cx, obj, cx->names().constructor, ctorName))
             return false;
 
         RootedValue size(cx, NumberValue(entry.size));
-        if (!DefineProperty(cx, obj, cx->names().size, size))
+        if (!DefineDataProperty(cx, obj, cx->names().size, size))
             return false;
 
         RootedValue inNursery(cx, BooleanValue(entry.inNursery));
-        if (!DefineProperty(cx, obj, cx->names().inNursery, inNursery))
+        if (!DefineDataProperty(cx, obj, cx->names().inNursery, inNursery))
             return false;
 
         result->setDenseElement(i, ObjectValue(*obj));
 
         // Pop the front queue entry, and delete it immediately, so that the GC
         // sees the AllocationsLogEntry's HeapPtr barriers run atomically with
         // the change to the graph (the queue link).
         if (!dbg->allocationsLog.popFront()) {
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -274,10 +274,10 @@ js::ErrorObject::setStack(JSContext* cx,
 js::ErrorObject::setStack_impl(JSContext* cx, const CallArgs& args)
 {
     RootedObject thisObj(cx, &args.thisv().toObject());
 
     if (!args.requireAtLeast(cx, "(set stack)", 1))
         return false;
     RootedValue val(cx, args[0]);
 
-    return DefineProperty(cx, thisObj, cx->names().stack, val);
+    return DefineDataProperty(cx, thisObj, cx->names().stack, val);
 }
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -221,17 +221,17 @@ GlobalObject::resolveConstructor(JSConte
     RootedObject ctor(cx, clasp->specCreateConstructorHook()(cx, key));
     if (!ctor)
         return false;
 
     RootedId id(cx, NameToId(ClassName(key, cx)));
     if (isObjectOrFunction) {
         if (clasp->specShouldDefineConstructor()) {
             RootedValue ctorValue(cx, ObjectValue(*ctor));
-            if (!DefineProperty(cx, global, id, ctorValue, nullptr, nullptr, JSPROP_RESOLVING))
+            if (!DefineDataProperty(cx, global, id, ctorValue, JSPROP_RESOLVING))
                 return false;
         }
 
         global->setConstructor(key, ObjectValue(*ctor));
     }
 
     // If we're operating on the self-hosting global, we don't want any
     // functions and properties on the builtins and their prototypes.
@@ -266,17 +266,17 @@ GlobalObject::resolveConstructor(JSConte
 
     if (!isObjectOrFunction) {
         // Any operations that modifies the global object should be placed
         // after any other fallible operations.
 
         // Fallible operation that modifies the global object.
         if (clasp->specShouldDefineConstructor()) {
             RootedValue ctorValue(cx, ObjectValue(*ctor));
-            if (!DefineProperty(cx, global, id, ctorValue, nullptr, nullptr, JSPROP_RESOLVING))
+            if (!DefineDataProperty(cx, global, id, ctorValue, JSPROP_RESOLVING))
                 return false;
         }
 
         // Infallible operations that modify the global object.
         global->setConstructor(key, ObjectValue(*ctor));
         if (proto)
             global->setPrototype(key, ObjectValue(*proto));
     }
@@ -292,17 +292,17 @@ GlobalObject::initBuiltinConstructor(JSC
     MOZ_ASSERT(key != JSProto_Null);
     MOZ_ASSERT(ctor);
     MOZ_ASSERT(proto);
 
     RootedId id(cx, NameToId(ClassName(key, cx)));
     MOZ_ASSERT(!global->lookup(cx, id));
 
     RootedValue ctorValue(cx, ObjectValue(*ctor));
-    if (!DefineProperty(cx, global, id, ctorValue, nullptr, nullptr, JSPROP_RESOLVING))
+    if (!DefineDataProperty(cx, global, id, ctorValue, JSPROP_RESOLVING))
         return false;
 
     global->setConstructor(key, ObjectValue(*ctor));
     global->setPrototype(key, ObjectValue(*proto));
     return true;
 }
 
 GlobalObject*
@@ -400,18 +400,18 @@ GlobalObject::valueIsEval(const Value& v
     Value eval = getSlot(EVAL);
     return eval.isObject() && eval == val;
 }
 
 /* static */ bool
 GlobalObject::initStandardClasses(JSContext* cx, Handle<GlobalObject*> global)
 {
     /* Define a top-level property 'undefined' with the undefined value. */
-    if (!DefineProperty(cx, global, cx->names().undefined, UndefinedHandleValue,
-                        nullptr, nullptr, JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_RESOLVING))
+    if (!DefineDataProperty(cx, global, cx->names().undefined, UndefinedHandleValue,
+                            JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_RESOLVING))
     {
         return false;
     }
 
     for (size_t k = 0; k < JSProto_LIMIT; ++k) {
         if (!ensureConstructor(cx, global, static_cast<JSProtoKey>(k)))
             return false;
     }
@@ -447,18 +447,18 @@ InitBareBuiltinCtor(JSContext* cx, Handl
  * Even those are only created as bare constructors without any properties
  * or functions.
  */
 /* static */ bool
 GlobalObject::initSelfHostingBuiltins(JSContext* cx, Handle<GlobalObject*> global,
                                       const JSFunctionSpec* builtins)
 {
     // Define a top-level property 'undefined' with the undefined value.
-    if (!DefineProperty(cx, global, cx->names().undefined, UndefinedHandleValue,
-                        nullptr, nullptr, JSPROP_PERMANENT | JSPROP_READONLY))
+    if (!DefineDataProperty(cx, global, cx->names().undefined, UndefinedHandleValue,
+                            JSPROP_PERMANENT | JSPROP_READONLY))
     {
         return false;
     }
 
     RootedValue std_isConcatSpreadable(cx);
     std_isConcatSpreadable.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::isConcatSpreadable));
     if (!JS_DefineProperty(cx, global, "std_isConcatSpreadable", std_isConcatSpreadable,
                            JSPROP_PERMANENT | JSPROP_READONLY))
@@ -591,20 +591,18 @@ bool
 js::LinkConstructorAndPrototype(JSContext* cx, JSObject* ctor_, JSObject* proto_,
                                 unsigned prototypeAttrs, unsigned constructorAttrs)
 {
     RootedObject ctor(cx, ctor_), proto(cx, proto_);
 
     RootedValue protoVal(cx, ObjectValue(*proto));
     RootedValue ctorVal(cx, ObjectValue(*ctor));
 
-    return DefineProperty(cx, ctor, cx->names().prototype, protoVal, nullptr, nullptr,
-                          prototypeAttrs) &&
-           DefineProperty(cx, proto, cx->names().constructor, ctorVal, nullptr, nullptr,
-                          constructorAttrs);
+    return DefineDataProperty(cx, ctor, cx->names().prototype, protoVal, prototypeAttrs) &&
+           DefineDataProperty(cx, proto, cx->names().constructor, ctorVal, constructorAttrs);
 }
 
 bool
 js::DefinePropertiesAndFunctions(JSContext* cx, HandleObject obj,
                                  const JSPropertySpec* ps, const JSFunctionSpec* fs)
 {
     if (ps && !JS_DefineProperties(cx, obj, ps))
         return false;
@@ -613,17 +611,17 @@ js::DefinePropertiesAndFunctions(JSConte
     return true;
 }
 
 bool
 js::DefineToStringTag(JSContext* cx, HandleObject obj, JSAtom* tag)
 {
     RootedId toStringTagId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().toStringTag));
     RootedValue tagString(cx, StringValue(tag));
-    return DefineProperty(cx, obj, toStringTagId, tagString, nullptr, nullptr, JSPROP_READONLY);
+    return DefineDataProperty(cx, obj, toStringTagId, tagString, JSPROP_READONLY);
 }
 
 static void
 GlobalDebuggees_finalize(FreeOp* fop, JSObject* obj)
 {
     MOZ_ASSERT(fop->maybeOnHelperThread());
     fop->delete_((GlobalObject::DebuggerVector*) obj->as<NativeObject>().getPrivate());
 }
@@ -740,18 +738,18 @@ GlobalObject::getIntrinsicsHolder(JSCont
     } else {
         intrinsicsHolder = NewObjectWithGivenProto<PlainObject>(cx, nullptr, TenuredObject);
         if (!intrinsicsHolder)
             return nullptr;
     }
 
     /* Define a property 'global' with the current global as its value. */
     RootedValue globalValue(cx, ObjectValue(*global));
-    if (!DefineProperty(cx, intrinsicsHolder, cx->names().global, globalValue,
-                        nullptr, nullptr, JSPROP_PERMANENT | JSPROP_READONLY))
+    if (!DefineDataProperty(cx, intrinsicsHolder, cx->names().global, globalValue,
+                            JSPROP_PERMANENT | JSPROP_READONLY))
     {
         return nullptr;
     }
 
     // Install the intrinsics holder in the intrinsics.
     global->setReservedSlot(INTRINSICS, ObjectValue(*intrinsicsHolder));
     return intrinsicsHolder;
 }
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -431,17 +431,17 @@ DefVarOperation(JSContext* cx, HandleObj
 
     Rooted<PropertyResult> prop(cx);
     RootedObject obj2(cx);
     if (!LookupProperty(cx, varobj, dn, &obj2, &prop))
         return false;
 
     /* Steps 8c, 8d. */
     if (!prop || (obj2 != varobj && varobj->is<GlobalObject>())) {
-        if (!DefineProperty(cx, varobj, dn, UndefinedHandleValue, nullptr, nullptr, attrs))
+        if (!DefineDataProperty(cx, varobj, dn, UndefinedHandleValue, attrs))
             return false;
     }
 
     if (varobj->is<GlobalObject>()) {
         if (!varobj->compartment()->addToVarNames(cx, dn))
             return false;
     }
 
@@ -643,17 +643,17 @@ InitElemOperation(JSContext* cx, jsbytec
 {
     MOZ_ASSERT(!val.isMagic(JS_ELEMENTS_HOLE));
 
     RootedId id(cx);
     if (!ToPropertyKey(cx, idval, &id))
         return false;
 
     unsigned flags = GetInitDataPropAttrs(JSOp(*pc));
-    return DefineProperty(cx, obj, id, val, nullptr, nullptr, flags);
+    return DefineDataProperty(cx, obj, id, val, flags);
 }
 
 static MOZ_ALWAYS_INLINE bool
 InitArrayElemOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, uint32_t index, HandleValue val)
 {
     JSOp op = JSOp(*pc);
     MOZ_ASSERT(op == JSOP_INITELEM_ARRAY || op == JSOP_INITELEM_INC);
 
@@ -677,17 +677,17 @@ InitArrayElemOperation(JSContext* cx, js
      * cannot follow JSOP_SPREAD.
      */
     if (val.isMagic(JS_ELEMENTS_HOLE)) {
         if (op == JSOP_INITELEM_INC) {
             if (!SetLengthProperty(cx, obj, index + 1))
                 return false;
         }
     } else {
-        if (!DefineElement(cx, obj, index, val, nullptr, nullptr, JSPROP_ENUMERATE))
+        if (!DefineDataElement(cx, obj, index, val, JSPROP_ENUMERATE))
             return false;
     }
 
     return true;
 }
 
 #define RELATIONAL_OP(OP)                                                     \
     JS_BEGIN_MACRO                                                            \
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -4493,17 +4493,17 @@ js::DefFunOperation(JSContext* cx, Handl
      * impermanent.
      */
     unsigned attrs = script->isActiveEval()
                      ? JSPROP_ENUMERATE
                      : JSPROP_ENUMERATE | JSPROP_PERMANENT;
 
     /* Steps 5d, 5f. */
     if (!prop || pobj != parent) {
-        if (!DefineProperty(cx, parent, name, rval, nullptr, nullptr, attrs))
+        if (!DefineDataProperty(cx, parent, name, rval, attrs))
             return false;
 
         return parent->is<GlobalObject>() ? parent->compartment()->addToVarNames(cx, name) : true;
     }
 
     /*
      * Step 5e.
      *
@@ -4512,17 +4512,17 @@ js::DefFunOperation(JSContext* cx, Handl
      * extant variable in the frame, the DebugEnvironmentProxy takes care of storing
      * the function in the stack frame (for non-aliased variables) or on the
      * scope object (for aliased).
      */
     MOZ_ASSERT(parent->isNative() || parent->is<DebugEnvironmentProxy>());
     if (parent->is<GlobalObject>()) {
         Shape* shape = prop.shape();
         if (shape->configurable()) {
-            if (!DefineProperty(cx, parent, name, rval, nullptr, nullptr, attrs))
+            if (!DefineDataProperty(cx, parent, name, rval, attrs))
                 return false;
         } else {
             MOZ_ASSERT(shape->isDataDescriptor());
             MOZ_ASSERT(shape->writable());
             MOZ_ASSERT(shape->enumerable());
         }
 
         // Careful: the presence of a shape, even one appearing to derive from
@@ -4830,18 +4830,17 @@ js::InitGetterSetterOperation(JSContext*
     } else {
         MOZ_ASSERT(op == JSOP_INITPROP_SETTER || op == JSOP_INITELEM_SETTER ||
                    op == JSOP_INITHIDDENPROP_SETTER || op == JSOP_INITHIDDENELEM_SETTER);
         getter = nullptr;
         setter = CastAsSetterOp(val);
         attrs |= JSPROP_SETTER;
     }
 
-    RootedValue scratch(cx);
-    return DefineProperty(cx, obj, id, scratch, getter, setter, attrs);
+    return DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
 }
 
 bool
 js::InitGetterSetterOperation(JSContext* cx, jsbytecode* pc, HandleObject obj,
                               HandlePropertyName name, HandleObject val)
 {
     RootedId id(cx, NameToId(name));
     return InitGetterSetterOperation(cx, pc, obj, id, val);
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -2565,17 +2565,17 @@ js::SetPropertyByDefining(JSContext* cx,
     if (!PurgeEnvironmentChain(cx, receiver, id))
         return false;
 
     // Steps 5.e.iii-iv. and 5.f.i. Define the new data property.
     unsigned attrs =
         existing
         ? JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_PERMANENT
         : JSPROP_ENUMERATE;
-    return DefineProperty(cx, receiver, id, v, nullptr, nullptr, attrs, result);
+    return DefineDataProperty(cx, receiver, id, v, attrs, result);
 }
 
 // When setting |id| for |receiver| and |obj| has no property for id, continue
 // the search up the prototype chain.
 bool
 js::SetPropertyOnProto(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
                        HandleValue receiver, ObjectOpResult& result)
 {
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -452,19 +452,18 @@ intrinsic_MakeConstructible(JSContext* c
     MOZ_ASSERT(args[0].isObject());
     MOZ_ASSERT(args[0].toObject().is<JSFunction>());
     MOZ_ASSERT(args[0].toObject().as<JSFunction>().isSelfHostedBuiltin());
     MOZ_ASSERT(args[1].isObjectOrNull());
 
     // Normal .prototype properties aren't enumerable.  But for this to clone
     // correctly, it must be enumerable.
     RootedObject ctor(cx, &args[0].toObject());
-    if (!DefineProperty(cx, ctor, cx->names().prototype, args[1],
-                        nullptr, nullptr,
-                        JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT))
+    if (!DefineDataProperty(cx, ctor, cx->names().prototype, args[1],
+                            JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT))
     {
         return false;
     }
 
     ctor->as<JSFunction>().setIsConstructor();
     args.rval().setUndefined();
     return true;
 }
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -2552,17 +2552,17 @@ JSStructuredCloneReader::read(MutableHan
             if (!MapObject::set(context(), obj, key, val))
                 return false;
         } else {
             // For any other Object, interpret them as plain properties.
             RootedId id(context());
             if (!ValueToId<CanGC>(context(), key, &id))
                 return false;
 
-            if (!DefineProperty(context(), obj, id, val))
+            if (!DefineDataProperty(context(), obj, id, val))
                 return false;
          }
     }
 
     allObjs.clear();
 
     return true;
 }
--- a/js/src/vm/UbiNodeCensus.cpp
+++ b/js/src/vm/UbiNodeCensus.cpp
@@ -97,29 +97,29 @@ SimpleCount::report(JSContext* cx, Count
 {
     Count& count = static_cast<Count&>(countBase);
 
     RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!obj)
         return false;
 
     RootedValue countValue(cx, NumberValue(count.total_));
-    if (reportCount && !DefineProperty(cx, obj, cx->names().count, countValue))
+    if (reportCount && !DefineDataProperty(cx, obj, cx->names().count, countValue))
         return false;
 
     RootedValue bytesValue(cx, NumberValue(count.totalBytes_));
-    if (reportBytes && !DefineProperty(cx, obj, cx->names().bytes, bytesValue))
+    if (reportBytes && !DefineDataProperty(cx, obj, cx->names().bytes, bytesValue))
         return false;
 
     if (label) {
         JSString* labelString = JS_NewUCStringCopyZ(cx, label.get());
         if (!labelString)
             return false;
         RootedValue labelValue(cx, StringValue(labelString));
-        if (!DefineProperty(cx, obj, cx->names().label, labelValue))
+        if (!DefineDataProperty(cx, obj, cx->names().label, labelValue))
             return false;
     }
 
     report.setObject(*obj);
     return true;
 }
 
 
@@ -285,32 +285,32 @@ ByCoarseType::report(JSContext* cx, Coun
     Count& count = static_cast<Count&>(countBase);
 
     RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!obj)
         return false;
 
     RootedValue objectsReport(cx);
     if (!count.objects->report(cx, &objectsReport) ||
-        !DefineProperty(cx, obj, cx->names().objects, objectsReport))
+        !DefineDataProperty(cx, obj, cx->names().objects, objectsReport))
         return false;
 
     RootedValue scriptsReport(cx);
     if (!count.scripts->report(cx, &scriptsReport) ||
-        !DefineProperty(cx, obj, cx->names().scripts, scriptsReport))
+        !DefineDataProperty(cx, obj, cx->names().scripts, scriptsReport))
         return false;
 
     RootedValue stringsReport(cx);
     if (!count.strings->report(cx, &stringsReport) ||
-        !DefineProperty(cx, obj, cx->names().strings, stringsReport))
+        !DefineDataProperty(cx, obj, cx->names().strings, stringsReport))
         return false;
 
     RootedValue otherReport(cx);
     if (!count.other->report(cx, &otherReport) ||
-        !DefineProperty(cx, obj, cx->names().other, otherReport))
+        !DefineDataProperty(cx, obj, cx->names().other, otherReport))
         return false;
 
     report.setObject(*obj);
     return true;
 }
 
 
 // Comparison function for sorting hash table entries by the smallest node ID
@@ -373,17 +373,17 @@ countMapToObject(JSContext* cx, Map& map
 
         const char* name = getName(entry->key());
         MOZ_ASSERT(name);
         JSAtom* atom = Atomize(cx, name, strlen(name));
         if (!atom)
             return nullptr;
 
         RootedId entryId(cx, AtomToId(atom));
-        if (!DefineProperty(cx, obj, entryId, thenReport))
+        if (!DefineDataProperty(cx, obj, entryId, thenReport))
             return nullptr;
     }
 
     return obj;
 }
 
 
 // A type that categorizes nodes that are JSObjects by their class name,
@@ -479,17 +479,17 @@ ByObjectClass::report(JSContext* cx, Cou
     RootedPlainObject obj(cx, countMapToObject(cx, count.table, [](const char* key) {
         return key;
     }));
     if (!obj)
         return false;
 
     RootedValue otherReport(cx);
     if (!count.other->report(cx, &otherReport) ||
-        !DefineProperty(cx, obj, cx->names().other, otherReport))
+        !DefineDataProperty(cx, obj, cx->names().other, otherReport))
         return false;
 
     report.setObject(*obj);
     return true;
 }
 
 
 // A count type that categorizes nodes by their ubi::Node::typeName.
@@ -590,17 +590,17 @@ ByUbinodeType::report(JSContext* cx, Cou
 
         const char16_t* name = entry.key();
         MOZ_ASSERT(name);
         JSAtom* atom = AtomizeChars(cx, name, js_strlen(name));
         if (!atom)
             return false;
         RootedId entryId(cx, AtomToId(atom));
 
-        if (!DefineProperty(cx, obj, entryId, typeReport))
+        if (!DefineDataProperty(cx, obj, entryId, typeReport))
             return false;
     }
 
     report.setObject(*obj);
     return true;
 }
 
 
@@ -898,17 +898,17 @@ ByFilename::report(JSContext* cx, CountB
     RootedPlainObject obj(cx, countMapToObject(cx, count.table, [](const UniqueCString& key) {
         return key.get();
     }));
     if (!obj)
         return false;
 
     RootedValue noFilenameReport(cx);
     if (!count.noFilename->report(cx, &noFilenameReport) ||
-        !DefineProperty(cx, obj, cx->names().noFilename, noFilenameReport))
+        !DefineDataProperty(cx, obj, cx->names().noFilename, noFilenameReport))
     {
         return false;
     }
 
     report.setObject(*obj);
     return true;
 }
 
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -2196,34 +2196,34 @@ InitConstructor(JSContext* cx, HandleObj
     RootedAtom tag(cx, Atomize(cx, tagStr.get(), strlen(tagStr.get())));
     if (!tag)
         return false;
     if (!DefineToStringTag(cx, proto, tag))
         return false;
 
     RootedId id(cx, AtomToId(className));
     RootedValue ctorValue(cx, ObjectValue(*ctor));
-    return DefineProperty(cx, wasm, id, ctorValue, nullptr, nullptr, 0);
+    return DefineDataProperty(cx, wasm, id, ctorValue, 0);
 }
 
 static bool
 InitErrorClass(JSContext* cx, HandleObject wasm, const char* name, JSExnType exn)
 {
     Handle<GlobalObject*> global = cx->global();
     RootedObject proto(cx, GlobalObject::getOrCreateCustomErrorPrototype(cx, global, exn));
     if (!proto)
         return false;
 
     RootedAtom className(cx, Atomize(cx, name, strlen(name)));
     if (!className)
         return false;
 
     RootedId id(cx, AtomToId(className));
     RootedValue ctorValue(cx, global->getConstructor(GetExceptionProtoKey(exn)));
-    return DefineProperty(cx, wasm, id, ctorValue, nullptr, nullptr, 0);
+    return DefineDataProperty(cx, wasm, id, ctorValue, 0);
 }
 
 JSObject*
 js::InitWebAssemblyClass(JSContext* cx, HandleObject obj)
 {
     MOZ_RELEASE_ASSERT(HasSupport(cx));
 
     Handle<GlobalObject*> global = obj.as<GlobalObject>();