Bug 614138 followup to fix Windows debug compile errors for good.
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 09 Dec 2010 00:01:52 -0500
changeset 59006 ae03fdb249ad90fa54dda9626eae89c995fb0f6c
parent 59005 bac4a8d704921fc4bcb6b4eeaf97e80fc4ee5ee6
child 59007 4d97e9955bfbfff03d1548db0e1ef7c5f55ad4fe
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
bugs614138
milestone2.0b8pre
Bug 614138 followup to fix Windows debug compile errors for good.
js/src/jsapi.h
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1376,28 +1376,19 @@ class Anchor: AnchorPermitted<T> {
          * ("Objection, your honor!  *Alleged* killer whale!")
          *
          * The disadvantage of this approach is that it does generate code for the store.
          * We do need to use Anchors in some cases where cycles are tight.
          */
         volatile T sink;
 #ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES
         /*
-         * The default assignment operator for |struct C| has the signature:
-         *
-         *   C& C::operator=(const C&)
-         *
-         * And in particular requires implicit conversion of |this| to
-         * type |C| for the return value.  But |volatile C| cannot
-         * thus be converted to |C|, so just doing |sink = hold| here
-         * would fail to compile.  Do the assignment on asBits
-         * instead, since I don't think we want to give jsval_layout
-         * an assignment operator returning |volatile jsval_layout|.
+         * Can't just do a simple assignment here.
          */
-        sink.asBits = hold.asBits;
+        doAssignment(sink, hold);
 #else
         sink = hold;
 #endif
 #endif
     }
     T &get()      { return hold; }
     void set(T t) { hold = t; }
     void clear()  { hold = 0; }
@@ -1407,23 +1398,50 @@ class Anchor: AnchorPermitted<T> {
     Anchor(const Anchor &);
     const Anchor &operator=(const Anchor &);
 };
 
 /*
  * Ensure that attempts to create Anchors for types the garbage collector's conservative
  * scanner doesn't actually recgonize fail. Such anchors would have no effect.
  */
-template<> class AnchorPermitted<JSObject *> { };
-template<> class AnchorPermitted<const JSObject *> { };
-template<> class AnchorPermitted<JSFunction *> { };
-template<> class AnchorPermitted<const JSFunction *> { };
-template<> class AnchorPermitted<JSString *> { };
-template<> class AnchorPermitted<const JSString *> { };
-template<> class AnchorPermitted<jsval> { };
+class Anchor_base {
+protected:
+#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES
+    template<typename T> void doAssignment(volatile T &lhs, const T &rhs) {
+        lhs = rhs;
+    }
+#endif
+};
+template<> class AnchorPermitted<JSObject *> : protected Anchor_base { };
+template<> class AnchorPermitted<const JSObject *> : protected Anchor_base { };
+template<> class AnchorPermitted<JSFunction *> : protected Anchor_base { };
+template<> class AnchorPermitted<const JSFunction *> : protected Anchor_base { };
+template<> class AnchorPermitted<JSString *> : protected Anchor_base { };
+template<> class AnchorPermitted<const JSString *> : protected Anchor_base { };
+template<> class AnchorPermitted<jsval> : protected Anchor_base {
+protected:
+#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES
+    void doAssignment(volatile jsval &lhs, const jsval &rhs) {
+        /*
+         * The default assignment operator for |struct C| has the signature:
+         *
+         *   C& C::operator=(const C&)
+         *
+         * And in particular requires implicit conversion of |this| to
+         * type |C| for the return value.  But |volatile C| cannot
+         * thus be converted to |C|, so just doing |sink = hold| here
+         * would fail to compile.  Do the assignment on asBits
+         * instead, since I don't think we want to give jsval_layout
+         * an assignment operator returning |volatile jsval_layout|.
+         */
+        lhs.asBits = rhs.asBits;
+#endif
+    }
+};
 
 }  /* namespace js */
 
 JS_BEGIN_EXTERN_C
 #endif
 
 /*
  * This symbol may be used by embedders to detect the change from the old