15a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 25a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Redistribution and use in source and binary forms, with or without 35a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// modification, are permitted provided that the following conditions are 45a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// met: 55a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 65a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// * Redistributions of source code must retain the above copyright 75a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// notice, this list of conditions and the following disclaimer. 85a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// * Redistributions in binary form must reproduce the above 95a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// copyright notice, this list of conditions and the following 105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// disclaimer in the documentation and/or other materials provided 115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// with the distribution. 125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// * Neither the name of Google Inc. nor the names of its 135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// contributors may be used to endorse or promote products derived 145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// from this software without specific prior written permission. 155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Flags: --expose-debug-as debug 295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Get the Debug object exposed from the debug context global object. 305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgDebug = debug.Debug 325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgfunction FindCallFrame(exec_state, frame_code) { 345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org var number = Number(frame_code); 355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (number >= 0) { 365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return exec_state.frame(number); 375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org for (var i = 0; i < exec_state.frameCount(); i++) { 395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org var frame = exec_state.frame(i); 405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org var func_mirror = frame.func(); 415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (frame_code == func_mirror.name()) { 425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return frame; 435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org throw new Error("Failed to find function name " + function_name); 475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org} 485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgfunction TestCase(test_scenario, expected_output) { 505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Global variable, accessed from eval'd script. 515a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org test_output = ""; 525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function TestCode() { 545a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function A() { 555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Extra stack variable. To make function not slim. 565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Restarter doesn't work on slim function when stopped on 'debugger' 575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // statement. (There is no padding for 'debugger' statement). 585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org var o = {}; 595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org test_output += 'A'; 605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org test_output += '='; 615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org debugger; 625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return 'Capybara'; 635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function B(p1, p2) { 655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org test_output += 'B'; 665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return A(); 675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function C() { 695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org test_output += 'C'; 705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Function call with argument adaptor is intentional. 715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return B(); 725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function D() { 745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org test_output += 'D'; 755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Function call with argument adaptor is intentional. 765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return C(1, 2); 775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function E() { 795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org test_output += 'E'; 805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return D(); 815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function F() { 835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org test_output += 'F'; 845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return E(); 855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return F(); 875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org var scenario_pos = 0; 905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function DebuggerStatementHandler(exec_state) { 925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org while (true) { 935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org assertTrue(scenario_pos < test_scenario.length); 945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org var change_code = test_scenario[scenario_pos++]; 955a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (change_code == '=') { 965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Continue. 975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return; 985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org var frame = FindCallFrame(exec_state, change_code); 1005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Throws if fails. 1015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Debug.LiveEdit.RestartFrame(frame); 1025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 1035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 1045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org var saved_exception = null; 1065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org function listener(event, exec_state, event_data, data) { 1085a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (saved_exception != null) { 1095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return; 1105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 1115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (event == Debug.DebugEvent.Break) { 1125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org try { 1135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org DebuggerStatementHandler(exec_state); 1145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } catch (e) { 1155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org saved_exception = e; 1165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 1175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 1185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org print("Other: " + event); 1195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 1205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 1215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Debug.setListener(listener); 1235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org assertEquals("Capybara", TestCode()); 1245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Debug.setListener(null); 1255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (saved_exception) { 1275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org print("Exception: " + saved_exception); 1285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org print("Stack: " + saved_exception.stack); 1295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org assertUnreachable(); 1305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 1315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org print(test_output); 1335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org assertEquals(expected_output, test_output); 1355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org} 1365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('0==', "FEDCBA=A="); 1385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('1==', "FEDCBA=BA="); 1395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('2==', "FEDCBA=CBA="); 1405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('3==', "FEDCBA=DCBA="); 1415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('4==', "FEDCBA=EDCBA="); 1425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('5==', "FEDCBA=FEDCBA="); 1435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('=', "FEDCBA="); 1455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('C==', "FEDCBA=CBA="); 1475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgTestCase('B=C=A=D==', "FEDCBA=BA=CBA=A=DCBA="); 1495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 1505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Successive restarts don't work now and require additional fix. 1515a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//TestCase('BCDE==', "FEDCBA=EDCBA="); 1525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//TestCase('BC=BCDE==', "FEDCBA=CBA=EDCBA="); 1535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//TestCase('EF==', "FEDCBA=FEDCBA="); 154