1 /*
   2  * Copyright (c) 2012, 2014, 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.hotspot.replacements;
  24 
  25 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
  26 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.ARRAY_KLASS_COMPONENT_MIRROR;
  27 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_ACCESS_FLAGS_LOCATION;
  28 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_MODIFIER_FLAGS_LOCATION;
  29 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_SUPER_KLASS_LOCATION;
  30 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayKlassComponentMirrorOffset;
  31 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassAccessFlagsOffset;
  32 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassIsArray;
  33 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassModifierFlagsOffset;
  34 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassSuperKlassOffset;
  35 
  36 import java.lang.reflect.Modifier;
  37 
  38 import org.graalvm.compiler.api.replacements.ClassSubstitution;
  39 import org.graalvm.compiler.api.replacements.MethodSubstitution;
  40 import org.graalvm.compiler.hotspot.word.KlassPointer;
  41 import org.graalvm.compiler.nodes.PiNode;
  42 
  43 // JaCoCo Exclude
  44 
  45 /**
  46  * Substitutions for {@link java.lang.Class} methods.
  47  */
  48 @ClassSubstitution(Class.class)
  49 public class HotSpotClassSubstitutions {
  50 
  51     @MethodSubstitution(isStatic = false)
  52     public static int getModifiers(final Class<?> thisObj) {
  53         KlassPointer klass = ClassGetHubNode.readClass(thisObj);
  54         if (klass.isNull()) {
  55             // Class for primitive type
  56             return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
  57         } else {
  58             return klass.readInt(klassModifierFlagsOffset(INJECTED_VMCONFIG), KLASS_MODIFIER_FLAGS_LOCATION);
  59         }
  60     }
  61 
  62     @MethodSubstitution(isStatic = false)
  63     public static boolean isInterface(final Class<?> thisObj) {
  64         KlassPointer klass = ClassGetHubNode.readClass(thisObj);
  65         if (klass.isNull()) {
  66             // Class for primitive type
  67             return false;
  68         } else {
  69             int accessFlags = klass.readInt(klassAccessFlagsOffset(INJECTED_VMCONFIG), KLASS_ACCESS_FLAGS_LOCATION);
  70             return (accessFlags & Modifier.INTERFACE) != 0;
  71         }
  72     }
  73 
  74     @MethodSubstitution(isStatic = false)
  75     public static boolean isArray(final Class<?> thisObj) {
  76         KlassPointer klass = ClassGetHubNode.readClass(thisObj);
  77         if (klass.isNull()) {
  78             // Class for primitive type
  79             return false;
  80         } else {
  81             return klassIsArray(klass);
  82         }
  83     }
  84 
  85     @MethodSubstitution(isStatic = false)
  86     public static boolean isPrimitive(final Class<?> thisObj) {
  87         KlassPointer klass = ClassGetHubNode.readClass(thisObj);
  88         return klass.isNull();
  89     }
  90 
  91     @MethodSubstitution(isStatic = false)
  92     public static Class<?> getSuperclass(final Class<?> thisObj) {
  93         KlassPointer klass = ClassGetHubNode.readClass(thisObj);
  94         if (!klass.isNull()) {
  95             int accessFlags = klass.readInt(klassAccessFlagsOffset(INJECTED_VMCONFIG), KLASS_ACCESS_FLAGS_LOCATION);
  96             if ((accessFlags & Modifier.INTERFACE) == 0) {
  97                 if (klassIsArray(klass)) {
  98                     return Object.class;
  99                 } else {
 100                     KlassPointer superKlass = klass.readKlassPointer(klassSuperKlassOffset(INJECTED_VMCONFIG), KLASS_SUPER_KLASS_LOCATION);
 101                     if (superKlass.isNull()) {
 102                         return null;
 103                     } else {
 104                         return readJavaMirror(superKlass);
 105                     }
 106                 }
 107             }
 108         } else {
 109             // Class for primitive type
 110         }
 111         return null;
 112     }
 113 
 114     public static Class<?> readJavaMirror(KlassPointer klass) {
 115         return PiNode.asNonNullClass(HubGetClassNode.readClass(klass));
 116     }
 117 
 118     @MethodSubstitution(isStatic = false)
 119     public static Class<?> getComponentType(final Class<?> thisObj) {
 120         KlassPointer klass = ClassGetHubNode.readClass(thisObj);
 121         if (!klass.isNull()) {
 122             if (klassIsArray(klass)) {
 123                 return PiNode.asNonNullClass(klass.readObject(arrayKlassComponentMirrorOffset(INJECTED_VMCONFIG), ARRAY_KLASS_COMPONENT_MIRROR));
 124             }
 125         } else {
 126             // Class for primitive type
 127         }
 128         return null;
 129     }
 130 }