Bug 645416, part 8 - Support passing symbols across compartment boundaries. r=terrence.

Trivial. Since symbols are always allocated in the atoms compartment and all
compartments are allowed to have direct references to them, Compartment::wrap
on a symbol is a no-op.

--HG--
extra : rebase_source : 2f51ff0b3870885de8c6ef6a82efa7398e17d5e8
This commit is contained in:
Jason Orendorff 2014-06-23 10:56:49 -05:00
Родитель b158e0b883
Коммит 157c34e600
9 изменённых файлов: 56 добавлений и 6 удалений

Просмотреть файл

@ -0,0 +1,8 @@
function f() {
return Object(Symbol());
}
for (var i = 0; i < 4; i++) {
f();
gc();
}

Просмотреть файл

@ -22,8 +22,10 @@ g.eval("function f() { debugger; }");
hits = 0;
g.eval("args = []; f();");
g.eval("this.f();");
g.eval("args = ['hello', 3.14, true, false, null, undefined]; f.apply(undefined, args);");
g.eval("f('hello', 3.14, true, false, null, undefined);");
g.eval("var world = Symbol('world'); " +
"args = ['hello', world, 3.14, true, false, null, undefined]; " +
"f('hello', world, 3.14, true, false, null, undefined);");
g.eval("f.apply(undefined, args);");
g.eval("args = [-0, NaN, -1/0]; this.f(-0, NaN, -1/0);");
assertEq(hits, 5);

Просмотреть файл

@ -5,12 +5,12 @@ var global = dbg.addDebuggee(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
var argc = frame.arguments.length;
assertEq(argc, 7);
assertEq(argc, 8);
assertEq(frame.evalWithBindings("arguments[prop]", {prop: "length"}).return, argc);
for (var i = 0; i < argc; i++)
assertEq(frame.evalWithBindings("arguments[i]", {i: i}).return, frame.arguments[i]);
hits++;
};
g.eval("function f() { debugger; }");
g.eval("f(undefined, -0, NaN, '\uffff', Array.prototype, Math, f);");
g.eval("f(undefined, -0, NaN, '\uffff', Symbol('alpha'), Array.prototype, Math, f);");
assertEq(hits, 1);

Просмотреть файл

@ -23,6 +23,7 @@ test(null);
test(false);
test(1);
test("stringy");
test(Symbol("symbolic"));
test({});
test([]);

Просмотреть файл

@ -16,7 +16,9 @@ g.eval("Number.prototype.f = f; v = 3.14; v.f();");
g.eval("f.call(v);");
g.eval("String.prototype.f = f; v = 'hello'; v.f();");
g.eval("f.call(v);");
g.eval("Symbol.prototype.f = f; v = Symbol('world'); v.f();");
g.eval("f.call(v);");
g.eval("v = undefined; f.call(v);");
g.eval("v = null; f.call(v);");
assertEq(hits, 8);
assertEq(hits, 10);

Просмотреть файл

@ -21,7 +21,9 @@ g.eval("Number.prototype.f = f; v = 3.14; v.f();");
g.eval("f.call(v);");
g.eval("String.prototype.f = f; v = 'hello'; v.f();");
g.eval("f.call(v);");
g.eval("Symbol.prototype.f = f; v = Symbol('world'); v.f();");
g.eval("f.call(v);");
g.eval("v = undefined; f.call(v);");
g.eval("v = null; f.call(v);");
assertEq(hits, 8);
assertEq(hits, 10);

Просмотреть файл

@ -38,3 +38,5 @@ assertEq(gw.makeDebuggeeValue(null), null);
assertEq(gw.makeDebuggeeValue(1729), 1729);
assertEq(gw.makeDebuggeeValue(Math.PI), Math.PI);
assertEq(gw.makeDebuggeeValue(undefined), undefined);
var s = g.eval("Symbol('Stavromula Beta')");
assertEq(gw.makeDebuggeeValue(s), s);

Просмотреть файл

@ -56,6 +56,13 @@ JSCompartment::wrap(JSContext *cx, JS::MutableHandleValue vp, JS::HandleObject e
if (!vp.isMarkable())
return true;
/*
* Symbols are GC things, but never need to be wrapped or copied because
* they are always allocated in the atoms compartment.
*/
if (vp.isSymbol())
return true;
/* Handle strings. */
if (vp.isString()) {
JS::RootedString str(cx, vp.toString());

Просмотреть файл

@ -0,0 +1,26 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/ */
// Symbols can be shared across realms.
if (typeof Reflect !== "undefined" && typeof Reflect.Realm === "function") {
throw new Error("Congratulations on implementing Reflect.Realm! " +
"Please update this test to use it.");
}
if (typeof newGlobal === "function") {
var g = newGlobal();
var gj = g.eval("jones = Symbol('jones')");
assertEq(typeof gj, "symbol");
assertEq(g.jones, g.jones);
assertEq(gj, g.jones);
assertEq(gj !== Symbol("jones"), true);
// A symbol can be round-tripped to another realm and back;
// the result is the original symbol.
var smith = Symbol("smith");
g.smith = smith; // put smith into the realm
assertEq(g.smith, smith); // pull it back out
}
if (typeof reportCompare === "function")
reportCompare(0, 0);