1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar global = this;
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar globalProto = Object.getPrototypeOf(global);
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Number of objects being tested. There is an assert ensuring this is correct.
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar objectCount = 21;
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction runTest(f) {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function restore(object, oldProto) {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete object[Symbol.unscopables];
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete object.x;
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete object.x_;
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete object.y;
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete object.z;
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object.setPrototypeOf(object, oldProto);
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function getObject(i) {
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var objects = [
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      {},
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      [],
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function() {},
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function() {
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return arguments;
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }(),
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function() {
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        'use strict';
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return arguments;
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }(),
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Object(1),
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Object(true),
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Object('bla'),
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new Date,
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new RegExp,
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new Set,
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new Map,
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new WeakMap,
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new WeakSet,
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new ArrayBuffer(10),
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new Int32Array(5),
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Object,
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Function,
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Date,
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RegExp,
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      global
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ];
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(objectCount, objects.length);
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return objects[i];
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Tests depends on this not being there to start with.
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete Array.prototype[Symbol.unscopables];
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (f.length === 1) {
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < objectCount; i++) {
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var object = getObject(i);
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var oldObjectProto = Object.getPrototypeOf(object);
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      f(object);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      restore(object, oldObjectProto);
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < objectCount; i++) {
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (var j = 0; j < objectCount; j++) {
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var object = getObject(i);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var proto = getObject(j);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (object === proto) {
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          continue;
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var oldObjectProto = Object.getPrototypeOf(object);
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var oldProtoProto = Object.getPrototypeOf(proto);
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        f(object, proto);
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        restore(object, oldObjectProto);
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        restore(proto, oldProtoProto);
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test array first, since other tests are changing
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Array.prototype[Symbol.unscopables].
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestArrayPrototypeUnscopables() {
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var descr = Object.getOwnPropertyDescriptor(Array.prototype,
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              Symbol.unscopables);
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertFalse(descr.enumerable);
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertFalse(descr.writable);
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertTrue(descr.configurable);
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(null, Object.getPrototypeOf(descr.value));
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var copyWithin = 'local copyWithin';
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var entries = 'local entries';
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var fill = 'local fill';
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var find = 'local find';
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var findIndex = 'local findIndex';
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var keys = 'local keys';
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var values = 'local values';
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var array = [];
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array.toString = 42;
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (array) {
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local copyWithin', copyWithin);
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local entries', entries);
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local fill', fill);
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local find', find);
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local findIndex', findIndex);
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local keys', keys);
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local values', values);
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(42, toString);
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestArrayPrototypeUnscopables();
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestBasics(object) {
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var y = 2;
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var z = 3;
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 4;
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.y = 5;
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4, x);
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(5, y);
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, z);
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {x: true};
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(5, y);
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, z);
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {x: 0, y: true};
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, y);
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, z);
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestBasics);
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestUnscopableChain(object) {
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, x);
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __proto__: {x: true}
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestUnscopableChain);
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestBasicsSet(object) {
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, x);
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {x: true};
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x = 3;
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, x);
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(3, x);
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(2, object.x);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestBasicsSet);
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestOnProto(object, proto) {
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var y = 2;
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var z = 3;
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  proto.x = 4;
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.setPrototypeOf(object, proto);
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.y = 5;
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4, x);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(5, y);
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, z);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  proto[Symbol.unscopables] = {x: true};
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(5, y);
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, z);
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {y: true};
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4, x);
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, y);
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, z);
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  proto[Symbol.unscopables] = {y: true};
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {x: true};
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(5, y);
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, z);
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestOnProto);
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestSetBlockedOnProto(object, proto) {
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, x);
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.setPrototypeOf(object, proto);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  proto[Symbol.unscopables] = {x: true};
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x = 3;
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, x);
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(3, x);
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(2, object.x);
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestSetBlockedOnProto);
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestNonObject(object) {
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var y = 2;
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 3;
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.y = 4;
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = 'xy';
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, x);
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4, y);
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = null;
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, x);
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4, y);
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestNonObject);
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestChangeDuringWith(object) {
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var y = 2;
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 3;
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.y = 4;
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, x);
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4, y);
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object[Symbol.unscopables] = {x: true};
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4, y);
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestChangeDuringWith);
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestChangeDuringWithWithPossibleOptimization(object) {
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < 1000; i++) {
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i === 500) object[Symbol.unscopables] = {x: true};
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(i < 500 ? 2: 1, x);
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestChangeDuringWithWithPossibleOptimization({});
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestChangeDuringWithWithPossibleOptimization2(object) {
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {x: true};
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < 1000; i++) {
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i === 500) delete object[Symbol.unscopables];
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(i < 500 ? 1 : 2, x);
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestChangeDuringWithWithPossibleOptimization2({});
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestChangeDuringWithWithPossibleOptimization3(object) {
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {};
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < 1000; i++) {
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i === 500) object[Symbol.unscopables].x = true;
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(i < 500 ? 2 : 1, x);
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestChangeDuringWithWithPossibleOptimization3({});
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestChangeDuringWithWithPossibleOptimization4(object) {
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {x: true};
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < 1000; i++) {
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i === 500) delete object[Symbol.unscopables].x;
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(i < 500 ? 1 : 2, x);
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestChangeDuringWithWithPossibleOptimization4({});
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestAccessorReceiver(object, proto) {
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 'local';
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.defineProperty(proto, 'x', {
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get: function() {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(object, this);
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return this.x_;
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    },
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    configurable: true
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  proto.x_ = 'proto';
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.setPrototypeOf(object, proto);
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  proto.x_ = 'object';
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('object', x);
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestAccessorReceiver);
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestUnscopablesGetter(object) {
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This test gets really messy when object is the global since the assert
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // functions are properties on the global object and the call count gets
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // completely different.
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (object === global) return;
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 'local';
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 'object';
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var callCount = 0;
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.defineProperty(object, Symbol.unscopables, {
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get: function() {
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      callCount++;
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return {};
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    },
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    configurable: true
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('object', x);
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Once for HasBinding
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(1, callCount);
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  callCount = 0;
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.defineProperty(object, Symbol.unscopables, {
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get: function() {
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      callCount++;
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return {x: true};
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    },
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    configurable: true
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local', x);
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Once for HasBinding
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(1, callCount);
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  callCount = 0;
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.defineProperty(object, Symbol.unscopables, {
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get: function() {
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      callCount++;
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return callCount == 1 ? {} : {x: true};
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    },
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    configurable: true
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x = 1;
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Once for HasBinding
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(1, callCount);
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(1, object.x);
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals('local', x);
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x = 2;
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // One more HasBinding.
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(2, callCount);
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(1, object.x);
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(2, x);
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestUnscopablesGetter);
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar global = this;
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestUnscopablesGetter2() {
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 'local';
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var globalProto = Object.getPrototypeOf(global);
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var protos = [{}, [], function() {}, global];
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var objects = [{}, [], function() {}];
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  protos.forEach(function(proto) {
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    objects.forEach(function(object) {
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Object.defineProperty(proto, 'x', {
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        get: function() {
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          assertEquals(object, this);
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return 'proto';
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        },
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        configurable: true
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      });
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object.__proto__ = proto;
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Object.defineProperty(object, 'x', {
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        get: function() {
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          assertEquals(object, this);
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return 'object';
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        },
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        configurable: true
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      });
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      with (object) {
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assertEquals('object', x);
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object[Symbol.unscopables] = {x: true};
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      with (object) {
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assertEquals('local', x);
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      delete proto[Symbol.unscopables];
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      delete object[Symbol.unscopables];
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    });
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete global.x;
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.setPrototypeOf(global, globalProto);
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestUnscopablesGetter2();
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestSetterOnBlacklisted(object, proto) {
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 'local';
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.defineProperty(proto, 'x', {
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set: function(x) {
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertUnreachable();
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    },
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get: function() {
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return 'proto';
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    },
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    configurable: true
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.setPrototypeOf(object, proto);
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.defineProperty(object, 'x', {
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get: function() {
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return this.x_;
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    },
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set: function(x) {
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this.x_ = x;
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    },
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    configurable: true
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x_ = 1;
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x = 2;
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, x);
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(2, object.x);
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object[Symbol.unscopables] = {x: true};
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x = 3;
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, x);
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(2, object.x);
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestSetterOnBlacklisted);
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestObjectsAsUnscopables(object, unscopables) {
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, x);
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object[Symbol.unscopables] = unscopables;
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, x);
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestObjectsAsUnscopables);
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestAccessorOnUnscopables(object) {
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var x = 1;
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object.x = 2;
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var unscopables = {
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get x() {
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertUnreachable();
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, x);
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object[Symbol.unscopables] = unscopables;
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, x);
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochrunTest(TestAccessorOnUnscopables);
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestLengthUnscopables(object, proto) {
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var length = 2;
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, length);
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object[Symbol.unscopables] = {length: true};
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2, length);
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete object[Symbol.unscopables];
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, length);
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestLengthUnscopables([1], Array.prototype);
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestLengthUnscopables(function(x) {}, Function.prototype);
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestLengthUnscopables(new String('x'), String.prototype);
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestFunctionNameUnscopables(object) {
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var name = 'local';
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (object) {
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('f', name);
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object[Symbol.unscopables] = {name: true};
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local', name);
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete object[Symbol.unscopables];
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('f', name);
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestFunctionNameUnscopables(function f() {});
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestFunctionPrototypeUnscopables() {
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var prototype = 'local';
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var f = function() {};
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var g = function() {};
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.setPrototypeOf(f, g);
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var fp = f.prototype;
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var gp = g.prototype;
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  with (f) {
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(fp, prototype);
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    f[Symbol.unscopables] = {prototype: true};
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals('local', prototype);
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete f[Symbol.unscopables];
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(fp, prototype);
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestFunctionPrototypeUnscopables(function() {});
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestFunctionArgumentsUnscopables() {
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var func = function() {
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var arguments = 'local';
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var args = func.arguments;
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    with (func) {
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(args, arguments);
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      func[Symbol.unscopables] = {arguments: true};
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals('local', arguments);
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      delete func[Symbol.unscopables];
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(args, arguments);
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(1);
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestFunctionArgumentsUnscopables();
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestArgumentsLengthUnscopables() {
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var func = function() {
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var length = 'local';
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    with (arguments) {
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(1, length);
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arguments[Symbol.unscopables] = {length: true};
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals('local', length);
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(1);
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestArgumentsLengthUnscopables();
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestFunctionCallerUnscopables() {
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var func = function() {
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var caller = 'local';
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    with (func) {
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(TestFunctionCallerUnscopables, caller);
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      func[Symbol.unscopables] = {caller: true};
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals('local', caller);
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      delete func[Symbol.unscopables];
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(TestFunctionCallerUnscopables, caller);
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(1);
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestFunctionCallerUnscopables();
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction TestGetUnscopablesGetterThrows() {
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var object = {
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get x() {
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertUnreachable();
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function CustomError() {}
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.defineProperty(object, Symbol.unscopables, {
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    get: function() {
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      throw new CustomError();
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertThrows(function() {
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    with (object) {
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      x;
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }, CustomError);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTestGetUnscopablesGetterThrows();
662