Bug 1595745 - Part 5: Change JSON to use ClassSpec. r=mgaudet
☠☠ backed out by ec8cad689121 ☠ ☠
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 15 Nov 2019 15:02:53 +0000
changeset 502199 d5f5e9091fb049e19001b408e9c784178348fd5b
parent 502198 6c917c2ca4a7b1799ea159d5cc0f88ec85e11148
child 502200 68c5cdced300d92c3102c2fdddab32459e14e95d
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmgaudet
bugs1595745
milestone72.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 1595745 - Part 5: Change JSON to use ClassSpec. r=mgaudet The JSON ClassSpec uses a custom 'createConstructor', because the JSON object is a singleton object and not a built-in constructor function. Differential Revision: https://phabricator.services.mozilla.com/D52661
js/public/ProtoKey.h
js/src/builtin/JSON.cpp
js/src/builtin/JSON.h
--- a/js/public/ProtoKey.h
+++ b/js/public/ProtoKey.h
@@ -49,17 +49,17 @@
 #endif
 
 #define JS_FOR_PROTOTYPES_(REAL, IMAGINARY, REAL_IF_INTL, REAL_IF_BDATA)     \
   IMAGINARY(Null, InitNullClass, dummy)                                      \
   REAL(Object, InitViaClassSpec, OCLASP(Plain))                              \
   REAL(Function, InitViaClassSpec, &JSFunction::class_)                      \
   REAL(Array, InitViaClassSpec, OCLASP(Array))                               \
   REAL(Boolean, InitViaClassSpec, OCLASP(Boolean))                           \
-  REAL(JSON, InitJSONClass, CLASP(JSON))                                     \
+  REAL(JSON, InitViaClassSpec, CLASP(JSON))                                  \
   REAL(Date, InitViaClassSpec, OCLASP(Date))                                 \
   REAL(Math, InitMathClass, CLASP(Math))                                     \
   REAL(Number, InitViaClassSpec, OCLASP(Number))                             \
   REAL(String, InitViaClassSpec, OCLASP(String))                             \
   REAL(RegExp, InitViaClassSpec, OCLASP(RegExp))                             \
   REAL(Error, InitViaClassSpec, ERROR_CLASP(JSEXN_ERR))                      \
   REAL(InternalError, InitViaClassSpec, ERROR_CLASP(JSEXN_INTERNALERR))      \
   REAL(EvalError, InitViaClassSpec, ERROR_CLASP(JSEXN_EVALERR))              \
--- a/js/src/builtin/JSON.cpp
+++ b/js/src/builtin/JSON.cpp
@@ -36,19 +36,16 @@ using namespace js;
 
 using mozilla::CheckedInt;
 using mozilla::IsFinite;
 using mozilla::Maybe;
 using mozilla::RangedPtr;
 
 using JS::AutoStableStringChars;
 
-const JSClass js::JSONClass = {js_JSON_str,
-                               JSCLASS_HAS_CACHED_PROTO(JSProto_JSON)};
-
 /* ES5 15.12.3 Quote.
  * Requires that the destination has enough space allocated for src after
  * escaping (that is, `2 + 6 * (srcEnd - srcBegin)` characters).
  */
 template <typename SrcCharT, typename DstCharT>
 static MOZ_ALWAYS_INLINE RangedPtr<DstCharT> InfallibleQuote(
     RangedPtr<const SrcCharT> srcBegin, RangedPtr<const SrcCharT> srcEnd,
     RangedPtr<DstCharT> dstPtr) {
@@ -1099,35 +1096,26 @@ bool json_stringify(JSContext* cx, unsig
   return true;
 }
 
 static const JSFunctionSpec json_static_methods[] = {
     JS_FN(js_toSource_str, json_toSource, 0, 0),
     JS_FN("parse", json_parse, 2, 0), JS_FN("stringify", json_stringify, 3, 0),
     JS_FS_END};
 
-JSObject* js::InitJSONClass(JSContext* cx, Handle<GlobalObject*> global) {
+static const JSPropertySpec json_static_properties[] = {
+    JS_STRING_SYM_PS(toStringTag, "JSON", JSPROP_READONLY), JS_PS_END};
+
+static JSObject* CreateJSONObject(JSContext* cx, JSProtoKey key) {
+  Handle<GlobalObject*> global = cx->global();
   RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
   if (!proto) {
     return nullptr;
   }
-  RootedObject JSON(
-      cx, NewObjectWithGivenProto(cx, &JSONClass, proto, SingletonObject));
-  if (!JSON) {
-    return nullptr;
-  }
-
-  if (!JS_DefineProperty(cx, global, js_JSON_str, JSON, JSPROP_RESOLVING)) {
-    return nullptr;
-  }
+  return NewObjectWithGivenProto(cx, &JSONClass, proto, SingletonObject);
+}
 
-  if (!JS_DefineFunctions(cx, JSON, json_static_methods)) {
-    return nullptr;
-  }
+static const ClassSpec JSONClassSpec = {
+    CreateJSONObject, nullptr, json_static_methods, json_static_properties};
 
-  if (!DefineToStringTag(cx, JSON, cx->names().JSON)) {
-    return nullptr;
-  }
-
-  global->setConstructor(JSProto_JSON, ObjectValue(*JSON));
-
-  return JSON;
-}
+const JSClass js::JSONClass = {js_JSON_str,
+                               JSCLASS_HAS_CACHED_PROTO(JSProto_JSON),
+                               JS_NULL_CLASS_OPS, &JSONClassSpec};
--- a/js/src/builtin/JSON.h
+++ b/js/src/builtin/JSON.h
@@ -10,23 +10,20 @@
 #include "mozilla/Range.h"
 
 #include "NamespaceImports.h"
 
 #include "js/RootingAPI.h"
 
 namespace js {
 
-class GlobalObject;
 class StringBuffer;
 
 extern const JSClass JSONClass;
 
-extern JSObject* InitJSONClass(JSContext* cx, Handle<GlobalObject*> obj);
-
 enum class StringifyBehavior { Normal, RestrictedSafe };
 
 /**
  * If maybeSafely is true, Stringify will attempt to assert the API requirements
  * of JS::ToJSONMaybeSafely as it traverses the graph, and will not try to
  * invoke .toJSON on things as it goes.
  */
 extern bool Stringify(JSContext* cx, js::MutableHandleValue vp,