13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
23fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Redistribution and use in source and binary forms, with or without
33fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// modification, are permitted provided that the following conditions are
43fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// met:
53fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//
63fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//     * Redistributions of source code must retain the above copyright
73fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       notice, this list of conditions and the following disclaimer.
83fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//     * Redistributions in binary form must reproduce the above
93fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       copyright notice, this list of conditions and the following
103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       disclaimer in the documentation and/or other materials provided
113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       with the distribution.
123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//     * Neither the name of Google Inc. nor the names of its
133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       contributors may be used to endorse or promote products derived
143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       from this software without specific prior written permission.
153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//
163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Flags: --expose-debug-as debug --expose-gc --allow-natives-syntax --inline-construct
293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Get the Debug object exposed from the debug context global object.
303fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochDebug = debug.Debug
313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvar listenerComplete = false;
333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvar exception = false;
343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvar testingConstructCall = false;
363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar input = [
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  {a: 1, b: 2},
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  {a: 3, b: 4},
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  {a: 5, b: 6},
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  {a: 7, b: 8},
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  {a: 9, b: 10}
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch];
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar expected = [
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  { locals: {a0: 1.01, b0: 2.02}, args: { names: ["i", "x0", "y0"], values: [0, 3.03, 4.04] } },
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  { locals: {a1: 3.03, b1: 4.04}, args: { names: ["i", "x1", "y1"], values: [1, 5.05, 6.06] } },
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  { locals: {a2: 5.05, b2: 6.06}, args: { names: ["i"], values: [2] } },
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  { locals: {a3: 7.07, b3: 8.08}, args: { names: ["i", "x3", "y3", "z3"],
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          values: [3, 9.09, 10.10, undefined] }
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  },
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  { locals: {a4: 9.09, b4: 10.10}, args: { names: ["i", "x4", "y4"], values: [4, 11.11, 12.12] } }
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch];
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction arraySum(arr) {
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return arr.reduce(function (a, b) { return a + b; }, 0);
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction listener(event, exec_state, event_data, data) {
603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  try {
613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (event == Debug.DebugEvent.Break)
623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    {
633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      assertEquals(6, exec_state.frameCount());
643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      for (var i = 0; i < exec_state.frameCount(); i++) {
663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        var frame = exec_state.frame(i);
673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        if (i < exec_state.frameCount() - 1) {
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          var expected_args = expected[i].args;
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          var expected_locals = expected[i].locals;
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // All frames except the bottom one have expected locals.
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          var locals = {};
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          for (var j = 0; j < frame.localCount(); j++) {
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            locals[frame.localName(j)] = frame.localValue(j).value();
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          }
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          assertPropertiesEqual(expected_locals, locals);
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // All frames except the bottom one have expected arguments.
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          for (var j = 0; j < expected_args.names.length; j++) {
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            assertEquals(expected_args.names[j], frame.argumentName(j));
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            assertEquals(expected_args.values[j], frame.argumentValue(j).value());
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          }
833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          // All frames except the bottom one have two scopes.
853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          assertEquals(2, frame.scopeCount());
863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          Object.keys(expected_locals).forEach(function (name) {
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            assertEquals(expected_locals[name], frame.scope(0).scopeObject().value()[name]);
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          });
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          for (var j = 0; j < expected_args.names.length; j++) {
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            var arg_name = expected_args.names[j];
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            var arg_value = expected_args.values[j];
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            assertEquals(arg_value, frame.scope(0).scopeObject().value()[arg_name]);
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          }
983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          // Evaluate in the inlined frame.
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          Object.keys(expected_locals).forEach(function (name) {
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            assertEquals(expected_locals[name], frame.evaluate(name).value());
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          });
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          for (var j = 0; j < expected_args.names.length; j++) {
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            var arg_name = expected_args.names[j];
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            var arg_value = expected_args.values[j];
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            assertEquals(arg_value, frame.evaluate(arg_name).value());
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            assertEquals(arg_value, frame.evaluate('arguments['+j+']').value());
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          }
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          var expected_args_sum = arraySum(expected_args.values);
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          var expected_locals_sum =
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              arraySum(Object.keys(expected_locals).
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       map(function (k) { return expected_locals[k]; }));
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          assertEquals(expected_locals_sum + expected_args_sum,
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       frame.evaluate(Object.keys(expected_locals).join('+') + ' + ' +
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      expected_args.names.join('+')).value());
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          var arguments_sum = expected_args.names.map(function(_, idx) {
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            return "arguments[" + idx + "]";
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          }).join('+');
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          assertEquals(expected_args_sum,
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       frame.evaluate(arguments_sum).value());
1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        } else {
1263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          // The bottom frame only have the global scope.
1273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          assertEquals(1, frame.scopeCount());
1283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          assertEquals(debug.ScopeType.Global, frame.scope(0).scopeType());
1293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        }
1303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        // Check the frame function.
1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        switch (i) {
1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          case 0: assertEquals(h, frame.func().value()); break;
1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          case 1: assertEquals(g3, frame.func().value()); break;
1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          case 2: assertEquals(g2, frame.func().value()); break;
1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          case 3: assertEquals(g1, frame.func().value()); break;
1373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          case 4: assertEquals(f, frame.func().value()); break;
1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          case 5: break;
1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          default: assertUnreachable();
1403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        }
1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        // Check for construct call.
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (i == 4) {
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          assertEquals(testingConstructCall, frame.isConstructCall());
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        } else if (i == 2) {
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          assertTrue(frame.isConstructCall());
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        } else {
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          assertFalse(frame.isConstructCall());
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        // When function f is optimized (1 means YES, see runtime.cc) we
1523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        // expect an optimized frame for f with g1, g2 and g3 inlined.
1533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        if (%GetOptimizationStatus(f) == 1) {
1543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          if (i == 1 || i == 2 || i == 3) {
1553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            assertTrue(frame.isOptimizedFrame());
1563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            assertTrue(frame.isInlinedFrame());
1573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            assertEquals(4 - i, frame.inlinedFrameIndex());
1583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          } else if (i == 4) {
1593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            assertTrue(frame.isOptimizedFrame());
1603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            assertFalse(frame.isInlinedFrame());
1613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          } else {
1623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            assertFalse(frame.isOptimizedFrame());
1633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            assertFalse(frame.isInlinedFrame());
1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          }
1653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        }
1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      }
1673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // Indicate that all was processed.
1693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      listenerComplete = true;
1703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
1713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } catch (e) {
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    exception = e.toString() + e.stack;
1733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  };
1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfor (var i = 0; i < 4; i++) f(input.length - 1, 11.11, 12.12);
1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch%OptimizeFunctionOnNextCall(f);
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochf(input.length - 1, 11.11, 12.12);
1793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Add the debug event listener.
1813fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochDebug.setListener(listener);
1823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction h(i, x0, y0) {
1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var a0 = input[i].a;
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var b0 = input[i].b;
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  a0 = a0 + a0 / 100;
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  b0 = b0 + b0 / 100;
1883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  debugger;  // Breakpoint.
1893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction g3(i, x1, y1) {
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var a1 = input[i].a;
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var b1 = input[i].b;
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  a1 = a1 + a1 / 100;
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  b1 = b1 + b1 / 100;
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  h(i - 1, a1, b1);
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return a1+b1;
1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction g2(i) {
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var a2 = input[i].a;
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var b2 = input[i].b;
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  a2 = a2 + a2 / 100;
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  b2 = b2 + b2 / 100;
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  g3(i - 1, a2, b2);
2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction g1(i, x3, y3, z3) {
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var a3 = input[i].a;
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var b3 = input[i].b;
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  a3 = a3 + a3 / 100;
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  b3 = b3 + b3 / 100;
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  new g2(i - 1, a3, b3);
2143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction f(i, x4, y4) {
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var a4 = input[i].a;
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var b4 = input[i].b;
2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  a4 = a4 + a4 / 100;
2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  b4 = b4 + b4 / 100;
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  g1(i - 1, a4, b4);
2223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
2233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Test calling f normally and as a constructor.
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochf(input.length - 1, 11.11, 12.12);
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochf(input.length - 1, 11.11, 12.12, "");
2273fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochtestingConstructCall = true;
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnew f(input.length - 1, 11.11, 12.12);
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnew f(input.length - 1, 11.11, 12.12, "");
2303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Make sure that the debug event listener was invoked.
2323fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochassertFalse(exception, "exception in listener " + exception)
2333fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochassertTrue(listenerComplete);
2343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//Throw away type information for next run.
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochgc();
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2383fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochDebug.setListener(null);
239