| // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| // This code is not run directly. It needs to be compiled to dex code. |
| // 'trycatch.dex' is what is run. |
| |
| package trycatch; |
| |
| class TryCatch { |
| |
| |
| private static class Thrower { |
| |
| private boolean shouldThrow; |
| |
| public Thrower(boolean shouldThrow) { |
| this.shouldThrow = shouldThrow; |
| } |
| |
| public void maybeThrow() { |
| if (shouldThrow) { |
| throw new RuntimeException(); |
| } |
| } |
| } |
| |
| private static void throwOrCatch(Thrower thrower) { |
| String firstJunk = "junk 1"; |
| String result = "Did not throw"; |
| String secondJunk = "junk 2"; |
| try { |
| thrower.maybeThrow(); |
| } catch (Throwable e) { |
| String tmp = secondJunk; |
| secondJunk = firstJunk; |
| result = "Did throw"; |
| firstJunk = tmp; |
| } |
| System.out.println(result); |
| System.out.println(firstJunk); |
| System.out.println(secondJunk); |
| } |
| |
| private static void throwOnPositive(int i) { |
| if (i > 0) { |
| throw new RuntimeException(); |
| } |
| } |
| |
| private static int loopWhileThrow(int i) { |
| while (true) { |
| int result = 100; |
| try { |
| throwOnPositive(i--); |
| return result; |
| } catch (Throwable e) { |
| } |
| } |
| } |
| |
| private static void foo() { |
| try { |
| throw new RuntimeException(); |
| } catch (IllegalStateException e) { |
| System.out.println("Error!"); |
| } |
| } |
| |
| private static String tryCatchPhi(int i) { |
| String result = "one"; |
| String otherResult = "two"; |
| try { |
| throwOnPositive(i++); |
| result = otherResult; |
| throwOnPositive(i); |
| } catch (Throwable e) { |
| return result; |
| } |
| return "three"; |
| } |
| |
| private static void emptyMethod(int x) { |
| } |
| |
| private static int regressRemoveCatchHandlers(int a, int b) { |
| try { |
| if (a == b) { |
| emptyMethod(a); |
| return 0; |
| } else { |
| emptyMethod(a); |
| return a / b; |
| } |
| } catch (IllegalStateException | ArithmeticException e) { |
| System.out.println("Error!"); |
| } |
| return -1; |
| } |
| |
| static final int NUM_OF_EVENTS_PER_FILE = 8192; |
| |
| public static Object regressMultiNewArray() { |
| try { |
| int[][] args = new int[3][NUM_OF_EVENTS_PER_FILE]; |
| return args; |
| } catch (Exception e) { |
| return null; |
| } |
| } |
| |
| // Create a class hierarchy which introduces a bridge method (B::x returning Object) by |
| // overriding a method (A::x) with one with a narrower type. |
| public static class A { |
| |
| public Object x() { |
| return null; |
| } |
| } |
| |
| public static class B extends A { |
| |
| // This bridge method will be generated. |
| // public Object x() { |
| // return result of call "String x()" |
| //} |
| |
| public String x() { |
| return null; |
| } |
| } |
| |
| static B b = new B(); |
| |
| public static Object regressBridgeMethod() { |
| String s; |
| try { |
| s = b.x(); |
| } catch (ClassCastException e) { |
| return null; |
| } |
| return s; |
| } |
| |
| public static void main(String[] args) { |
| loopWhileThrow(-100); |
| throwOrCatch(new Thrower(false)); |
| throwOrCatch(new Thrower(true)); |
| System.out.println(tryCatchPhi(-1)); |
| System.out.println(tryCatchPhi(0)); |
| System.out.println(tryCatchPhi(1)); |
| try { |
| foo(); |
| } catch (RuntimeException e) { |
| System.out.print("Success!"); |
| } |
| regressRemoveCatchHandlers(1, 0); |
| regressMultiNewArray(); |
| regressBridgeMethod(); |
| } |
| } |