1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --strong-mode --allow-natives-syntax
6
7// TODO(conradw): Track implementation of strong bit for other objects, add
8// tests.
9
10function getSloppyObjects() {
11  return [(function(){}), ({})];
12}
13
14function getStrictObjects() {
15  "use strict";
16  return [(function(){}), ({})];
17}
18
19function getWeakObjects() {
20  return getSloppyObjects().concat(getStrictObjects());
21}
22
23function getStrongObjects() {
24  "use strong";
25// Strong functions can't have properties added to them, and will be tested as a
26// special case.
27  return [({})];
28}
29
30function strongFunction() {
31  "use strong";
32}
33
34function deleteFromObjectSloppy(o) {
35  return delete o.foo;
36}
37
38function deleteFromObjectKeyedSloppy(o) {
39  return delete o["foo"];
40}
41
42function deleteFromObjectKeyedVarSloppy(o) {
43  var a = "foo";
44  return delete o[a];
45}
46
47function deleteFromObjectKeyedComputedSloppy(o) {
48  var a = "o";
49  return delete o["fo" + a];
50}
51
52function deleteFromObjectWith(o) {
53  with (o) {
54    return delete foo;
55  }
56}
57
58function deleteFromObjectElementSloppy(o) {
59  return delete o[0];
60}
61
62function deleteFromObjectElementVarSloppy(o) {
63  var a = 0;
64  return delete o[a];
65}
66
67function deleteFromObjectElementSparseSloppy(o) {
68  return delete o[100000];
69}
70
71function deleteFromObjectElementVarSloppy(o) {
72  var a = 0;
73  return delete o[a];
74}
75
76function deleteFromObjectElementSparseVarSloppy(o) {
77  var a = 100000;
78  return delete o[a];
79}
80
81function deleteFromObjectStrict(o) {
82  "use strict";
83  return delete o.foo;
84}
85
86function deleteFromObjectKeyedStrict(o) {
87  "use strict";
88  return delete o["foo"];
89}
90
91function deleteFromObjectKeyedVarStrict(o) {
92  "use strict";
93  var a = "foo";
94  return delete o[a];
95}
96
97function deleteFromObjectKeyedComputedStrict(o) {
98  "use strict";
99  var a = "o";
100  return delete o["fo" + a];
101}
102
103function deleteFromObjectElementStrict(o) {
104  "use strict";
105  return delete o[0];
106}
107
108function deleteFromObjectElementSparseStrict(o) {
109  "use strict";
110  return delete o[100000];
111}
112
113function deleteFromObjectElementVarStrict(o) {
114  "use strict";
115  var a = 0;
116  return delete o[a];
117}
118
119function deleteFromObjectElementSparseVarStrict(o) {
120  "use strict";
121  var a = 100000;
122  return delete o[a];
123}
124
125function testStrongObjectDelete() {
126  "use strict";
127
128  let deletePropertyFuncsSloppy = [
129    deleteFromObjectSloppy,
130    deleteFromObjectKeyedSloppy,
131    deleteFromObjectKeyedVarSloppy,
132    deleteFromObjectKeyedComputedSloppy,
133    deleteFromObjectWith
134  ];
135  let deletePropertyFuncsStrict = [
136    deleteFromObjectStrict,
137    deleteFromObjectKeyedStrict,
138    deleteFromObjectKeyedVarStrict,
139    deleteFromObjectKeyedComputedStrict
140  ];
141  let deleteElementFuncsSloppy = [
142    deleteFromObjectElementSloppy,
143    deleteFromObjectElementVarSloppy
144  ];
145  let deleteElementSparseFuncsSloppy = [
146    deleteFromObjectElementSparseSloppy,
147    deleteFromObjectElementSparseVarSloppy
148  ];
149  let deleteElementFuncsStrict = [
150    deleteFromObjectElementStrict,
151    deleteFromObjectElementVarStrict
152  ];
153  let deleteElementSparseFuncsStrict = [
154    deleteFromObjectElementSparseStrict,
155    deleteFromObjectElementSparseVarStrict
156  ];
157  let deleteFuncs = deletePropertyFuncsSloppy.concat(
158    deletePropertyFuncsStrict, deleteElementFuncsSloppy,
159    deleteElementSparseFuncsSloppy, deleteElementFuncsStrict,
160    deleteElementSparseFuncsStrict);
161
162  for (let deleteFunc of deleteFuncs) {
163    assertTrue(deleteFunc(strongFunction));
164  }
165
166  let testCasesSloppy = [
167    [deletePropertyFuncsSloppy, "foo"],
168    [deleteElementFuncsSloppy, "0"],
169    [deleteElementSparseFuncsSloppy, "100000"]
170  ];
171
172  let testCasesStrict = [
173    [deletePropertyFuncsStrict, "foo"],
174    [deleteElementFuncsStrict, "0"],
175    [deleteElementSparseFuncsStrict, "100000"]
176  ];
177
178  let propDescs = [
179     {configurable: true, value: "bar"},
180     {configurable: true, value: 1},
181     {configurable: true, enumerable: true, writable: true, value: "bar"},
182     {configurable: true, enumerable: true, writable: true, value: 1},
183     {configurable: true, get: (function(){return 0}), set: (function(x){})}
184  ];
185
186  for (let propDesc of propDescs) {
187    for (let testCase of testCasesSloppy) {
188      let name = testCase[1];
189      for (let deleteFunc of testCase[0]) {
190        for (let o of getWeakObjects()) {
191          Object.defineProperty(o, name, propDesc);
192          assertTrue(delete o["bar"]);
193          assertTrue(delete o[5000]);
194          assertTrue(deleteFunc(o));
195          assertFalse(o.hasOwnProperty(name));
196          %OptimizeFunctionOnNextCall(deleteFunc);
197          Object.defineProperty(o, name, propDesc);
198          assertTrue(deleteFunc(o));
199          assertFalse(o.hasOwnProperty(name));
200          %DeoptimizeFunction(deleteFunc);
201          Object.defineProperty(o, name, propDesc);
202          assertTrue(deleteFunc(o));
203          assertFalse(o.hasOwnProperty(name));
204        }
205        for (let o of getStrongObjects()) {
206          Object.defineProperty(o, name, propDesc);
207          assertTrue(delete o["bar"]);
208          assertTrue(delete o[5000]);
209          assertFalse(deleteFunc(o));
210          assertTrue(o.hasOwnProperty(name));
211          %OptimizeFunctionOnNextCall(deleteFunc);
212          assertFalse(deleteFunc(o));
213          assertTrue(o.hasOwnProperty(name));
214          %DeoptimizeFunction(deleteFunc);
215          assertFalse(deleteFunc(o));
216          assertTrue(o.hasOwnProperty(name));
217        }
218      }
219    }
220    for (let testCase of testCasesStrict) {
221      let name = testCase[1];
222      for (let deleteFunc of testCase[0]) {
223        for (let o of getWeakObjects()) {
224          Object.defineProperty(o, name, propDesc);
225          assertTrue(delete o["bar"]);
226          assertTrue(delete o[5000]);
227          assertTrue(deleteFunc(o));
228          assertFalse(o.hasOwnProperty(name));
229          %OptimizeFunctionOnNextCall(deleteFunc);
230          Object.defineProperty(o, name, propDesc);
231          assertTrue(deleteFunc(o));
232          assertFalse(o.hasOwnProperty(name));
233          %DeoptimizeFunction(deleteFunc);
234          Object.defineProperty(o, name, propDesc);
235          assertTrue(deleteFunc(o));
236          assertFalse(o.hasOwnProperty(name));
237        }
238        for (let o of getStrongObjects()) {
239          Object.defineProperty(o, name, propDesc);
240          assertTrue(delete o["bar"]);
241          assertTrue(delete o[5000]);
242          assertThrows(function(){deleteFunc(o)}, TypeError);
243          assertTrue(o.hasOwnProperty(name));
244          %OptimizeFunctionOnNextCall(deleteFunc);
245          assertThrows(function(){deleteFunc(o)}, TypeError);
246          assertTrue(o.hasOwnProperty(name));
247          %DeoptimizeFunction(deleteFunc);
248          assertThrows(function(){deleteFunc(o)}, TypeError);
249          assertTrue(o.hasOwnProperty(name));
250        }
251      }
252    }
253  }
254}
255testStrongObjectDelete();
256