All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.lwjgl.system.StackWalkUtil Maven / Gradle / Ivy

The newest version!
/*
 * Copyright LWJGL. All rights reserved.
 * License terms: https://www.lwjgl.org/license
 */
package org.lwjgl.system;

import javax.annotation.*;
import java.util.*;

/**
 * Stack-walking utilities.
 *
 * 

On Java 9 these methods are implemented using {@code java.lang.StackWalker}, which has much lower overhead.

*/ final class StackWalkUtil { private StackWalkUtil() { } static StackTraceElement[] stackWalkArray(Object[] a) { return (StackTraceElement[])a; } static Object stackWalkGetMethod(Class after) { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); for (int i = 3; i < stackTrace.length; i++) { if (!stackTrace[i].getClassName().startsWith(after.getName())) { return stackTrace[i]; } } throw new IllegalStateException(); } private static boolean isSameMethod(StackTraceElement a, StackTraceElement b) { return isSameMethod(a, b, b.getMethodName()); } private static boolean isSameMethod(StackTraceElement a, StackTraceElement b, String methodName) { return a.getMethodName().equals(methodName) && a.getClassName().equals(b.getClassName()) && a.getFileName().equals(b.getFileName()); } private static boolean isAutoCloseable(StackTraceElement element, StackTraceElement pushed) { // Java 9 try-with-resources: synthetic $closeResource if (isSameMethod(element, pushed, "$closeResource")) { return true; } // Kotlin T.use: kotlin.AutoCloseable::closeFinally if ("closeFinally".equals(element.getMethodName()) && "AutoCloseable.kt".equals(element.getFileName())) { return true; } return false; } @Nullable static Object stackWalkCheckPop(Class after, Object pushedObj) { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); for (int i = 3; i < stackTrace.length; i++) { StackTraceElement element = stackTrace[i]; if (element.getClassName().startsWith(after.getName())) { continue; } StackTraceElement pushed = (StackTraceElement)pushedObj; if (isSameMethod(element, pushed)) { return null; } if (isAutoCloseable(element, pushed) && i + 1 < stackTrace.length) { // Some runtimes use a separate method to call AutoCloseable::close in try-with-resources blocks. // That method suppresses any exceptions thrown by close if necessary. // When that happens, the pop is 1 level deeper than expected. element = stackTrace[i + 1]; if (isSameMethod(pushed, stackTrace[i + 1])) { return null; } } return element; } throw new IllegalStateException(); } static Object[] stackWalkGetTrace() { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); int i = 3; for (; i < stackTrace.length; i++) { if (!stackTrace[i].getClassName().startsWith("org.lwjgl.system.Memory")) { break; } } return Arrays.copyOfRange(stackTrace, i, stackTrace.length); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy