src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.verifier/src/org/graalvm/compiler/replacements/verifier/APHotSpotSignature.java
branchJDK-8145252-TLS13-branch
changeset 56645 c10dbcaed048
parent 56637 d66751750b72
parent 50332 d0d933d61610
child 56646 e57205a6e4ee
equal deleted inserted replaced
56637:d66751750b72 56645:c10dbcaed048
     1 /*
       
     2  * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 package org.graalvm.compiler.replacements.verifier;
       
    24 
       
    25 import java.util.ArrayList;
       
    26 import java.util.List;
       
    27 
       
    28 import javax.annotation.processing.ProcessingEnvironment;
       
    29 import javax.lang.model.element.TypeElement;
       
    30 import javax.lang.model.type.TypeKind;
       
    31 import javax.lang.model.type.TypeMirror;
       
    32 import javax.tools.Diagnostic.Kind;
       
    33 
       
    34 /**
       
    35  * Pretty much copied from HotSpotSignature but using a different method for resolving types. This
       
    36  * class should be rewritten, its just a quick hack to get signatures working.
       
    37  */
       
    38 final class APHotSpotSignature {
       
    39 
       
    40     private final List<String> arguments = new ArrayList<>();
       
    41     private final String returnType;
       
    42     private final String originalString;
       
    43     private TypeMirror[] argumentTypes;
       
    44     private TypeMirror returnTypeCache;
       
    45 
       
    46     APHotSpotSignature(String signature) {
       
    47         assert signature.length() > 0;
       
    48         this.originalString = signature;
       
    49 
       
    50         if (signature.charAt(0) == '(') {
       
    51             int cur = 1;
       
    52             while (cur < signature.length() && signature.charAt(cur) != ')') {
       
    53                 int nextCur = parseSignature(signature, cur);
       
    54                 arguments.add(signature.substring(cur, nextCur));
       
    55                 cur = nextCur;
       
    56             }
       
    57 
       
    58             cur++;
       
    59             int nextCur = parseSignature(signature, cur);
       
    60             returnType = signature.substring(cur, nextCur);
       
    61             if (nextCur != signature.length()) {
       
    62                 throw new RuntimeException("Invalid trailing characters.");
       
    63             }
       
    64         } else {
       
    65             returnType = null;
       
    66         }
       
    67     }
       
    68 
       
    69     private static int parseSignature(String signature, int start) {
       
    70         int cur = start;
       
    71         char first;
       
    72         do {
       
    73             first = signature.charAt(cur++);
       
    74         } while (first == '[');
       
    75 
       
    76         switch (first) {
       
    77             case 'L':
       
    78                 while (signature.charAt(cur) != ';') {
       
    79                     cur++;
       
    80                 }
       
    81                 cur++;
       
    82                 break;
       
    83             case 'V':
       
    84             case 'I':
       
    85             case 'B':
       
    86             case 'C':
       
    87             case 'D':
       
    88             case 'F':
       
    89             case 'J':
       
    90             case 'S':
       
    91             case 'Z':
       
    92                 break;
       
    93             default:
       
    94                 throw new RuntimeException("Invalid character at index " + cur + " in signature: " + signature);
       
    95         }
       
    96         return cur;
       
    97     }
       
    98 
       
    99     public int getParameterCount(boolean withReceiver) {
       
   100         return arguments.size() + (withReceiver ? 1 : 0);
       
   101     }
       
   102 
       
   103     public TypeMirror getParameterType(ProcessingEnvironment env, int index) {
       
   104         if (argumentTypes == null) {
       
   105             argumentTypes = new TypeMirror[arguments.size()];
       
   106         }
       
   107         TypeMirror type = argumentTypes[index];
       
   108         if (arguments.get(index) == null) {
       
   109             throw new RuntimeException(String.format("Invalid argument at index %s.", index));
       
   110         }
       
   111 
       
   112         if (type == null) {
       
   113             argumentTypes[index] = lookupType(env, arguments.get(index));
       
   114         }
       
   115         return argumentTypes[index];
       
   116     }
       
   117 
       
   118     private static TypeMirror lookupType(ProcessingEnvironment env, String binaryName) {
       
   119         if (binaryName.length() == 1) {
       
   120             TypeKind kind = fromPrimitiveOrVoidTypeChar(binaryName.charAt(0));
       
   121             if (kind.isPrimitive()) {
       
   122                 return env.getTypeUtils().getPrimitiveType(kind);
       
   123             } else if (kind == TypeKind.VOID) {
       
   124                 return env.getTypeUtils().getNoType(kind);
       
   125             }
       
   126         }
       
   127 
       
   128         String canonicalName = binaryName;
       
   129         if (canonicalName.startsWith("L") && canonicalName.endsWith(";")) {
       
   130             canonicalName = canonicalName.substring(1, canonicalName.length() - 1);
       
   131         }
       
   132         env.getMessager().printMessage(Kind.ERROR, canonicalName);
       
   133 
       
   134         int arrayDims = 0;
       
   135         while (canonicalName.startsWith("[")) {
       
   136             canonicalName = canonicalName.substring(1, canonicalName.length());
       
   137             arrayDims++;
       
   138         }
       
   139 
       
   140         canonicalName = canonicalName.replaceAll("/", ".");
       
   141         TypeElement typeElement = env.getElementUtils().getTypeElement(canonicalName);
       
   142         if (typeElement == null) {
       
   143             throw new RuntimeException(String.format("Type with name %s not found.", canonicalName));
       
   144         }
       
   145         TypeMirror mirror = typeElement.asType();
       
   146         for (int i = 0; i < arrayDims; i++) {
       
   147             mirror = env.getTypeUtils().getArrayType(mirror);
       
   148         }
       
   149         return mirror;
       
   150     }
       
   151 
       
   152     /**
       
   153      * Returns the kind from the character describing a primitive or void.
       
   154      *
       
   155      * @param ch the character
       
   156      * @return the kind
       
   157      */
       
   158     public static TypeKind fromPrimitiveOrVoidTypeChar(char ch) {
       
   159         switch (ch) {
       
   160             case 'Z':
       
   161                 return TypeKind.BOOLEAN;
       
   162             case 'C':
       
   163                 return TypeKind.CHAR;
       
   164             case 'F':
       
   165                 return TypeKind.FLOAT;
       
   166             case 'D':
       
   167                 return TypeKind.DOUBLE;
       
   168             case 'B':
       
   169                 return TypeKind.BYTE;
       
   170             case 'S':
       
   171                 return TypeKind.SHORT;
       
   172             case 'I':
       
   173                 return TypeKind.INT;
       
   174             case 'J':
       
   175                 return TypeKind.LONG;
       
   176             case 'V':
       
   177                 return TypeKind.VOID;
       
   178         }
       
   179         throw new IllegalArgumentException("unknown primitive or void type character: " + ch);
       
   180     }
       
   181 
       
   182     public TypeMirror getReturnType(ProcessingEnvironment env) {
       
   183         if (returnTypeCache == null) {
       
   184             if (returnType == null) {
       
   185                 throw new RuntimeException("Invalid return type.");
       
   186             }
       
   187             returnTypeCache = lookupType(env, returnType);
       
   188         }
       
   189         return returnTypeCache;
       
   190     }
       
   191 
       
   192     @Override
       
   193     public String toString() {
       
   194         return "Signature<" + originalString + ">";
       
   195     }
       
   196 }