Bug 1510588 - Fix a bug in ObjectGroup::defaultNewGroup with TypedObject and Reflect.construct. r=bhackett
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 09 Jan 2019 16:41:35 +0000
changeset 510210 f7223955d3402473d45beaed2ca616f7541ca80f
parent 510209 f9e54ff712bcddd257a3c4084839e6c70b40ec53
child 510211 f8bb48d6a644a8bd2879dd5b397724c5d9bbda40
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs1510588
milestone66.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 1510588 - Fix a bug in ObjectGroup::defaultNewGroup with TypedObject and Reflect.construct. r=bhackett Differential Revision: https://phabricator.services.mozilla.com/D16044
js/src/jit-test/tests/TypedObject/bug1510588.js
js/src/vm/ObjectGroup.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/bug1510588.js
@@ -0,0 +1,2 @@
+var t = new TypedObject.StructType({});
+Reflect.construct(function() {}, [], t);
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -379,17 +379,19 @@ struct ObjectGroupRealm::NewEntry {
       : group(group), associated(associated) {}
 
   struct Lookup {
     const Class* clasp;
     TaggedProto proto;
     JSObject* associated;
 
     Lookup(const Class* clasp, TaggedProto proto, JSObject* associated)
-        : clasp(clasp), proto(proto), associated(associated) {}
+        : clasp(clasp), proto(proto), associated(associated) {
+      MOZ_ASSERT((associated && associated->is<JSFunction>()) == !clasp);
+    }
 
     explicit Lookup(const NewEntry& entry)
         : clasp(entry.group.unbarrieredGet()->clasp()),
           proto(entry.group.unbarrieredGet()->proto()),
           associated(entry.associated) {
       if (associated && associated->is<JSFunction>()) {
         clasp = nullptr;
       }
@@ -489,31 +491,37 @@ MOZ_ALWAYS_INLINE ObjectGroup* ObjectGro
   MOZ_ASSERT_IF(proto.isObject(),
                 cx->isInsideCurrentCompartment(proto.toObject()));
 
   // A null lookup clasp is used for 'new' groups with an associated
   // function. The group starts out as a plain object but might mutate into an
   // unboxed plain object.
   MOZ_ASSERT_IF(!clasp, !!associated);
 
-  if (associated && !associated->is<TypeDescr>()) {
-    MOZ_ASSERT(!clasp);
+  if (associated) {
+    MOZ_ASSERT_IF(!associated->is<TypeDescr>(), !clasp);
     if (associated->is<JSFunction>()) {
       // Canonicalize new functions to use the original one associated with its
       // script.
       associated = associated->as<JSFunction>().maybeCanonicalFunction();
 
       // If we have previously cleared the 'new' script information for this
       // function, don't try to construct another one. Also, for simplicity,
       // don't bother optimizing cross-realm constructors.
       if (associated && (associated->as<JSFunction>().wasNewScriptCleared() ||
                          associated->as<JSFunction>().realm() != cx->realm())) {
         associated = nullptr;
       }
-
+    } else if (associated->is<TypeDescr>()) {
+      if (!clasp) {
+        // This can happen when we call Reflect.construct with a TypeDescr as
+        // newTarget argument. We're creating a plain object in this case, so
+        // don't set the TypeDescr on the group.
+        associated = nullptr;
+      }
     } else {
       associated = nullptr;
     }
 
     if (!associated) {
       clasp = &PlainObject::class_;
     }
   }