var g1 = newGlobal({sameCompartmentAs: this}); var g2 = newGlobal({sameCompartmentAs: g1}); g2.x = g1; gc(); assertEq(objectGlobal(Math), this); assertEq(objectGlobal(g1.print), g1); assertEq(objectGlobal(g2.x), g1); assertEq(isSameCompartment(g1, g2), true); assertEq(isSameCompartment(g1, Math), true); // Different-compartment realms have wrappers. assertEq(objectGlobal(newGlobal({newCompartment: true}).Math), null); function testCrossRealmProto() { var g = newGlobal({sameCompartmentAs:this}); for (var i = 0; i < 20; i++) { var o = Object.create(g.Math); assertEq(objectGlobal(o), this); assertEq(o.__proto__, g.Math); var a = Reflect.construct(Array, [], g.Object); assertEq(Array.isArray(a), true); assertEq(objectGlobal(a), this); assertEq(a.__proto__, g.Object.prototype); } } testCrossRealmProto(); function testSystemNonSystemRealms() { var systemRealm = newGlobal({newCompartment: true, systemPrincipal: true}); var ex; try { var nonSystemRealm = newGlobal({sameCompartmentAs: systemRealm, principal: 10}); } catch(e) { ex = e; } assertEq(ex.toString().includes("non-system realms"), true); ex = null; try { systemRealm = newGlobal({systemPrincipal: true, sameCompartmentAs: this}); } catch(e) { ex = e; } assertEq(ex.toString().includes("non-system realms"), true); } testSystemNonSystemRealms(); function testNewObjectCache() { // NewObjectCache lookup based on the proto should not return a cross-realm // object. var g = newGlobal({sameCompartmentAs: this}); var o1 = g.evaluate("Object.create(Math)"); var o2 = Object.create(g.Math); assertEq(objectGlobal(o1), g); assertEq(objectGlobal(o2), this); } testNewObjectCache(); function testCCWs() { // CCWs are allocated in the first realm. var g1 = newGlobal({newCompartment: true}); var g2 = newGlobal({sameCompartmentAs: g1}); g1.o1 = {x: 1}; g2.o2 = {x: 2}; g1 = null; gc(); g2.o3 = {x: 3}; assertEq(g2.o2.x, 2); assertEq(g2.o3.x, 3); } testCCWs(); function testTypedArrayLazyBuffer(global) { var arr1 = new global.Int32Array(1); var arr2 = new Int32Array(arr1); assertEq(objectGlobal(arr2.buffer), this); global.buf = arr1.buffer; global.eval("assertEq(objectGlobal(buf), this);"); } testTypedArrayLazyBuffer(newGlobal()); testTypedArrayLazyBuffer(newGlobal({sameCompartmentAs: this})); function testEvalcx() { var g = newGlobal(); evalcx("this.x = 7", g); assertEq(g.x, 7); g = newGlobal({newCompartment: true, invisibleToDebugger: true}); var ex, sb; try { sb = g.eval("evalcx('')"); } catch(e) { ex = e; } // Check for either an exception or CCW (with --more-compartments). assertEq((sb && objectGlobal(sb) === null) || ex.toString().includes("visibility"), true); // Bug 1524707. var lazysb = evalcx("lazy"); Object.setPrototypeOf(lazysb, Math); assertEq(lazysb.__proto__, Math); } testEvalcx(); function testSetProto() { var o = {}; o.__proto__ = newGlobal(); o.__proto__ = newGlobal(); assertEq(objectGlobal(o), this); } testSetProto();