1 /* 2 * Copyright (c) 2022, 2024, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 * 25 */ 26 package jdk.internal.classfile.impl.verifier; 27 28 import java.lang.classfile.Attributes; 29 import java.lang.classfile.ClassModel; 30 import java.lang.classfile.FieldModel; 31 import java.lang.classfile.MethodModel; 32 import java.lang.classfile.attribute.LocalVariableInfo; 33 import java.lang.classfile.constantpool.ClassEntry; 34 import java.lang.classfile.constantpool.ConstantPool; 35 import java.lang.classfile.constantpool.DynamicConstantPoolEntry; 36 import java.lang.classfile.constantpool.MemberRefEntry; 37 import java.lang.classfile.constantpool.NameAndTypeEntry; 38 import java.lang.constant.ClassDesc; 39 import java.lang.reflect.AccessFlag; 40 import java.util.LinkedList; 41 import java.util.List; 42 import java.util.stream.Collectors; 43 44 import jdk.internal.classfile.impl.BoundAttribute; 45 import jdk.internal.classfile.impl.CodeImpl; 46 import jdk.internal.classfile.impl.Util; 47 48 public final class VerificationWrapper { 49 final ClassModel clm; 50 private final ConstantPoolWrapper cp; 51 52 public VerificationWrapper(ClassModel clm) { 53 this.clm = clm; 54 this.cp = new ConstantPoolWrapper(clm.constantPool()); 55 } 56 57 String thisClassName() { 58 return clm.thisClass().asInternalName(); 59 } 60 61 int majorVersion() { 62 return clm.majorVersion(); 63 } 64 65 String superclassName() { 66 return clm.superclass().map(ClassEntry::asInternalName).orElse(null); 67 } 68 69 Iterable<String> interfaceNames() { 70 return Util.mappedList(clm.interfaces(), ClassEntry::asInternalName); 71 } 72 73 Iterable<MethodWrapper> methods() { 74 return clm.methods().stream().map(m -> new MethodWrapper(m)).toList(); 75 } 76 77 FieldModel findField(String name, String sig) { 78 for (var f : clm.fields()) 79 if (f.fieldName().stringValue().equals(name) && f.fieldType().stringValue().equals(sig)) 80 return f; 81 return null; 82 } 83 84 class MethodWrapper { 85 86 final MethodModel m; 87 private final CodeImpl c; 88 private final List<int[]> exc; 89 90 MethodWrapper(MethodModel m) { 91 this.m = m; 92 this.c = (CodeImpl)m.code().orElse(null); 93 exc = new LinkedList<>(); 94 if (c != null) c.iterateExceptionHandlers((start, end, handler, catchType) -> { 95 exc.add(new int[] {start, end, handler, catchType}); 96 }); 97 } 98 99 ConstantPoolWrapper constantPool() { 100 return cp; 101 } 102 103 boolean isNative() { 104 return m.flags().has(AccessFlag.NATIVE); 105 } 106 107 boolean isAbstract() { 108 return m.flags().has(AccessFlag.ABSTRACT); 109 } 110 111 boolean isBridge() { 112 return m.flags().has(AccessFlag.BRIDGE); 113 } 114 115 boolean isStatic() { 116 return m.flags().has(AccessFlag.STATIC); 117 } 118 119 String name() { 120 return m.methodName().stringValue(); 121 } 122 123 int maxStack() { 124 return c == null ? 0 : c.maxStack(); 125 } 126 127 int maxLocals() { 128 return c == null ? 0 : c.maxLocals(); 129 } 130 131 String descriptor() { 132 return m.methodType().stringValue(); 133 } 134 135 String parameters() { 136 return m.methodTypeSymbol().parameterList().stream().map(ClassDesc::displayName).collect(Collectors.joining(",")); 137 } 138 139 int codeLength() { 140 return c == null ? 0 : c.codeLength(); 141 } 142 143 byte[] codeArray() { 144 return c == null ? null : c.codeArray(); 145 } 146 147 List<int[]> exceptionTable() { 148 return exc; 149 } 150 151 List<LocalVariableInfo> localVariableTable() { 152 var attro = c.findAttribute(Attributes.localVariableTable()); 153 return attro.map(lvta -> lvta.localVariables()).orElse(List.of()); 154 } 155 156 byte[] stackMapTableRawData() { 157 var attro = c.findAttribute(Attributes.stackMapTable()); 158 return attro.map(attr -> ((BoundAttribute) attr).contents()).orElse(null); 159 } 160 161 } 162 163 static class ConstantPoolWrapper { 164 165 final ConstantPool cp; 166 167 ConstantPoolWrapper(ConstantPool cp) { 168 this.cp = cp; 169 } 170 171 int entryCount() { 172 return cp.size(); 173 } 174 175 String classNameAt(int index) { 176 return cp.entryByIndex(index, ClassEntry.class).asInternalName(); 177 } 178 179 String dynamicConstantSignatureAt(int index) { 180 return cp.entryByIndex(index, DynamicConstantPoolEntry.class).type().stringValue(); 181 } 182 183 int tagAt(int index) { 184 return cp.entryByIndex(index).tag(); 185 } 186 187 private NameAndTypeEntry _refNameType(int index) { 188 var e = cp.entryByIndex(index); 189 return (e instanceof DynamicConstantPoolEntry de) ? de.nameAndType() : 190 e != null ? ((MemberRefEntry)e).nameAndType() : null; 191 } 192 193 String refNameAt(int index) { 194 return _refNameType(index).name().stringValue(); 195 } 196 197 String refSignatureAt(int index) { 198 return _refNameType(index).type().stringValue(); 199 } 200 201 int refClassIndexAt(int index) { 202 return cp.entryByIndex(index, MemberRefEntry.class).owner().index(); 203 } 204 205 boolean is_within_bounds(int i) { 206 return i >= 1 && i <= cp.size(); 207 } 208 } 209 }