1967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Redistribution and use in source and binary forms, with or without 3967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// modification, are permitted provided that the following conditions are 4967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// met: 5967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// 6967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// * Redistributions of source code must retain the above copyright 7967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// notice, this list of conditions and the following disclaimer. 8967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// * Redistributions in binary form must reproduce the above 9967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// copyright notice, this list of conditions and the following 10967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// disclaimer in the documentation and/or other materials provided 11967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// with the distribution. 12967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// * Neither the name of Google Inc. nor the names of its 13967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// contributors may be used to endorse or promote products derived 14967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// from this software without specific prior written permission. 15967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// 16967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 28212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Flags: --allow-natives-syntax --inline-construct 29967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 30967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Test inlining of constructor calls. 31967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 32de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction TestInlinedConstructor(constructor, closure) { 33967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org var result; 34967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org var counter = { value:0 }; 35de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org var noDeopt = { deopt:0 }; 36de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org var forceDeopt = { /*empty*/ }; 37de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 38de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org result = closure(constructor, 11, noDeopt, counter); 39de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org assertEquals(11, result); 40967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org assertEquals(1, counter.value); 41de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 42de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org result = closure(constructor, 23, noDeopt, counter); 43de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org assertEquals(23, result); 44967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org assertEquals(2, counter.value); 45de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 46967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org %OptimizeFunctionOnNextCall(closure); 47de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org result = closure(constructor, 42, noDeopt, counter); 48de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org assertEquals(42, result); 49967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org assertEquals(3, counter.value); 50de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 51de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org result = closure(constructor, 127, forceDeopt, counter); 52de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org assertEquals(127, result) 53967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org assertEquals(4, counter.value); 54de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 55de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org %DeoptimizeFunction(closure); 56de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org %ClearFunctionTypeFeedback(closure); 57de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org %ClearFunctionTypeFeedback(constructor); 58967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 59967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 60de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction value_context(constructor, val, deopt, counter) { 61de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org var obj = new constructor(val, deopt, counter); 62de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org return obj.x; 63de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org} 64de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 65de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction test_context(constructor, val, deopt, counter) { 66de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org if (!new constructor(val, deopt, counter)) { 67de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org assertUnreachable("should not happen"); 689a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org } 69de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org return val; 70de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org} 71de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 72de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction effect_context(constructor, val, deopt, counter) { 73de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org new constructor(val, deopt, counter); 74de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org return val; 75de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org} 76de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 77de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction TestInAllContexts(constructor) { 78de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org TestInlinedConstructor(constructor, value_context); 79de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org TestInlinedConstructor(constructor, test_context); 80de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org TestInlinedConstructor(constructor, effect_context); 819a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org} 829a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 83967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 84967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Test constructor returning nothing in all contexts. 85de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction c1(val, deopt, counter) { 86de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org deopt.deopt; 87de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org this.x = val; 88967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org counter.value++; 89967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 909a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.orgTestInAllContexts(c1); 91967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 92967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 93967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Test constructor returning an object in all contexts. 94de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction c2(val, deopt, counter) { 95de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org var obj = {}; 96de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org deopt.deopt; 97de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org obj.x = val; 98967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org counter.value++; 99967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return obj; 100967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 1019a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.orgTestInAllContexts(c2); 102967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 103967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 104967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Test constructor returning a primitive value in all contexts. 105de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction c3(val, deopt, counter) { 106de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org deopt.deopt; 107de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org this.x = val; 108967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org counter.value++; 109967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return "not an object"; 110967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 1119a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.orgTestInAllContexts(c3); 112967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 113967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 114967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Test constructor called with too many arguments. 115967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgfunction c_too_many(a, b) { 116967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org this.x = a + b; 117967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 118967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgfunction f_too_many(a, b, c) { 119967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org var obj = new c_too_many(a, b, c); 120967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return obj.x; 121967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 122967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgassertEquals(23, f_too_many(11, 12, 1)); 123967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgassertEquals(42, f_too_many(23, 19, 1)); 124967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org%OptimizeFunctionOnNextCall(f_too_many); 125967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgassertEquals(43, f_too_many(1, 42, 1)); 126967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgassertEquals("foobar", f_too_many("foo", "bar", "baz")) 127967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 128967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 129967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Test constructor called with too few arguments. 130967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgfunction c_too_few(a, b) { 131967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org assertSame(undefined, b); 132967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org this.x = a + 1; 133967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 134967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgfunction f_too_few(a) { 135967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org var obj = new c_too_few(a); 136967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return obj.x; 137967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 138967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgassertEquals(12, f_too_few(11)); 139967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgassertEquals(24, f_too_few(23)); 140967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org%OptimizeFunctionOnNextCall(f_too_few); 141967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgassertEquals(2, f_too_few(1)); 142967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgassertEquals("foo1", f_too_few("foo")) 143967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 144967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 145967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Test constructor that cannot be inlined. 146de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction c_unsupported_syntax(val, deopt, counter) { 147967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org try { 148de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org deopt.deopt; 149de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org this.x = val; 150967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org counter.value++; 151967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } catch(e) { 152967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org throw new Error(); 153967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } 154967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 1559a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.orgTestInAllContexts(c_unsupported_syntax); 1569a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 1579a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 1589a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org// Regression test: Inlined constructors called as functions do not get their 1599a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org// implicit receiver object set to undefined, even in strict mode. 160de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.orgfunction c_strict(val, deopt, counter) { 1619a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org "use strict"; 162de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org deopt.deopt; 163de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org this.x = val; 1649a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org counter.value++; 165967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 1669a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.orgTestInAllContexts(c_strict); 167