13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
23ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Redistribution and use in source and binary forms, with or without
33ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// modification, are permitted provided that the following conditions are
43ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// met:
53ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions of source code must retain the above copyright
73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       notice, this list of conditions and the following disclaimer.
83ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions in binary form must reproduce the above
93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       copyright notice, this list of conditions and the following
103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       disclaimer in the documentation and/or other materials provided
113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       with the distribution.
123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Neither the name of Google Inc. nor the names of its
133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       contributors may be used to endorse or promote products derived
143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       from this software without specific prior written permission.
153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Flags: --allow-natives-syntax --expose-gc --inline-construct
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test inlining of constructor calls.
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction TestInlinedConstructor(closure) {
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var result;
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var counter = { value:0 };
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  result = closure(11, 12, counter);
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(23, result);
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(1, counter.value);
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  result = closure(23, 19, counter);
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(42, result);
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(2, counter.value);
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %OptimizeFunctionOnNextCall(closure);
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  result = closure(1, 42, counter)
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(43, result);
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(3, counter.value);
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  result = closure("foo", "bar", counter)
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals("foobar", result)
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(4, counter.value);
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction TestInAllContexts(constructor) {
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  function value_context(a, b, counter) {
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var obj = new constructor(a, b, counter);
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return obj.x;
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  function test_context(a, b, counter) {
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!new constructor(a, b, counter)) {
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      assertUnreachable("should not happen");
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return a + b;
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  function effect_context(a, b, counter) {
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    new constructor(a, b, counter);
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return a + b;
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  TestInlinedConstructor(value_context);
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  TestInlinedConstructor(test_context);
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  TestInlinedConstructor(effect_context);
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %DeoptimizeFunction(value_context);
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %DeoptimizeFunction(test_context);
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %DeoptimizeFunction(effect_context);
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  gc();  // Makes V8 forget about type information for *_context.
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test constructor returning nothing in all contexts.
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction c1(a, b, counter) {
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.x = a + b;
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  counter.value++;
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestInAllContexts(c1);
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test constructor returning an object in all contexts.
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction c2(a, b, counter) {
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var obj = new Object();
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  obj.x = a + b;
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  counter.value++;
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return obj;
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestInAllContexts(c2);
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test constructor returning a primitive value in all contexts.
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction c3(a, b, counter) {
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.x = a + b;
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  counter.value++;
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return "not an object";
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestInAllContexts(c3);
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test constructor called with too many arguments.
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction c_too_many(a, b) {
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.x = a + b;
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction f_too_many(a, b, c) {
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var obj = new c_too_many(a, b, c);
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return obj.x;
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(23, f_too_many(11, 12, 1));
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(42, f_too_many(23, 19, 1));
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch%OptimizeFunctionOnNextCall(f_too_many);
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(43, f_too_many(1, 42, 1));
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals("foobar", f_too_many("foo", "bar", "baz"))
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test constructor called with too few arguments.
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction c_too_few(a, b) {
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertSame(undefined, b);
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.x = a + 1;
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction f_too_few(a) {
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var obj = new c_too_few(a);
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return obj.x;
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(12, f_too_few(11));
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(24, f_too_few(23));
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch%OptimizeFunctionOnNextCall(f_too_few);
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(2, f_too_few(1));
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals("foo1", f_too_few("foo"))
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test constructor that cannot be inlined.
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction c_unsupported_syntax(a, b, counter) {
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  try {
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this.x = a + b;
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    counter.value++;
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } catch(e) {
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw new Error();
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestInAllContexts(c_unsupported_syntax);
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Regression test: Inlined constructors called as functions do not get their
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// implicit receiver object set to undefined, even in strict mode.
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction c_strict(a, b, counter) {
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  "use strict";
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.x = a + b;
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  counter.value++;
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestInAllContexts(c_strict);
153