1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2009 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that we match JSC in making some functions undeletable.
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// See http://code.google.com/p/chromium/issues/detail?id=1717
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The functions on these prototypes are not just undeletable.  It is
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// possible to override them with new definitions, then get the old
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// version back by deleting the new definition.
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar array;
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toString", "toLocaleString", "join", "pop", "push", "concat", "reverse",
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "shift", "unshift", "slice", "splice", "sort", "filter", "forEach", "some",
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "every", "map", "indexOf", "lastIndexOf", "reduce", "reduceRight"];
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckJSCSemantics(Array.prototype, array, "Array prototype");
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toString", "toDateString", "toTimeString", "toLocaleString",
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toLocaleDateString", "toLocaleTimeString", "valueOf", "getTime",
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "getFullYear", "getUTCFullYear", "getMonth", "getUTCMonth", "getDate",
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "getUTCDate", "getDay", "getUTCDay", "getHours", "getUTCHours", "getMinutes",
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "getUTCMinutes", "getSeconds", "getUTCSeconds", "getMilliseconds",
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "getUTCMilliseconds", "getTimezoneOffset", "setTime", "setMilliseconds",
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "setUTCMilliseconds", "setSeconds", "setUTCSeconds", "setMinutes",
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "setUTCMinutes", "setHours", "setUTCHours", "setDate", "setUTCDate",
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "setMonth", "setUTCMonth", "setFullYear", "setUTCFullYear", "toGMTString",
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toUTCString", "getYear", "setYear", "toISOString", "toJSON"];
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckJSCSemantics(Date.prototype, array, "Date prototype");
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", "floor", "log",
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "round", "sin", "sqrt", "tan", "atan2", "pow", "max", "min"];
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckJSCSemantics(Math, array, "Math1");
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(Date, ["UTC", "parse", "now"], "Date");
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "E", "LN10", "LN2", "LOG2E", "LOG10E", "PI", "SQRT1_2", "SQRT2"];
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckDontDelete(Math, array, "Math2");
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "escape", "unescape", "decodeURI", "decodeURIComponent", "encodeURI",
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "encodeURIComponent", "isNaN", "isFinite", "parseInt", "parseFloat", "eval",
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "execScript"];
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(this, array, "Global");
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckReadOnlyAttr(this, "Infinity");
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = ["exec", "test", "toString", "compile"];
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(RegExp.prototype, array, "RegExp prototype");
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toString", "toLocaleString", "valueOf", "hasOwnProperty",
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "isPrototypeOf", "propertyIsEnumerable", "__defineGetter__",
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "__lookupGetter__", "__defineSetter__", "__lookupSetter__"];
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(Object.prototype, array, "Object prototype");
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toString", "valueOf", "toJSON"];
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(Boolean.prototype, array, "Boolean prototype");
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toString", "toLocaleString", "valueOf", "toFixed", "toExponential",
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toPrecision", "toJSON"];
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(Number.prototype, array, "Number prototype");
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(Function.prototype, ["toString"], "Function prototype");
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(Date.prototype, ["constructor"], "Date prototype constructor");
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarray = [
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "charAt", "charCodeAt", "concat", "indexOf",
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "lastIndexOf", "localeCompare", "match", "replace", "search", "slice",
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "split", "substring", "substr", "toLowerCase", "toLocaleLowerCase",
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toUpperCase", "toLocaleUpperCase", "link", "anchor", "fontcolor", "fontsize",
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "big", "blink", "bold", "fixed", "italics", "small", "strike", "sub", "sup",
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "toJSON", "toString", "valueOf"];
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckJSCSemantics(String.prototype, array, "String prototype");
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCheckEcmaSemantics(String, ["fromCharCode"], "String");
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CheckEcmaSemantics(type, props, name) {
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  print(name);
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < props.length; i++) {
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CheckDeletable(type, props[i]);
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CheckJSCSemantics(type, props, name) {
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  print(name);
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < props.length; i++) {
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CheckNotDeletable(type, props[i]);
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CheckDontDelete(type, props, name) {
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  print(name);
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < props.length; i++) {
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CheckDontDeleteAttr(type, props[i]);
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CheckDeletable(type, prop) {
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var old = type[prop];
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var hasOwnProperty = Object.prototype.hasOwnProperty;
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!type[prop]) return;
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(type.hasOwnProperty(prop), "inherited: " + prop);
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var deleted = delete type[prop];
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(deleted, "delete operator returned false: " + prop);
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertFalse(hasOwnProperty.call(type, prop), "still there after delete: " + prop);
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  type[prop] = "foo";
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertEquals("foo", type[prop], "not overwritable: " + prop);
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  type[prop] = old;
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CheckNotDeletable(type, prop) {
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var old = type[prop];
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!type[prop]) return;
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(type.hasOwnProperty(prop), "inherited: " + prop);
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var deleted = delete type[prop];
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(deleted, "delete operator returned false: " + prop);
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop);
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  type[prop] = "foo";
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertEquals("foo", type[prop], "not overwritable: " + prop);
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  deleted = delete type[prop];
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(deleted, "delete operator returned false 2nd time: " + prop);
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertEquals(old.toString(), type[prop].toString(), "delete didn't restore the old value: " + prop);
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CheckDontDeleteAttr(type, prop) {
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var old = type[prop];
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!type[prop]) return;
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(type.hasOwnProperty(prop), "inherited: " + prop);
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var deleted = delete type[prop];
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertFalse(deleted, "delete operator returned true: " + prop);
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop);
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  type[prop] = "foo";
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertFalse("foo" == type[prop], "overwritable: " + prop);
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CheckReadOnlyAttr(type, prop) {
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var old = type[prop];
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!type[prop]) return;
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(type.hasOwnProperty(prop), "inherited: " + prop);
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var deleted = delete type[prop];
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertFalse(deleted, "delete operator returned true: " + prop);
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop);
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  type[prop] = "foo";
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertEquals("foo", type[prop], "overwritable: " + prop);
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockprint("OK");
182