test/tools/javac/lambdaShapes/org/openjdk/tests/separate/ClassFile.java

Thu, 24 Oct 2013 16:52:27 -0700

author
rfield
date
Thu, 24 Oct 2013 16:52:27 -0700
changeset 2170
860f1d21763a
parent 1448
7d34e91f66bb
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8027220: DefaultMethodsTest: Change test to match spec
Reviewed-by: ksrini

rfield@1422 1 /*
katleman@1448 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
rfield@1422 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
rfield@1422 4 *
rfield@1422 5 * This code is free software; you can redistribute it and/or modify it
rfield@1422 6 * under the terms of the GNU General Public License version 2 only, as
rfield@1422 7 * published by the Free Software Foundation. Oracle designates this
rfield@1422 8 * particular file as subject to the "Classpath" exception as provided
rfield@1422 9 * by Oracle in the LICENSE file that accompanied this code.
rfield@1422 10 *
rfield@1422 11 * This code is distributed in the hope that it will be useful, but WITHOUT
rfield@1422 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
rfield@1422 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
rfield@1422 14 * version 2 for more details (a copy is included in the LICENSE file that
rfield@1422 15 * accompanied this code).
rfield@1422 16 *
rfield@1422 17 * You should have received a copy of the GNU General Public License version
rfield@1422 18 * 2 along with this work; if not, write to the Free Software Foundation,
rfield@1422 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
rfield@1422 20 *
rfield@1422 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
rfield@1422 22 * or visit www.oracle.com if you need additional information or have any
rfield@1422 23 * questions.
rfield@1422 24 */
rfield@1422 25
rfield@1422 26 package org.openjdk.tests.separate;
rfield@1422 27
rfield@1422 28 import java.io.*;
rfield@1422 29 import java.util.*;
rfield@1422 30
rfield@1422 31 class CfInputStream extends ByteArrayInputStream {
rfield@1422 32 private int ct;
rfield@1422 33 public CfInputStream(byte[] input) {
rfield@1422 34 super(input);
rfield@1422 35 }
rfield@1422 36
rfield@1422 37 byte u1() { return (byte)read(); }
rfield@1422 38 short u2() {
rfield@1422 39 int b0 = read() << 8;
rfield@1422 40 int b1 = read();
rfield@1422 41 return (short)(b0 | b1);
rfield@1422 42 }
rfield@1422 43 int u4() {
rfield@1422 44 int b0 = read() << 24;
rfield@1422 45 int b1 = read() << 16;
rfield@1422 46 int b2 = read() << 8;
rfield@1422 47 int b3 = read();
rfield@1422 48 return b0 | b1 | b2 | b3;
rfield@1422 49 }
rfield@1422 50 byte[] array(int count) {
rfield@1422 51 byte[] ret = new byte[count];
rfield@1422 52 read(ret, 0, count);
rfield@1422 53 return ret;
rfield@1422 54 }
rfield@1422 55 };
rfield@1422 56
rfield@1422 57 class CfOutputStream extends ByteArrayOutputStream {
rfield@1422 58 void u1(byte b) { write((int)b); }
rfield@1422 59 void u2(short s) {
rfield@1422 60 write((s >> 8) & 0xff);
rfield@1422 61 write(s & 0xff);
rfield@1422 62 }
rfield@1422 63 void u4(int i) {
rfield@1422 64 write((i >> 24) & 0xff);
rfield@1422 65 write((i >> 16) & 0xff);
rfield@1422 66 write((i >> 8) & 0xff);
rfield@1422 67 write(i & 0xff);
rfield@1422 68 }
rfield@1422 69 void array(byte[] a) {
rfield@1422 70 write(a, 0, a.length);
rfield@1422 71 }
rfield@1422 72
rfield@1422 73 public byte[] toByteArray() { return super.toByteArray(); }
rfield@1422 74 };
rfield@1422 75
rfield@1422 76 // A quick and dirty class file parser and representation
rfield@1422 77 public class ClassFile {
rfield@1422 78
rfield@1422 79 int magic;
rfield@1422 80 short minor_version;
rfield@1422 81 short major_version;
rfield@1422 82 ArrayList<CpEntry> constant_pool;
rfield@1422 83 short access_flags;
rfield@1422 84 short this_class;
rfield@1422 85 short super_class;
rfield@1422 86 ArrayList<Interface> interfaces;
rfield@1422 87 ArrayList<Field> fields;
rfield@1422 88 ArrayList<Method> methods;
rfield@1422 89 ArrayList<Attribute> attributes;
rfield@1422 90
rfield@1422 91 ClassFile(byte[] cf) {
rfield@1422 92 CfInputStream in = new CfInputStream(cf);
rfield@1422 93
rfield@1422 94 magic = in.u4();
rfield@1422 95 minor_version = in.u2();
rfield@1422 96 major_version = in.u2();
rfield@1422 97
rfield@1422 98 short cpCount = in.u2();
rfield@1422 99 constant_pool = new ArrayList<>();
rfield@1422 100 constant_pool.add(new CpNull());
rfield@1422 101 for (int i = 1; i < cpCount; ++i) {
rfield@1422 102 constant_pool.add(CpEntry.newCpEntry(in));
rfield@1422 103 }
rfield@1422 104
rfield@1422 105 access_flags = in.u2();
rfield@1422 106 this_class = in.u2();
rfield@1422 107 super_class = in.u2();
rfield@1422 108
rfield@1422 109 short ifaceCount = in.u2();
rfield@1422 110 interfaces = new ArrayList<>();
rfield@1422 111 for (int i = 0; i < ifaceCount; ++i) {
rfield@1422 112 interfaces.add(new Interface(in));
rfield@1422 113 }
rfield@1422 114
rfield@1422 115 short fieldCount = in.u2();
rfield@1422 116 fields = new ArrayList<>();
rfield@1422 117 for (int i = 0; i < fieldCount; ++i) {
rfield@1422 118 fields.add(new Field(in));
rfield@1422 119 }
rfield@1422 120
rfield@1422 121 short methodCount = in.u2();
rfield@1422 122 methods = new ArrayList<>();
rfield@1422 123 for (int i = 0; i < methodCount; ++i) {
rfield@1422 124 methods.add(new Method(in));
rfield@1422 125 }
rfield@1422 126
rfield@1422 127 short attributeCount = in.u2();
rfield@1422 128 attributes = new ArrayList<>();
rfield@1422 129 for (int i = 0; i < attributeCount; ++i) {
rfield@1422 130 attributes.add(new Attribute(in));
rfield@1422 131 }
rfield@1422 132 }
rfield@1422 133
rfield@1422 134 byte[] toByteArray() {
rfield@1422 135 CfOutputStream out = new CfOutputStream();
rfield@1422 136
rfield@1422 137 out.u4(magic);
rfield@1422 138 out.u2(minor_version);
rfield@1422 139 out.u2(major_version);
rfield@1422 140
rfield@1422 141 out.u2((short)(constant_pool.size()));
rfield@1422 142 for (CpEntry cp : constant_pool) {
rfield@1422 143 cp.write(out);
rfield@1422 144 }
rfield@1422 145
rfield@1422 146 out.u2(access_flags);
rfield@1422 147 out.u2(this_class);
rfield@1422 148 out.u2(super_class);
rfield@1422 149
rfield@1422 150 out.u2((short)interfaces.size());
rfield@1422 151 for (Interface iface : interfaces) {
rfield@1422 152 iface.write(out);
rfield@1422 153 }
rfield@1422 154
rfield@1422 155 out.u2((short)fields.size());
rfield@1422 156 for (Field field : fields) {
rfield@1422 157 field.write(out);
rfield@1422 158 }
rfield@1422 159
rfield@1422 160 out.u2((short)methods.size());
rfield@1422 161 for (Method method : methods) {
rfield@1422 162 method.write(out);
rfield@1422 163 }
rfield@1422 164
rfield@1422 165 out.u2((short)attributes.size());
rfield@1422 166 for (Attribute attribute : attributes) {
rfield@1422 167 attribute.write(out);
rfield@1422 168 }
rfield@1422 169
rfield@1422 170 return out.toByteArray();
rfield@1422 171 }
rfield@1422 172
rfield@1422 173 static abstract class CpEntry {
rfield@1422 174 byte tag;
rfield@1422 175
rfield@1422 176 CpEntry(byte t) { tag = t; }
rfield@1422 177 void write(CfOutputStream out) {
rfield@1422 178 out.u1(tag);
rfield@1422 179 }
rfield@1422 180
rfield@1422 181 static CpEntry newCpEntry(CfInputStream in) {
rfield@1422 182 byte tag = in.u1();
rfield@1422 183 switch (tag) {
rfield@1422 184 case CpUtf8.TAG: return new CpUtf8(in);
rfield@1422 185 case CpInteger.TAG: return new CpInteger(in);
rfield@1422 186 case CpFloat.TAG: return new CpFloat(in);
rfield@1422 187 case CpLong.TAG: return new CpLong(in);
rfield@1422 188 case CpDouble.TAG: return new CpDouble(in);
rfield@1422 189 case CpClass.TAG: return new CpClass(in);
rfield@1422 190 case CpString.TAG: return new CpString(in);
rfield@1422 191 case CpFieldRef.TAG: return new CpFieldRef(in);
rfield@1422 192 case CpMethodRef.TAG: return new CpMethodRef(in);
rfield@1422 193 case CpInterfaceMethodRef.TAG:
rfield@1422 194 return new CpInterfaceMethodRef(in);
rfield@1422 195 case CpNameAndType.TAG: return new CpNameAndType(in);
rfield@1422 196 case CpMethodHandle.TAG: return new CpMethodHandle(in);
rfield@1422 197 case CpMethodType.TAG: return new CpMethodType(in);
rfield@1422 198 case CpInvokeDynamic.TAG: return new CpInvokeDynamic(in);
rfield@1422 199 default: throw new RuntimeException("Bad cp entry tag: " + tag);
rfield@1422 200 }
rfield@1422 201 }
rfield@1422 202 }
rfield@1422 203
rfield@1422 204 static class CpNull extends CpEntry {
rfield@1422 205 CpNull() { super((byte)0); }
rfield@1422 206 CpNull(CfInputStream in) { super((byte)0); }
rfield@1422 207 void write(CfOutputStream out) {}
rfield@1422 208 }
rfield@1422 209
rfield@1422 210 static class CpUtf8 extends CpEntry {
rfield@1422 211 static final byte TAG = 1;
rfield@1422 212 byte[] bytes;
rfield@1422 213
rfield@1422 214 CpUtf8() { super(TAG); }
rfield@1422 215 CpUtf8(CfInputStream in) {
rfield@1422 216 this();
rfield@1422 217 short length = in.u2();
rfield@1422 218 bytes = in.array(length);
rfield@1422 219 }
rfield@1422 220 void write(CfOutputStream out) {
rfield@1422 221 super.write(out);
rfield@1422 222 out.u2((short)bytes.length);
rfield@1422 223 out.array(bytes);
rfield@1422 224 }
rfield@1422 225 }
rfield@1422 226
rfield@1422 227 static class CpU4Constant extends CpEntry {
rfield@1422 228 byte[] bytes;
rfield@1422 229
rfield@1422 230 CpU4Constant(byte tag) { super(tag); }
rfield@1422 231 CpU4Constant(byte tag, CfInputStream in) {
rfield@1422 232 this(tag);
rfield@1422 233 bytes = in.array(4);
rfield@1422 234 }
rfield@1422 235 void write(CfOutputStream out) { super.write(out); out.array(bytes); }
rfield@1422 236 }
rfield@1422 237 static class CpInteger extends CpU4Constant {
rfield@1422 238 static final byte TAG = 3;
rfield@1422 239 CpInteger() { super(TAG); }
rfield@1422 240 CpInteger(CfInputStream in) { super(TAG, in); }
rfield@1422 241 }
rfield@1422 242 static class CpFloat extends CpU4Constant {
rfield@1422 243 static final byte TAG = 4;
rfield@1422 244 CpFloat() { super(TAG); }
rfield@1422 245 CpFloat(CfInputStream in) { super(TAG, in); }
rfield@1422 246 }
rfield@1422 247
rfield@1422 248 static class CpU8Constant extends CpEntry {
rfield@1422 249 byte[] bytes;
rfield@1422 250
rfield@1422 251 CpU8Constant(byte tag) { super(tag); }
rfield@1422 252 CpU8Constant(byte tag, CfInputStream in) {
rfield@1422 253 this(tag);
rfield@1422 254 bytes = in.array(8);
rfield@1422 255 }
rfield@1422 256 void write(CfOutputStream out) { super.write(out); out.array(bytes); }
rfield@1422 257 }
rfield@1422 258 static class CpLong extends CpU8Constant {
rfield@1422 259 static final byte TAG = 5;
rfield@1422 260 CpLong() { super(TAG); }
rfield@1422 261 CpLong(CfInputStream in) { super(TAG, in); }
rfield@1422 262 }
rfield@1422 263 static class CpDouble extends CpU8Constant {
rfield@1422 264 static final byte TAG = 6;
rfield@1422 265 CpDouble() { super(TAG); }
rfield@1422 266 CpDouble(CfInputStream in) { super(TAG, in); }
rfield@1422 267 }
rfield@1422 268
rfield@1422 269 static class CpClass extends CpEntry {
rfield@1422 270 static final byte TAG = 7;
rfield@1422 271 short name_index;
rfield@1422 272
rfield@1422 273 CpClass() { super(TAG); }
rfield@1422 274 CpClass(CfInputStream in) { super(TAG); name_index = in.u2(); }
rfield@1422 275 void write(CfOutputStream out) {
rfield@1422 276 super.write(out);
rfield@1422 277 out.u2(name_index);
rfield@1422 278 }
rfield@1422 279 }
rfield@1422 280
rfield@1422 281 static class CpString extends CpEntry {
rfield@1422 282 static final byte TAG = 8;
rfield@1422 283 short string_index;
rfield@1422 284
rfield@1422 285 CpString() { super(TAG); }
rfield@1422 286 CpString(CfInputStream in) { super(TAG); string_index = in.u2(); }
rfield@1422 287 void write(CfOutputStream out) {
rfield@1422 288 super.write(out);
rfield@1422 289 out.u2(string_index);
rfield@1422 290 }
rfield@1422 291 }
rfield@1422 292
rfield@1422 293 static class CpRef extends CpEntry {
rfield@1422 294 short class_index;
rfield@1422 295 short name_and_type_index;
rfield@1422 296
rfield@1422 297 CpRef(byte tag) { super(tag); }
rfield@1422 298 CpRef(byte tag, CfInputStream in) {
rfield@1422 299 this(tag);
rfield@1422 300 class_index = in.u2();
rfield@1422 301 name_and_type_index = in.u2();
rfield@1422 302 }
rfield@1422 303 void write(CfOutputStream out) {
rfield@1422 304 super.write(out);
rfield@1422 305 out.u2(class_index);
rfield@1422 306 out.u2(name_and_type_index);
rfield@1422 307 }
rfield@1422 308 }
rfield@1422 309 static class CpFieldRef extends CpRef {
rfield@1422 310 static final byte TAG = 9;
rfield@1422 311 CpFieldRef() { super(TAG); }
rfield@1422 312 CpFieldRef(CfInputStream in) { super(TAG, in); }
rfield@1422 313 }
rfield@1422 314 static class CpMethodRef extends CpRef {
rfield@1422 315 static final byte TAG = 10;
rfield@1422 316 CpMethodRef() { super(TAG); }
rfield@1422 317 CpMethodRef(CfInputStream in) { super(TAG, in); }
rfield@1422 318 }
rfield@1422 319 static class CpInterfaceMethodRef extends CpRef {
rfield@1422 320 static final byte TAG = 11;
rfield@1422 321 CpInterfaceMethodRef() { super(TAG); }
rfield@1422 322 CpInterfaceMethodRef(CfInputStream in) { super(TAG, in); }
rfield@1422 323 }
rfield@1422 324
rfield@1422 325 static class CpNameAndType extends CpEntry {
rfield@1422 326 static final byte TAG = 12;
rfield@1422 327 short name_index;
rfield@1422 328 short descriptor_index;
rfield@1422 329
rfield@1422 330 CpNameAndType() { super(TAG); }
rfield@1422 331 CpNameAndType(CfInputStream in) {
rfield@1422 332 this();
rfield@1422 333 name_index = in.u2();
rfield@1422 334 descriptor_index = in.u2();
rfield@1422 335 }
rfield@1422 336 void write(CfOutputStream out) {
rfield@1422 337 super.write(out);
rfield@1422 338 out.u2(name_index);
rfield@1422 339 out.u2(descriptor_index);
rfield@1422 340 }
rfield@1422 341 }
rfield@1422 342
rfield@1422 343 static class CpMethodHandle extends CpEntry {
rfield@1422 344 static final byte TAG = 15;
rfield@1422 345 byte reference_kind;
rfield@1422 346 short reference_index;
rfield@1422 347
rfield@1422 348 CpMethodHandle() { super(TAG); }
rfield@1422 349 CpMethodHandle(CfInputStream in) {
rfield@1422 350 this();
rfield@1422 351 reference_kind = in.u1();
rfield@1422 352 reference_index = in.u2();
rfield@1422 353 }
rfield@1422 354 void write(CfOutputStream out) {
rfield@1422 355 super.write(out);
rfield@1422 356 out.u1(reference_kind);
rfield@1422 357 out.u2(reference_index);
rfield@1422 358 }
rfield@1422 359 }
rfield@1422 360
rfield@1422 361 static class CpMethodType extends CpEntry {
rfield@1422 362 static final byte TAG = 16;
rfield@1422 363 short descriptor_index;
rfield@1422 364
rfield@1422 365 CpMethodType() { super(TAG); }
rfield@1422 366 CpMethodType(CfInputStream in) {
rfield@1422 367 this();
rfield@1422 368 descriptor_index = in.u2();
rfield@1422 369 }
rfield@1422 370 void write(CfOutputStream out) {
rfield@1422 371 super.write(out);
rfield@1422 372 out.u2(descriptor_index);
rfield@1422 373 }
rfield@1422 374 }
rfield@1422 375
rfield@1422 376 static class CpInvokeDynamic extends CpEntry {
rfield@1422 377 static final byte TAG = 18;
rfield@1422 378 short bootstrap_index;
rfield@1422 379 short name_and_type_index;
rfield@1422 380
rfield@1422 381 CpInvokeDynamic() { super(TAG); }
rfield@1422 382 CpInvokeDynamic(CfInputStream in) {
rfield@1422 383 this();
rfield@1422 384 bootstrap_index = in.u2();
rfield@1422 385 name_and_type_index = in.u2();
rfield@1422 386 }
rfield@1422 387 void write(CfOutputStream out) {
rfield@1422 388 super.write(out);
rfield@1422 389 out.u2(bootstrap_index);
rfield@1422 390 out.u2(name_and_type_index);
rfield@1422 391 }
rfield@1422 392 }
rfield@1422 393
rfield@1422 394 static class Interface {
rfield@1422 395 short index;
rfield@1422 396
rfield@1422 397 Interface() {}
rfield@1422 398 Interface(CfInputStream in) { index = in.u2(); }
rfield@1422 399 void write(CfOutputStream out) { out.u2(index); }
rfield@1422 400 }
rfield@1422 401
rfield@1422 402 static class FieldOrMethod {
rfield@1422 403 short access_flags;
rfield@1422 404 short name_index;
rfield@1422 405 short descriptor_index;
rfield@1422 406 ArrayList<Attribute> attributes;
rfield@1422 407
rfield@1422 408 FieldOrMethod() { attributes = new ArrayList<>(); }
rfield@1422 409 FieldOrMethod(CfInputStream in) {
rfield@1422 410 access_flags = in.u2();
rfield@1422 411 name_index = in.u2();
rfield@1422 412 descriptor_index = in.u2();
rfield@1422 413
rfield@1422 414 short attrCount = in.u2();
rfield@1422 415 attributes = new ArrayList<>();
rfield@1422 416 for (int i = 0; i < attrCount; ++i) {
rfield@1422 417 attributes.add(new Attribute(in));
rfield@1422 418 }
rfield@1422 419 }
rfield@1422 420 void write(CfOutputStream out) {
rfield@1422 421 out.u2(access_flags);
rfield@1422 422 out.u2(name_index);
rfield@1422 423 out.u2(descriptor_index);
rfield@1422 424 out.u2((short)attributes.size());
rfield@1422 425 for (Attribute attribute : attributes) { attribute.write(out); }
rfield@1422 426 }
rfield@1422 427 }
rfield@1422 428
rfield@1422 429 static class Field extends FieldOrMethod {
rfield@1422 430 Field() {}
rfield@1422 431 Field(CfInputStream in) { super(in); }
rfield@1422 432 }
rfield@1422 433 static class Method extends FieldOrMethod {
rfield@1422 434 Method() {}
rfield@1422 435 Method(CfInputStream in) { super(in); }
rfield@1422 436 }
rfield@1422 437
rfield@1422 438 static class Attribute {
rfield@1422 439 short attribute_name_index;
rfield@1422 440 byte[] info;
rfield@1422 441
rfield@1422 442 Attribute() { info = new byte[0]; }
rfield@1422 443 Attribute(CfInputStream in) {
rfield@1422 444 attribute_name_index = in.u2();
rfield@1422 445 int length = in.u4();
rfield@1422 446 info = in.array(length);
rfield@1422 447 }
rfield@1422 448 void write(CfOutputStream out) {
rfield@1422 449 out.u2(attribute_name_index);
rfield@1422 450 out.u4(info.length);
rfield@1422 451 out.array(info);
rfield@1422 452 }
rfield@1422 453 }
rfield@1422 454 }

mercurial