summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/strong/load-proxy.js
blob: 98a3238c4e2c56f2f11c7ba96d9b6f60ca081fa1 (plain)
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --harmony-proxies --strong-mode

// Forwarding proxies adapted from proposal definition
function handlerMaker1(obj) {
  return {
    getPropertyDescriptor: function(name) {
      var desc;
      var searchObj = obj;
      while (desc === undefined && searchObj != null) {
        desc = Object.getOwnPropertyDescriptor(searchObj, name);
        searchObj = searchObj.__proto__;
      }
      // a trapping proxy's properties must always be configurable
      if (desc !== undefined) { desc.configurable = true; }
      return desc;
    },
    fix: function() {
      if (Object.isFrozen(obj)) {
        var result = {};
        Object.getOwnPropertyNames(obj).forEach(function(name) {
          result[name] = Object.getOwnPropertyDescriptor(obj, name);
        });
        return result;
      }
      // As long as obj is not frozen, the proxy won't allow itself to be fixed
      return undefined; // will cause a TypeError to be thrown
    }
  };
}
function handlerMaker2(obj) {
  return {
    get: function(receiver, name) {
      return obj[name];
    },
    fix: function() {
      if (Object.isFrozen(obj)) {
        var result = {};
        Object.getOwnPropertyNames(obj).forEach(function(name) {
          result[name] = Object.getOwnPropertyDescriptor(obj, name);
        });
        return result;
      }
      // As long as obj is not frozen, the proxy won't allow itself to be fixed
      return undefined; // will cause a TypeError to be thrown
    }
  };
}
var baseObj = {};
var proxy1 = Proxy.create(handlerMaker1(baseObj));
var proxy2 = Proxy.create(handlerMaker2(baseObj));
var childObj1 = { __proto__: proxy1 };
var childObj2 = { __proto__: proxy2 };
var childObjAccessor1 = { set foo(_){}, set "1"(_){}, __proto__: proxy1 };
var childObjAccessor2 = { set foo(_){}, set "1"(_){}, __proto__: proxy2 };

(function() {
  "use strong";
  // TODO(conradw): These asserts are sanity checking V8's proxy implementation.
  // Strong mode semantics for ES6 proxies still need to be explored.
  assertDoesNotThrow(function(){proxy1.foo});
  assertDoesNotThrow(function(){proxy1[1]});
  assertDoesNotThrow(function(){proxy2.foo});
  assertDoesNotThrow(function(){proxy2[1]});
  assertDoesNotThrow(function(){childObj1.foo});
  assertDoesNotThrow(function(){childObj1[1]});
  assertDoesNotThrow(function(){childObj2.foo});
  assertDoesNotThrow(function(){childObj2[1]});
  assertThrows(function(){baseObj.foo}, TypeError);
  assertThrows(function(){baseObj[1]}, TypeError);
  assertThrows(function(){childObjAccessor1.foo}, TypeError);
  assertThrows(function(){childObjAccessor1[1]}, TypeError);
  assertThrows(function(){childObjAccessor2.foo}, TypeError);
  assertThrows(function(){childObjAccessor2[1]}, TypeError);

  // Once the proxy is no longer trapping, property access should have strong
  // semantics.
  Object.freeze(baseObj);

  Object.freeze(proxy1);
  assertThrows(function(){proxy1.foo}, TypeError);
  assertThrows(function(){proxy1[1]}, TypeError);
  assertThrows(function(){childObj1.foo}, TypeError);
  assertThrows(function(){childObj1[1]}, TypeError);
  assertThrows(function(){childObjAccessor1.foo}, TypeError);
  assertThrows(function(){childObjAccessor1[1]}, TypeError);

  Object.freeze(proxy2);
  assertThrows(function(){proxy2.foo}, TypeError);
  assertThrows(function(){proxy2[1]}, TypeError);
  assertThrows(function(){childObj2.foo}, TypeError);
  assertThrows(function(){childObj2[1]}, TypeError);
  assertThrows(function(){childObjAccessor2.foo}, TypeError);
  assertThrows(function(){childObjAccessor2[1]}, TypeError);
})();