private void handleTraceExit()

in log4j-weaver/src/main/java/org/apache/logging/log4j/weaver/log4j2/LoggerConversionHandler.java [294:344]


    private void handleTraceExit(LocationMethodVisitor mv, String descriptor) {
        final Type[] types = Type.getArgumentTypes(descriptor);
        final int[] vars = new int[types.length];
        for (int i = vars.length - 1; i >= 0; i--) {
            vars[i] = mv.nextLocal();
            mv.storeLocal(vars[i]);
        }
        // only Logger on stack
        mv.dup();
        final int loggerIdx = mv.nextLocal();
        mv.storeLocal(loggerIdx, LOGGER_TYPE);
        mv.invokeInterface(LOGGER_TYPE, AT_TRACE_METHOD);
        mv.storeLocation();
        mv.getStatic(ABSTRACT_LOGGER_TYPE, EXIT_MARKER, MARKER_TYPE);
        mv.invokeInterface(LOG_BUILDER_TYPE, WITH_MARKER_METHOD);
        mv.loadLocal(loggerIdx, LOGGER_TYPE);
        if (types.length == 0) {
            mv.push((String) null);
            mv.push((String) null);
            mv.invokeSupplierLambda(SupplierLambdaType.EXIT_MESSAGE_STRING_OBJECT);
        } else if (Arrays.deepEquals(types, MESSAGE_OBJECT_ARRAY)) {
            // Invert arguments
            mv.loadLocal(vars[1]);
            mv.loadLocal(vars[0]);
            mv.invokeSupplierLambda(SupplierLambdaType.EXIT_MESSAGE_OBJECT_MESSAGE);
        } else if (ENTRY_MESSAGE_TYPE.equals(types[0])) {
            final boolean hasResult = types.length == 2;
            if (hasResult) {
                mv.loadLocal(vars[1]);
            }
            mv.loadLocal(vars[0]);
            mv.invokeSupplierLambda(
                    hasResult
                            ? SupplierLambdaType.EXIT_MESSAGE_OBJECT_ENTRY_MESSAGE
                            : SupplierLambdaType.EXIT_MESSAGE_ENTRY_MESSAGE);
        } else {
            final boolean hasFormat = STRING_TYPE.equals(types[0]);
            if (hasFormat) {
                mv.loadLocal(vars[0]);
            } else {
                mv.push((String) null);
            }
            mv.loadLocal(vars[hasFormat ? 1 : 0], OBJECT_TYPE);
            mv.invokeSupplierLambda(SupplierLambdaType.EXIT_MESSAGE_STRING_OBJECT);
        }
        mv.invokeInterface(LOG_BUILDER_TYPE, LOG_BUILDER_LOG_SUPPLIER_METHOD);
        // except void methods traceExit() and traceExit(EntryMessage)
        if (types.length != 0 && (types.length > 1 || !ENTRY_MESSAGE_TYPE.equals(types[0]))) {
            mv.loadLocal(vars[vars.length - 1]);
        }
    }