Bug 689101 - make the jsval_layout field in JS::Value public in MSC compilers for binary compatibility across C and C++ (r=luke, a=asa)
authorSteve Fink <sfink@mozilla.com>
Tue, 11 Oct 2011 15:46:29 -0700
changeset 79121 021bf68f4d51d6dcc0adf968b0bd231871083d9b
parent 79120 88fb0cd0df5920fa0a24fb42107ea59da8b4f09b
child 79122 b9725bcebd715b1d8add6d7589a93040bde8ab63
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke, asa
bugs689101
milestone9.0a2
Bug 689101 - make the jsval_layout field in JS::Value public in MSC compilers for binary compatibility across C and C++ (r=luke, a=asa)
js/src/jsapi-tests/Makefile.in
js/src/jsapi-tests/testValueABI.cpp
js/src/jsapi-tests/valueABI.c
js/src/jsapi.h
--- a/js/src/jsapi-tests/Makefile.in
+++ b/js/src/jsapi-tests/Makefile.in
@@ -82,20 +82,24 @@ CPPSRCS = \
   testScriptInfo.cpp \
   testScriptObject.cpp \
   testSetProperty.cpp \
   testStringBuffer.cpp \
   testThreadGC.cpp \
   testThreads.cpp \
   testTrap.cpp \
   testUTF8.cpp \
+  testValueABI.cpp \
   testVersion.cpp \
   testXDR.cpp \
   $(NULL)
 
+CSRCS = \
+  valueABI.c
+
 # Disabled: an entirely unrelated test seems to cause this to fail.  Moreover,
 # given the test's dependence on interactions between the compiler, the GC, and
 # conservative stack scanning, the fix isn't obvious: more investigation
 # needed.
 #CPPSRCS += \
 #  testRegExpInstanceProperties.cpp \
 #  $(NULL)
 
new file mode 100644
--- /dev/null
+++ b/js/src/jsapi-tests/testValueABI.cpp
@@ -0,0 +1,35 @@
+#include "tests.h"
+
+/*
+ * Bug 689101 - jsval is technically a non-POD type because it has a private
+ * data member. On gcc, this doesn't seem to matter. On MSVC, this prevents
+ * returning a jsval from a function between C and C++ because it will use a
+ * retparam in C++ and a direct return value in C.
+ */
+
+extern "C" {
+
+extern JSBool
+C_ValueToObject(JSContext *cx, jsval v, JSObject **obj);
+
+extern jsval
+C_GetEmptyStringValue(JSContext *cx);
+
+}
+
+BEGIN_TEST(testValueABI)
+{
+    JSObject* obj = JS_GetGlobalObject(cx);
+    jsval v = OBJECT_TO_JSVAL(obj);
+    obj = NULL;
+    CHECK(C_ValueToObject(cx, v, &obj));
+    JSBool equal;
+    CHECK(JS_StrictlyEqual(cx, v, OBJECT_TO_JSVAL(obj), &equal));
+    CHECK(equal);
+
+    v = C_GetEmptyStringValue(cx);
+    CHECK(JSVAL_IS_STRING(v));
+
+    return true;
+}
+END_TEST(testValueABI)
new file mode 100644
--- /dev/null
+++ b/js/src/jsapi-tests/valueABI.c
@@ -0,0 +1,12 @@
+#include "jsapi.h"
+
+JSBool C_ValueToObject(JSContext *cx, jsval v, JSObject **obj)
+{
+    return JS_ValueToObject(cx, v, obj);
+}
+
+jsval
+C_GetEmptyStringValue(JSContext *cx)
+{
+    return JS_GetEmptyStringValue(cx);
+}
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -657,27 +657,35 @@ class Value
     const size_t *payloadWord() const {
 #if JS_BITS_PER_WORD == 32
         return &data.s.payload.word;
 #elif JS_BITS_PER_WORD == 64
         return &data.asWord;
 #endif
     }
 
+#ifndef _MSC_VER
+  /* To make jsval binary compatible when linking across C and C++ with MSVC,
+   * JS::Value needs to be POD. Otherwise, jsval will be passed in memory
+   * in C++ but by value in C (bug 645111).
+   */
+  private:
+#endif
+
+    jsval_layout data;
+
   private:
     void staticAssertions() {
         JS_STATIC_ASSERT(sizeof(JSValueType) == 1);
         JS_STATIC_ASSERT(sizeof(JSValueTag) == 4);
         JS_STATIC_ASSERT(sizeof(JSBool) == 4);
         JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4);
         JS_STATIC_ASSERT(sizeof(Value) == 8);
     }
 
-    jsval_layout data;
-
     friend jsval_layout (::JSVAL_TO_IMPL)(Value);
     friend Value (::IMPL_TO_JSVAL)(jsval_layout l);
 } JSVAL_ALIGNMENT;
 
 /************************************************************************/
 
 static JS_ALWAYS_INLINE Value
 NullValue()