1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * ASM: a very small and fast Java bytecode manipulation framework 32 * Copyright (c) 2000-2011 INRIA, France Telecom 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. Neither the name of the copyright holders nor the names of its 44 * contributors may be used to endorse or promote products derived from 45 * this software without specific prior written permission. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 57 * THE POSSIBILITY OF SUCH DAMAGE. 58 */ 59 60 package jdk.internal.org.objectweb.asm; 61 62 /** 63 * @author Remi Forax 64 */ 65 final class ModuleWriter extends ModuleVisitor { 66 /** 67 * The class writer to which this Module attribute must be added. 68 */ 69 private final ClassWriter cw; 70 71 /** 72 * size in byte of the Module attribute. 73 */ 74 int size; 75 76 /** 77 * Number of attributes associated with the current module 78 * (Version, ConcealPackages, etc) 79 */ 80 int attributeCount; 81 82 /** 83 * Size in bytes of the attributes associated with the current module 84 */ 85 int attributesSize; 86 87 /** 88 * module name index in the constant pool 89 */ 90 private final int name; 91 92 /** 93 * module access flags 94 */ 95 private final int access; 96 97 /** 98 * module version index in the constant pool or 0 99 */ 100 private final int version; 101 102 /** 103 * module main class index in the constant pool or 0 104 */ 105 private int mainClass; 106 107 /** 108 * number of packages 109 */ 110 private int packageCount; 111 112 /** 113 * The packages in bytecode form. This byte vector only contains 114 * the items themselves, the number of items is store in packageCount 115 */ 116 private ByteVector packages; 117 118 /** 119 * number of requires items 120 */ 121 private int requireCount; 122 123 /** 124 * The requires items in bytecode form. This byte vector only contains 125 * the items themselves, the number of items is store in requireCount 126 */ 127 private ByteVector requires; 128 129 /** 130 * number of exports items 131 */ 132 private int exportCount; 133 134 /** 135 * The exports items in bytecode form. This byte vector only contains 136 * the items themselves, the number of items is store in exportCount 137 */ 138 private ByteVector exports; 139 140 /** 141 * number of opens items 142 */ 143 private int openCount; 144 145 /** 146 * The opens items in bytecode form. This byte vector only contains 147 * the items themselves, the number of items is store in openCount 148 */ 149 private ByteVector opens; 150 151 /** 152 * number of uses items 153 */ 154 private int useCount; 155 156 /** 157 * The uses items in bytecode form. This byte vector only contains 158 * the items themselves, the number of items is store in useCount 159 */ 160 private ByteVector uses; 161 162 /** 163 * number of provides items 164 */ 165 private int provideCount; 166 167 /** 168 * The uses provides in bytecode form. This byte vector only contains 169 * the items themselves, the number of items is store in provideCount 170 */ 171 private ByteVector provides; 172 173 ModuleWriter(final ClassWriter cw, final int name, 174 final int access, final int version) { 175 super(Opcodes.ASM6); 176 this.cw = cw; 177 this.size = 16; // name + access + version + 5 counts 178 this.name = name; 179 this.access = access; 180 this.version = version; 181 } 182 183 @Override 184 public void visitMainClass(String mainClass) { 185 if (this.mainClass == 0) { // protect against several calls to visitMainClass 186 cw.newUTF8("ModuleMainClass"); 187 attributeCount++; 188 attributesSize += 8; 189 } 190 this.mainClass = cw.newClass(mainClass); 191 } 192 193 @Override 194 public void visitPackage(String packaze) { 195 if (packages == null) { 196 // protect against several calls to visitPackage 197 cw.newUTF8("ModulePackages"); 198 packages = new ByteVector(); 199 attributeCount++; 200 attributesSize += 8; 201 } 202 packages.putShort(cw.newPackage(packaze)); 203 packageCount++; 204 attributesSize += 2; 205 } 206 207 @Override 208 public void visitRequire(String module, int access, String version) { 209 if (requires == null) { 210 requires = new ByteVector(); 211 } 212 requires.putShort(cw.newModule(module)) 213 .putShort(access) 214 .putShort(version == null? 0: cw.newUTF8(version)); 215 requireCount++; 216 size += 6; 217 } 218 219 @Override 220 public void visitExport(String packaze, int access, String... modules) { 221 if (exports == null) { 222 exports = new ByteVector(); 223 } 224 exports.putShort(cw.newPackage(packaze)).putShort(access); 225 if (modules == null) { 226 exports.putShort(0); 227 size += 6; 228 } else { 229 exports.putShort(modules.length); 230 for(String module: modules) { 231 exports.putShort(cw.newModule(module)); 232 } 233 size += 6 + 2 * modules.length; 234 } 235 exportCount++; 236 } 237 238 @Override 239 public void visitOpen(String packaze, int access, String... modules) { 240 if (opens == null) { 241 opens = new ByteVector(); 242 } 243 opens.putShort(cw.newPackage(packaze)).putShort(access); 244 if (modules == null) { 245 opens.putShort(0); 246 size += 6; 247 } else { 248 opens.putShort(modules.length); 249 for(String module: modules) { 250 opens.putShort(cw.newModule(module)); 251 } 252 size += 6 + 2 * modules.length; 253 } 254 openCount++; 255 } 256 257 @Override 258 public void visitUse(String service) { 259 if (uses == null) { 260 uses = new ByteVector(); 261 } 262 uses.putShort(cw.newClass(service)); 263 useCount++; 264 size += 2; 265 } 266 267 @Override 268 public void visitProvide(String service, String... providers) { 269 if (provides == null) { 270 provides = new ByteVector(); 271 } 272 provides.putShort(cw.newClass(service)); 273 provides.putShort(providers.length); 274 for(String provider: providers) { 275 provides.putShort(cw.newClass(provider)); 276 } 277 provideCount++; 278 size += 4 + 2 * providers.length; 279 } 280 281 @Override 282 public void visitEnd() { 283 // empty 284 } 285 286 void putAttributes(ByteVector out) { 287 if (mainClass != 0) { 288 out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass); 289 } 290 if (packages != null) { 291 out.putShort(cw.newUTF8("ModulePackages")) 292 .putInt(2 + 2 * packageCount) 293 .putShort(packageCount) 294 .putByteArray(packages.data, 0, packages.length); 295 } 296 } 297 298 void put(ByteVector out) { 299 out.putInt(size); 300 out.putShort(name).putShort(access).putShort(version); 301 out.putShort(requireCount); 302 if (requires != null) { 303 out.putByteArray(requires.data, 0, requires.length); 304 } 305 out.putShort(exportCount); 306 if (exports != null) { 307 out.putByteArray(exports.data, 0, exports.length); 308 } 309 out.putShort(openCount); 310 if (opens != null) { 311 out.putByteArray(opens.data, 0, opens.length); 312 } 313 out.putShort(useCount); 314 if (uses != null) { 315 out.putByteArray(uses.data, 0, uses.length); 316 } 317 out.putShort(provideCount); 318 if (provides != null) { 319 out.putByteArray(provides.data, 0, provides.length); 320 } 321 } 322 }