Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added preliminary support for revocable proxies

  • Loading branch information...
commit 48f455e3a1042863c9cf675fac799b3281143b71 1 parent 85b55ed
Tom Van Cutsem authored September 24, 2012
17  doc/api.md
Source Rendered
@@ -212,4 +212,19 @@ The following `Handler` traps are regarded as "fundamental", and by default forw
212 212
 
213 213
 All other traps are "derived", and default to one or more of the above "fundamental" traps: get, set, has, hasOwn, keys, enumerate, iterate, seal, freeze, isSealed, isFrozen, construct.
214 214
 
215  
-[More details](http://wiki.ecmascript.org/doku.php?id=harmony:virtual_object_api)
  215
+[More details](http://wiki.ecmascript.org/doku.php?id=harmony:virtual_object_api)
  216
+
  217
+## Proxy.revocable(target, handler)
  218
+
  219
+Returns an object with properties `proxy` and `revoke`. `proxy` is a freshly constructed proxy, as if by calling `Proxy(target, handler)`. `revoke()` is a function that when called, renders the associated proxy unusable: any trappable operation performed on `proxy` after it has been revoked results in a TypeError.
  220
+
  221
+When a proxy is revoked, it no longer refers to its `target` and `handler` so that these may become subject to garbage-collection.
  222
+
  223
+Example:
  224
+
  225
+    var tuple = Proxy.revocable(target, handler);
  226
+    var proxy = tuple.proxy;
  227
+    var revoke = tuple.revoke;
  228
+    proxy.foo // traps
  229
+    revoke()  // returns undefined
  230
+    proxy.foo // throws TypeError: "proxy is revoked"
2  doc/handler_api.md
Source Rendered
@@ -121,7 +121,7 @@ The proxy throws a TypeError if:
121 121
 
122 122
   *  This trap returns `undefined`, but the `name` property of `target` is non-configurable. If a target property is non-configurable, a proxy cannot hide it.
123 123
   *  This trap returns a property descriptor that is not compatible with the corresponding property in `target` (e.g. `target[name]` is non-configurable and this trap returns a configurable descriptor).
124  
-  *  This trap returns a non-configurable property that doesn't exist on `target`. A non-configurable property can only be exposed if the `target` object has a corresponding property.
  124
+  *  This trap returns a non-configurable property that is configurable or doesn't exist on `target`. A non-configurable property can only be exposed if the `target` object has a corresponding non-configurable property.
125 125
   
126 126
 Examples:
127 127
 
18  reflect.js
@@ -1030,6 +1030,8 @@ Validator.prototype = {
1030 1030
    *  - create and return a fresh Array,
1031 1031
    *  - of which each element is coerced to String,
1032 1032
    *  - which does not contain duplicates
  1033
+   *
  1034
+   * TODO(tvcutsem) trap return value should change from [string] to iterator.
1033 1035
    */
1034 1036
   enumerate: function() {
1035 1037
     var trap = this.getTrap("enumerate");
@@ -1966,6 +1968,22 @@ if (typeof Proxy !== "undefined") {
1966 1968
       directProxies.set(proxy, vHandler);
1967 1969
       return proxy;
1968 1970
     };
  1971
+    
  1972
+    Reflect.Proxy.revocable = function(target, handler) {
  1973
+      var proxy = Reflect.Proxy(target, handler);
  1974
+      var revoke = function() {
  1975
+        var vHandler = directProxies.get(proxy);
  1976
+        if (vHandler !== null) {
  1977
+          // vHandler.target = null;         // null-out [[Target]]
  1978
+          Object.defineProperty(vHandler, 'target', {
  1979
+            get: function() { throw new TypeError("proxy is revoked"); }
  1980
+          });
  1981
+        }
  1982
+        directProxies.set(proxy, null);   // null-out [[Handler]]
  1983
+        return undefined;
  1984
+      };
  1985
+      return {proxy: proxy, revoke: revoke};
  1986
+    }
1969 1987
 
1970 1988
   } else {
1971 1989
     // Proxy is already a function, so presumably direct proxies
11  test/testProxies.js
@@ -95,6 +95,7 @@ load('../reflect.js');
95 95
       testFunctions();
96 96
       testSet();
97 97
       testTransparentWrappers();
  98
+      testRevocableProxies();
98 99
 
99 100
       for (var testName in TESTS) {
100 101
         emulatedProps = {};
@@ -731,6 +732,16 @@ load('../reflect.js');
731 732
              'Array.prototype.toString on app');
732 733
     }());
733 734
   }
  735
+  
  736
+  function testRevocableProxies() {
  737
+    var target = {};
  738
+    var handler = { get: function() { return 1; }};
  739
+    var tuple = Proxy.revocable(target, handler);
  740
+    var p = tuple.proxy;
  741
+    assert(p.x === 1, 'unrevoked proxy get works');
  742
+    tuple.revoke();
  743
+    assertThrows('proxy is revoked', function() { p.x });
  744
+  }
734 745
     
735 746
   if (typeof window === "undefined") {
736 747
     test();

0 notes on commit 48f455e

Please sign in to comment.
Something went wrong with that request. Please try again.