mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 718543 - Preserve SpecialPowers wrapper identity with a WeakMap cache. r=mrbkap
This commit is contained in:
parent
3e6a76d272
commit
80cafe8e18
@ -156,6 +156,9 @@ function doApply(fun, invocant, args) {
|
||||
return Function.prototype.apply.call(fun, invocant, args);
|
||||
}
|
||||
|
||||
// Use a weak map to cache wrappers. This allows the wrappers to preserve identity.
|
||||
var wrapperCache = WeakMap();
|
||||
|
||||
function wrapPrivileged(obj) {
|
||||
|
||||
// Primitives pass straight through.
|
||||
@ -166,10 +169,15 @@ function wrapPrivileged(obj) {
|
||||
if (isWrapper(obj))
|
||||
throw "Trying to double-wrap object!";
|
||||
|
||||
// Try the cache.
|
||||
if (wrapperCache.has(obj))
|
||||
return wrapperCache.get(obj);
|
||||
|
||||
// Make our core wrapper object.
|
||||
var handler = new SpecialPowersHandler(obj);
|
||||
|
||||
// If the object is callable, make a function proxy.
|
||||
var wrapper;
|
||||
if (typeof obj === "function") {
|
||||
var callTrap = function() {
|
||||
// The invocant and arguments may or may not be wrappers. Unwrap them if necessary.
|
||||
@ -193,11 +201,16 @@ function wrapPrivileged(obj) {
|
||||
return wrapPrivileged(new FakeConstructor());
|
||||
};
|
||||
|
||||
return Proxy.createFunction(handler, callTrap, constructTrap);
|
||||
wrapper = Proxy.createFunction(handler, callTrap, constructTrap);
|
||||
}
|
||||
// Otherwise, just make a regular object proxy.
|
||||
else {
|
||||
wrapper = Proxy.create(handler);
|
||||
}
|
||||
|
||||
// Otherwise, just make a regular object proxy.
|
||||
return Proxy.create(handler);
|
||||
// Cache the wrapper and return it.
|
||||
wrapperCache.set(obj, wrapper);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
function unwrapPrivileged(x) {
|
||||
@ -408,9 +421,6 @@ SpecialPowersAPI.prototype = {
|
||||
*
|
||||
* Known Issues:
|
||||
*
|
||||
* - The wrapping function does not preserve identity, so
|
||||
* SpecialPowers.wrap(foo) !== SpecialPowers.wrap(foo). See bug 718543.
|
||||
*
|
||||
* - The wrapper cannot see expando properties on unprivileged DOM objects.
|
||||
* That is to say, the wrapper uses Xray delegation.
|
||||
*
|
||||
|
@ -134,6 +134,13 @@ function starttest(){
|
||||
noxray.b = 122;
|
||||
is(noxray_wrapper.b, 122, "Should be able to shadow.");
|
||||
|
||||
// Check that the wrapper preserves identity.
|
||||
var someIdentityObject = {a: 2};
|
||||
ok(SpecialPowers.wrap(someIdentityObject) === SpecialPowers.wrap(someIdentityObject),
|
||||
"SpecialPowers wrapping should preserve identity!");
|
||||
ok(webnav === SpecialPowers.wrap(SpecialPowers.unwrap(webnav)),
|
||||
"SpecialPowers wrapping should preserve identity!");
|
||||
|
||||
info("\nProfile::SpecialPowersRunTime: " + (new Date() - startTime) + "\n");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user