Bug 1130988 - Add SharedArrayBuffer to JSXray. r=bz
authorTom Schuster <evilpies@gmail.com>
Sat, 29 Oct 2016 20:11:42 +0200
changeset 320194 40cd4eb145ffd5d0c4d698965ed3870903c70c2f
parent 320193 0b9e245f787d6c5c42a323d5db3e52302e71144a
child 320195 4a6cd6dff941517c15ce49226f74e438f83983e8
push id20751
push userphilringnalda@gmail.com
push dateSun, 30 Oct 2016 18:06:35 +0000
treeherderfx-team@e3279760cd97 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1130988
milestone52.0a1
Bug 1130988 - Add SharedArrayBuffer to JSXray. r=bz
js/xpconnect/tests/chrome/test_xrayToJS.xul
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -252,16 +252,23 @@ https://bugzilla.mozilla.org/show_bug.cg
   gConstructorProperties['Promise'] =
     constructorProps(["resolve", "reject", "all", "race", Symbol.species]);
 
   gPrototypeProperties['ArrayBuffer'] =
     ["constructor", "byteLength", "slice", Symbol.toStringTag];
   gConstructorProperties['ArrayBuffer'] =
     constructorProps(["isView", "slice", Symbol.species]);
 
+  if (!isReleaseOrBeta) {
+    gPrototypeProperties['SharedArrayBuffer'] = ["constructor", "byteLength"];
+    gConstructorProperties['SharedArrayBuffer'] = constructorProps([]);
+  } else {
+    is(typeof SharedArrayBuffer, "undefined", "Enable tests!");
+  }
+
   // Sort an array that may contain symbols as well as strings.
   function sortProperties(arr) {
     function sortKey(prop) {
       return typeof prop + ":" + prop.toString();
     }
     arr.sort((a, b) => sortKey(a) < sortKey(b) ? -1 : +1);
   }
 
@@ -888,41 +895,54 @@ for (var prop of props) {
     is(Cu.getGlobalForObject(pr.wrappedJSObject.catch), iwin, "Underlying global is correct");
 
     isnot(pr.then, Cu.unwaiveXrays(pr.wrappedJSObject.then), "Different function identities");
     is(Cu.getGlobalForObject(pr.then), window, "Xray global is correct");
     is(Cu.getGlobalForObject(pr.wrappedJSObject.then), iwin, "Underlying global is correct");
   }
 
   function testArrayBuffer() {
-    testXray('ArrayBuffer', new iwin.ArrayBuffer(0), new iwin.ArrayBuffer(12));
+    let constructors = ['ArrayBuffer'];
 
-    var t = new iwin.ArrayBuffer(12);
-    is(t.byteLength, 12, "ArrayBuffer byteLength is correct");
-    is(t.slice(4).byteLength, 8, "ArrayBuffer byteLength is correct after slicing");
-    is(Cu.getGlobalForObject(t.slice(4)), iwin, "Slice results lives in the target compartment");
-    is(Object.getPrototypeOf(t.slice(4)), iwin.ArrayBuffer.prototype, "Slice results proto lives in target compartment")
-    is(ArrayBuffer.slice(t, 4).byteLength, 8, "ArrayBuffer.slice (deprecated) works");
+    if (!isReleaseOrBeta) {
+      constructors.push('SharedArrayBuffer');
+      // If this fails enable the test a bit below.
+      is(typeof SharedArrayBuffer.prototype.slice, "undefined", "SharedArrayBuffer doesn't have slice");
+    }
+
+    for (const c of constructors) {
+      testXray(c, new iwin[c](0), new iwin[c](12));
+
+      var t = new iwin[c](12);
+      is(t.byteLength, 12, `${c} byteLength is correct`);
 
-    var i32Array = new Int32Array(t);
-    // i32Array is going to be created in the buffer's target compartment,
-    // but usually this is unobservable, because the proto is set to
-    // the current compartment's prototype.
-    // However Xrays ignore the object's proto and claim its proto is
-    // the default proto for that class in the relevant compartment,
-    // so see through this proto hack.
-    todo_is(Object.getPrototypeOf(i32Array), Int32Array.prototype, "Int32Array has correct proto");
-    is(i32Array.length, 3, "Int32Array created from Xray ArrayBuffer has the correct length");
-    is(i32Array.buffer, t, "Int32Array has the correct buffer that we passed in");
+      if (c === 'ArrayBuffer') {
+        is(t.slice(4).byteLength, 8, `${c} byteLength is correct after slicing`);
+        is(Cu.getGlobalForObject(t.slice(4)), iwin, "Slice results lives in the target compartment");
+        is(Object.getPrototypeOf(t.slice(4)), iwin[c].prototype, "Slice results proto lives in target compartment")
+        is(ArrayBuffer.slice(t, 4).byteLength, 8, `${c}.slice (deprecated) works`);
+      }
 
-    i32Array = new iwin.Int32Array(t);
-    is(Object.getPrototypeOf(i32Array), iwin.Int32Array.prototype, "Xray Int32Array has correct proto");
-    is(i32Array.length, 3, "Xray Int32Array created from Xray ArrayBuffer has the correct length");
-    is(i32Array.buffer, t, "Xray Int32Array has the correct buffer that we passed in");
+      var i32Array = new Int32Array(t);
+      // i32Array is going to be created in the buffer's target compartment,
+      // but usually this is unobservable, because the proto is set to
+      // the current compartment's prototype.
+      // However Xrays ignore the object's proto and claim its proto is
+      // the default proto for that class in the relevant compartment,
+      // so see through this proto hack.
+      todo_is(Object.getPrototypeOf(i32Array), Int32Array.prototype, "Int32Array has correct proto");
+      is(i32Array.length, 3, `Int32Array created from Xray ${c} has the correct length`);
+      is(i32Array.buffer, t, "Int32Array has the correct buffer that we passed in");
 
-    t = (new iwin.Int32Array(2)).buffer;
-    is(t.byteLength, 8, "Can access ArrayBuffer returned by buffer property");
+      i32Array = new iwin.Int32Array(t);
+      is(Object.getPrototypeOf(i32Array), iwin.Int32Array.prototype, "Xray Int32Array has correct proto");
+      is(i32Array.length, 3, `Xray Int32Array created from Xray ${c} has the correct length`);
+      is(i32Array.buffer, t, "Xray Int32Array has the correct buffer that we passed in");
+
+      t = (new iwin.Int32Array(2)).buffer;
+      is(t.byteLength, 8, `Can access ${c} returned by buffer property`);
+    }
   }
 
   ]]>
   </script>
   <iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" />
 </window>
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -83,16 +83,17 @@ IsJSXraySupported(JSProtoKey key)
       case JSProto_Object:
       case JSProto_Array:
       case JSProto_Function:
       case JSProto_TypedArray:
       case JSProto_SavedFrame:
       case JSProto_RegExp:
       case JSProto_Promise:
       case JSProto_ArrayBuffer:
+      case JSProto_SharedArrayBuffer:
         return true;
       default:
         return false;
     }
 }
 
 XrayType
 GetXrayType(JSObject* obj)