зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b158e0b883
Коммит
157c34e600
|
@ -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);
|
Загрузка…
Ссылка в новой задаче