< prev index next >

src/java.base/share/classes/java/lang/reflect/Method.java

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this

@@ -43,13 +43,20 @@
  import sun.reflect.generics.scope.MethodScope;
  import sun.reflect.annotation.AnnotationType;
  import sun.reflect.annotation.AnnotationParser;
  import java.lang.annotation.Annotation;
  import java.lang.annotation.AnnotationFormatError;
+ import java.lang.reflect.code.op.ExtendedOp;
+ import java.lang.reflect.code.Op;
+ import java.lang.reflect.code.parser.OpParser;
  import java.nio.ByteBuffer;
+ import java.util.List;
+ import java.util.Optional;
  import java.util.StringJoiner;
  
+ import static java.lang.reflect.code.op.CoreOp.*;
+ 
  /**
   * A {@code Method} provides information about, and access to, a single method
   * on a class or interface.  The reflected method may be a class method
   * or an instance method (including an abstract method).
   *

@@ -93,10 +100,11 @@
      // potentially many Method objects pointing to it.)
      //
      // If this branching structure would ever contain cycles, deadlocks can
      // occur in annotation code.
      private Method              root;
+     private volatile Optional<FuncOp>     codeModel;
  
      // Generics infrastructure
      private String getGenericSignature() {return signature;}
  
      // Accessor for factory

@@ -243,10 +251,62 @@
      @Override
      public int getModifiers() {
          return modifiers;
      }
  
+     /**
+      * Returns the code model of the method body, if present.
+      * @return the code model of the method body.
+      * @since 99
+      */
+     // @@@ Make caller sensitive with the same access control as invoke
+     // and throwing IllegalAccessException
+ //    @CallerSensitive
+     public Optional<FuncOp> getCodeModel() {
+         Optional<FuncOp> localRef = codeModel;
+         if (localRef == null) {
+             synchronized (this) {
+                 localRef = codeModel;
+                 if (localRef == null) {
+                     Optional<FuncOp> op = createCodeModel();
+                     codeModel = localRef = op;
+                 }
+             }
+         }
+         return localRef;
+     }
+ 
+     private Optional<FuncOp> createCodeModel() {
+         Class<?> dc = getDeclaringClass();
+         String fieldName = getName() + "$" + "op";
+         Field f;
+         try {
+             f = dc.getDeclaredField(fieldName);
+         } catch (NoSuchFieldException e) {
+             return Optional.empty();
+         }
+ 
+         String modelText;
+         try {
+             // @@@ Use method handle with full power mode
+             f.setAccessible(true);
+             modelText = (String) f.get(null);
+         } catch (IllegalAccessException e) {
+             throw new RuntimeException(e);
+         }
+ 
+         FuncOp op;
+         try {
+             List<Op> ops = OpParser.fromString(ExtendedOp.FACTORY, modelText);
+             op = (FuncOp) ops.get(0);
+         } catch (RuntimeException e) {
+             // @@@ Error or Exception?
+             throw e;
+         }
+         return Optional.of(op);
+     }
+ 
      /**
       * {@inheritDoc}
       * @throws GenericSignatureFormatError {@inheritDoc}
       * @since 1.5
       * @jls 8.4.4 Generic Methods
< prev index next >