1e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Copyright 2008 the V8 project authors. All rights reserved.
2e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Redistribution and use in source and binary forms, with or without
3e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// modification, are permitted provided that the following conditions are
4e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// met:
5e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//
6e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//     * Redistributions of source code must retain the above copyright
7e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//       notice, this list of conditions and the following disclaimer.
8e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//     * Redistributions in binary form must reproduce the above
9e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//       copyright notice, this list of conditions and the following
10e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//       disclaimer in the documentation and/or other materials provided
11e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//       with the distribution.
12e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//     * Neither the name of Google Inc. nor the names of its
13e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//       contributors may be used to endorse or promote products derived
14e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//       from this software without specific prior written permission.
15e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke//
16e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
28e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// When calling user-defined functions on strings, booleans or
29e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// numbers, we should create a wrapper object.
30e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
31d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// When running the tests use loops to ensure that the call site moves through
32d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// the different IC states and that both the runtime system and the generated
33d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// IC code is tested.
34e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction RunTests() {
35e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  for (var i = 0; i < 10; i++) {
36e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', 'xxx'.TypeOfThis());
37e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', true.TypeOfThis(2,3));
38e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', false.TypeOfThis());
39e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', (42).TypeOfThis());
40e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', (3.14).TypeOfThis());
41e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
42589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
43e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  for (var i = 0; i < 10; i++) {
44e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', 'xxx'['TypeOfThis']());
45e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', true['TypeOfThis']());
46e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', false['TypeOfThis']());
47e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', (42)['TypeOfThis']());
48e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', (3.14)['TypeOfThis']());
49e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
50589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
51e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  function CallTypeOfThis(obj) {
52e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', obj.TypeOfThis());
53e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
54589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
55e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  for (var i = 0; i < 10; i++) {
56e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    CallTypeOfThis('xxx');
57e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    CallTypeOfThis(true);
58e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    CallTypeOfThis(false);
59e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    CallTypeOfThis(42);
60e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    CallTypeOfThis(3.14);
61e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
62589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
63e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  function TestWithWith(obj) {
64e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    with (obj) {
65e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      for (var i = 0; i < 10; i++) {
66e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        assertEquals('object', TypeOfThis());
67e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      }
68e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    }
69e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
70589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
71e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  TestWithWith('xxx');
72e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  TestWithWith(true);
73e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  TestWithWith(false);
74e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  TestWithWith(42);
75e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  TestWithWith(3.14);
76589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
77e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  for (var i = 0; i < 10; i++) {
78e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', true[7]());
79e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', false[7]());
80e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', (42)[7]());
81e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    assertEquals('object', (3.14)[7]());
82e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
83d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
84d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (var i = 0; i < 10; i++) {
85d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('object', typeof 'xxx'.ObjectValueOf());
86d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('object', typeof true.ObjectValueOf());
87d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('object', typeof false.ObjectValueOf());
88d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('object', typeof (42).ObjectValueOf());
89d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('object', typeof (3.14).ObjectValueOf());
90d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
91d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
92d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (var i = 0; i < 10; i++) {
93d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('[object String]', 'xxx'.ObjectToString());
94d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('[object Boolean]', true.ObjectToString());
95d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('[object Boolean]', false.ObjectToString());
96d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('[object Number]', (42).ObjectToString());
97d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assertEquals('[object Number]', (3.14).ObjectToString());
98d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
99e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
100e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
101e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction TypeOfThis() { return typeof this; }
102e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
103589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Test with normal setup of prototype.
104e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeString.prototype.TypeOfThis = TypeOfThis;
105e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype.TypeOfThis = TypeOfThis;
106e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype.TypeOfThis = TypeOfThis;
107e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype[7] = TypeOfThis;
108e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype[7] = TypeOfThis;
109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeString.prototype.ObjectValueOf = Object.prototype.valueOf;
111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeBoolean.prototype.ObjectValueOf = Object.prototype.valueOf;
112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeNumber.prototype.ObjectValueOf = Object.prototype.valueOf;
113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeString.prototype.ObjectToString = Object.prototype.toString;
115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeBoolean.prototype.ObjectToString = Object.prototype.toString;
116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeNumber.prototype.ObjectToString = Object.prototype.toString;
117e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeRunTests();
119e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
120e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Run test after properties have been set to a different value.
121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeString.prototype.TypeOfThis = 'x';
122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype.TypeOfThis = 'x';
123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype.TypeOfThis = 'x';
124e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype[7] = 'x';
125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype[7] = 'x';
126e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
127e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeString.prototype.TypeOfThis = TypeOfThis;
128e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype.TypeOfThis = TypeOfThis;
129e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype.TypeOfThis = TypeOfThis;
130e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype[7] = TypeOfThis;
131e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype[7] = TypeOfThis;
132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
133e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeRunTests();
134e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Force the prototype into slow case and run the test again.
136e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkedelete String.prototype.TypeOfThis;
137e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkedelete Boolean.prototype.TypeOfThis;
138e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkedelete Number.prototype.TypeOfThis;
139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype[7];
140e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype[7];
141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
142e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeString.prototype.TypeOfThis = TypeOfThis;
143e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype.TypeOfThis = TypeOfThis;
144e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype.TypeOfThis = TypeOfThis;
145e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBoolean.prototype[7] = TypeOfThis;
146e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeNumber.prototype[7] = TypeOfThis;
147e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
148e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeRunTests();
149e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
150e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// According to ES3 15.3.4.3 the this value passed to Function.prototyle.apply
151e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// should wrapped. According to ES5 it should not.
152e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.apply('xxx', []));
153e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.apply(true, []));
154e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.apply(false, []));
155e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.apply(42, []));
156e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.apply(3.14, []));
157e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
158e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// According to ES3 15.3.4.3 the this value passed to Function.prototyle.call
159e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// should wrapped. According to ES5 it should not.
160e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.call('xxx'));
161e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.call(true));
162e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.call(false));
163e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.call(42));
164e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeassertEquals('object', TypeOfThis.call(3.14));
165