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 Blockvar obj = {
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    a: 7,
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    b: { x: 12, y: 24 },
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    c: 'Zebra'
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(7, obj.a);
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(12, obj.b.x);
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(24, obj.b.y);
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals('Zebra', obj.c);
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar z = 24;
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar obj2 = {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    a: 7,
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    b: { x: 12, y: z },
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    c: 'Zebra'
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(7, obj2.a);
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(12, obj2.b.x);
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(24, obj2.b.y);
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals('Zebra', obj2.c);
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar arr = [];
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfor (var i = 0; i < 2; i++) {
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  arr[i] = {
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      a: 7,
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      b: { x: 12, y: 24 },
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      c: 'Zebra'
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockarr[0].b.x = 2;
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(2, arr[0].b.x);
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(12, arr[1].b.x);
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction makeSparseArray() {
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return {
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    '0': { x: 12, y: 24 },
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    '1000000': { x: 0, y: 0 }
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar sa1 = makeSparseArray();
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocksa1[0].x = 0;
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar sa2 = makeSparseArray();
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(12, sa2[0].x);
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that non-constant literals work.
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar n = new Object();
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction makeNonConstantArray() { return [ [ n ] ]; }
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar a = makeNonConstantArray();
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocka[0][0].foo = "bar";
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("bar", n.foo);
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction makeNonConstantObject() { return { a: { b: n } }; }
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocka = makeNonConstantObject();
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocka.a.b.bar = "foo";
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("foo", n.bar);
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that exceptions for regexps still hold.
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction makeRegexpInArray() { return [ [ /a*/, {} ] ]; }
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocka = makeRegexpInArray();
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar b = makeRegexpInArray();
98bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochassertFalse(a[0][0] === b[0][0]);
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertFalse(a[0][1] === b[0][1]);
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction makeRegexpInObject() { return { a: { b: /b*/, c: {} } }; }
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocka = makeRegexpInObject();
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockb = makeRegexpInObject();
104bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochassertFalse(a.a.b === b.a.b);
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertFalse(a.a.c === b.a.c);
106bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
107bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Test keywords are valid as property names in initializers and dot-access.
109bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochvar keywords = [
110bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "break",
111bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "case",
112bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "catch",
113bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "const",
114bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "continue",
115bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "debugger",
116bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "default",
117bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "delete",
118bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "do",
119bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "else",
120bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "false",
121bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "finally",
122bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "for",
123bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "function",
124bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "if",
125bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "in",
126bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "instanceof",
127bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "new",
128bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "null",
129bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "return",
130bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "switch",
131bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "this",
132bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "throw",
133bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "true",
134bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "try",
135bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "typeof",
136bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "var",
137bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "void",
138bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  "while",
1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "with"
140bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch];
141bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
142bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochfunction testKeywordProperty(keyword) {
1433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var exception = false;
144bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  try {
145bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch    // Sanity check that what we get is a keyword.
146bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch    eval("var " + keyword + " = 42;");
1473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } catch (e) {
1483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    exception = true;
1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  assertTrue(exception);
151756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
152bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Simple property, read and write.
153bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  var x = eval("({" + keyword + ": 42})");
154bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(42, x[keyword]);
155bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(42, eval("x." + keyword));
156bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  eval("x." + keyword + " = 37");
157bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(37, x[keyword]);
158bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(37, eval("x." + keyword));
159756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
160bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Getter/setter property, read and write.
161bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  var y = eval("({value : 42, get " + keyword + "(){return this.value}," +
162bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch               " set " + keyword + "(v) { this.value = v; }})");
163bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(42, y[keyword]);
164bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(42, eval("y." + keyword));
165bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  eval("y." + keyword + " = 37");
166bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(37, y[keyword]);
167bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(37, eval("y." + keyword));
168756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
169bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Quoted keyword works is read back by unquoted as well.
170bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  var z = eval("({\"" + keyword + "\": 42})");
171bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(42, z[keyword]);
172bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertEquals(42, eval("z." + keyword));
173756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
174bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Function property, called.
175bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  var was_called;
176bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  function test_call() { this.was_called = true; was_called = true; }
177bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  var w = eval("({" + keyword + ": test_call, was_called: false})");
178bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  eval("w." + keyword + "();");
179bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertTrue(was_called);
180bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertTrue(w.was_called);
181bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
182bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Function property, constructed.
183bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  function construct() { this.constructed = true; }
184bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  var v = eval("({" + keyword + ": construct})");
185bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  var vo = eval("new v." + keyword + "()");
186bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertTrue(vo instanceof construct);
187bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  assertTrue(vo.constructed);
188bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch}
189bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
190bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochfor (var i = 0; i < keywords.length; i++) {
191bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  testKeywordProperty(keywords[i]);
1923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
193