public

membranes with dummy target and getPrototypeOf

  • Download Gist
membrane_dummy_getPrototypeOf.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
load('reflect.js'); // https://github.com/tvcutsem/harmony-reflect/blob/master/reflect.js
 
function makeMembrane(initTarget) {
var cache = new WeakMap();
var revoked = false;
function wrap(target) {
if (Object(target) !== target) return target; // primitives are passed through
var wrapper = cache.get(target);
if (wrapper) return wrapper;
var dummyTarget;
if (typeof target === "function") {
dummyTarget = target;
} else {
dummyTarget = Object.create(wrap(Object.getPrototypeOf(target)));
}
wrapper = Proxy(dummyTarget, Proxy(dummyTarget, { // "double lifting"
get: function(dummyTarget, trapName) {
if (revoked) throw new TypeError("membrane revoked");
return function(dummyTarget /*, ...args*/) { // generic trap
var args = Array.prototype.slice.call(arguments, 1).map(wrap);
return wrap(Reflect[trapName].apply(undefined, [target].concat(args)));
}
}
}));
cache.set(target, wrapper);
return wrapper;
}
function revoke() { revoked = true; }
return {revoke: revoke, target: wrap(initTarget)};
}
 
function C(){};
var membrane = makeMembrane(C);
var wrappedC = membrane.target;
 
// the invariant is preserved across the membrane (both return true)
print(Object.getPrototypeOf(new C()) !== C.prototype.constructor);
print(Object.getPrototypeOf(new wrappedC()) !== wrappedC.prototype.constructor);

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.