| // Copyright 2016 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Test debug event catch prediction for thrown exceptions. We distinguish | |
| // between "caught" and "uncaught" based on the following assumptions: | |
| // 1) try-catch : Will always catch the exception. | |
| // 2) try-finally : Will always re-throw the exception. | |
| Debug = debug.Debug; | |
| var log = []; | |
| function listener(event, exec_state, event_data, data) { | |
| try { | |
| if (event == Debug.DebugEvent.Exception) { | |
| log.push([event_data.exception(), event_data.uncaught()]); | |
| } | |
| } catch (e) { | |
| %AbortJS(e + "\n" + e.stack); | |
| } | |
| } | |
| Debug.setBreakOnException(); | |
| Debug.setListener(listener); | |
| (function TryCatch() { | |
| log = []; // Clear log. | |
| function f(a) { | |
| try { | |
| throw "boom" + a; | |
| } catch(e) { | |
| return e; | |
| } | |
| } | |
| assertEquals("boom1", f(1)); | |
| assertEquals("boom2", f(2)); | |
| %OptimizeFunctionOnNextCall(f); | |
| assertEquals("boom3", f(3)); | |
| print("Collect log:", log); | |
| assertEquals([["boom1",false], ["boom2",false], ["boom3",false]], log); | |
| })(); | |
| (function TryFinally() { | |
| log = []; // Clear log. | |
| function f(a) { | |
| try { | |
| throw "baem" + a; | |
| } finally { | |
| return a + 10; | |
| } | |
| } | |
| assertEquals(11, f(1)); | |
| assertEquals(12, f(2)); | |
| %OptimizeFunctionOnNextCall(f); | |
| assertEquals(13, f(3)); | |
| print("Collect log:", log); | |
| assertEquals([["baem1",true], ["baem2",true], ["baem3",true]], log); | |
| })(); | |
| (function TryCatchFinally() { | |
| log = []; // Clear log. | |
| function f(a) { | |
| try { | |
| throw "wosh" + a; | |
| } catch(e) { | |
| return e + a; | |
| } finally { | |
| // Nothing. | |
| } | |
| } | |
| assertEquals("wosh11", f(1)); | |
| assertEquals("wosh22", f(2)); | |
| %OptimizeFunctionOnNextCall(f); | |
| assertEquals("wosh33", f(3)); | |
| print("Collect log:", log); | |
| assertEquals([["wosh1",false], ["wosh2",false], ["wosh3",false]], log); | |
| })(); | |
| (function TryCatchNestedFinally() { | |
| log = []; // Clear log. | |
| function f(a) { | |
| try { | |
| try { | |
| throw "bang" + a; | |
| } finally { | |
| // Nothing. | |
| } | |
| } catch(e) { | |
| return e + a; | |
| } | |
| } | |
| assertEquals("bang11", f(1)); | |
| assertEquals("bang22", f(2)); | |
| %OptimizeFunctionOnNextCall(f); | |
| assertEquals("bang33", f(3)); | |
| print("Collect log:", log); | |
| assertEquals([["bang1",false], ["bang2",false], ["bang3",false]], log); | |
| })(); | |
| (function TryFinallyNestedCatch() { | |
| log = []; // Clear log. | |
| function f(a) { | |
| try { | |
| try { | |
| throw "peng" + a; | |
| } catch(e) { | |
| return e | |
| } | |
| } finally { | |
| return a + 10; | |
| } | |
| } | |
| assertEquals(11, f(1)); | |
| assertEquals(12, f(2)); | |
| %OptimizeFunctionOnNextCall(f); | |
| assertEquals(13, f(3)); | |
| print("Collect log:", log); | |
| assertEquals([["peng1",false], ["peng2",false], ["peng3",false]], log); | |
| })(); | |
| (function TryFinallyNestedFinally() { | |
| log = []; // Clear log. | |
| function f(a) { | |
| try { | |
| try { | |
| throw "oops" + a; | |
| } finally { | |
| // Nothing. | |
| } | |
| } finally { | |
| return a + 10; | |
| } | |
| } | |
| assertEquals(11, f(1)); | |
| assertEquals(12, f(2)); | |
| %OptimizeFunctionOnNextCall(f); | |
| assertEquals(13, f(3)); | |
| print("Collect log:", log); | |
| assertEquals([["oops1",true], ["oops2",true], ["oops3",true]], log); | |
| })(); |