/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Define the structure and ordering of "bands" in a packed file.
* @author John Rose
*/
abstract
class BandStructure {
// Inherit options from Pack200:
// Various heuristic options.
// Local copy of package version.
/** Call this exactly once, early, to specify the archive major version. */
if (this.packageMajver > 0) {
throw new IOException(
"Package majver is already initialized to " + this.packageMajver+
"; new setting is " + packageMajver);
}
this.packageMajver = packageMajver;
}
public int getPackageMajver() {
if (packageMajver < 0) {
throw new RuntimeException("Package majver not yet initialized");
}
return packageMajver;
}
protected BandStructure() {
}
// Note: Tried sharper (3,16) with no post-zip benefit.
// This is best used with BCI values:
// "sharp" (5,64) zips 0.4% better than "medium" (5,128)
// It zips 1.1% better than "flat" (5,192)
// Note: Tried (5,128,2) and (5,192,2) with no benefit.
// Table of "Canonical BHSD Codings" from Pack200 spec.
null, // _meta_default
// Fixed-length codings:
// Full-range variable-length codings:
// Variable length subrange codings:
};
static {
Coding c = basicCodings[i];
if (c == null) continue;
assert(i >= _meta_canon_min);
assert(i <= _meta_canon_max);
}
}
}
if (i == null) return 0;
return i.intValue();
}
return basicCodings.clone();
}
// push back XB onto the band header bytes
// scan forward through XB and any additional band header bytes
res);
return res[0];
}
return pos+1;
}
int pos2;
}
// package writing phases:
// package reading phases:
static boolean phaseIsRead(int p) {
return (p % 2) == 0;
}
}
/** The packed file is divided up into a number of segments.
* Most segments are typed as ValueBand, strongly-typed sequences
* of integer values, all interpreted in a single way.
* A few segments are ByteBands, which hetergeneous sequences
* of bytes.
*
* The two phases for writing a packed file are COLLECT and WRITE.
* 1. When writing a packed file, each band collects
* data in an ad-hoc order.
* 2. At the end, each band is assigned a coding scheme,
* and then all the bands are written in their global order.
*
* The three phases for reading a packed file are EXPECT, READ,
* and DISBURSE.
* 1. For each band, the expected number of integers is determined.
* 2. The data is actually read from the file into the band.
* 3. The band pays out its values as requested, in an ad hoc order.
*
* When the last phase of a band is done, it is marked so (DONE).
* Clearly, these phases must be properly ordered WRT each other.
*/
abstract class Band {
private int valuesExpected;
final public int seqForDebug;
public int elementCountForDebug;
this.regularCoding = regularCoding;
this.seqForDebug = ++nextSeqForDebug;
if (verbose > 2)
// caller must call init
}
// Cannot due this from the constructor, because constructor
// may wish to initialize some subclass variables.
// Set initial phase for reading or writing:
if (isReader)
else
return this;
}
// common operations
/** Return -1 if data buffer not allocated, else max length. */
public abstract int capacity();
/** Allocate data buffer to specified length. */
/** Return current number of values in buffer, which must exist. */
public abstract int length();
protected abstract int valuesRemainingForDebug();
public final int valuesExpected() {
return valuesExpected;
}
/** Write out bytes, encoding the values. */
assert(assertReadyToWriteTo(this, out));
// subclasses continue by writing their contents to output
doneWriting();
}
public final long outputSize() {
if (outputSize >= 0) {
long size = outputSize;
assert(size == computeOutputSize());
return size;
}
return computeOutputSize();
}
protected abstract long computeOutputSize();
/** Expect a certain number of values. */
void expectLength(int l) {
assert(assertPhase(this, EXPECT_PHASE));
assert(l >= 0);
valuesExpected = l;
}
/** Expect more values. (Multiple calls accumulate.) */
void expectMoreLength(int l) {
assert(assertPhase(this, EXPECT_PHASE));
valuesExpected += l;
}
/// Phase change markers.
setCapacity(1);
}
protected void doneWriting() {
assert(assertPhase(this, WRITE_PHASE));
}
}
/** Read in bytes, decoding the values. */
assert(assertReadyToReadFrom(this, in));
// subclasses continue by reading their contents from input:
}
protected void readyToDisburse() {
}
public void doneDisbursing() {
assert(assertPhase(this, DISBURSE_PHASE));
}
public final void doneWithUnusedBand() {
if (isReader) {
assert(assertPhase(this, EXPECT_PHASE));
assert(valuesExpected() == 0);
// Fast forward:
} else {
}
}
}
if (length != 0)
if (elementCountForDebug != 0)
return str;
}
}
private int length;
private int valuesDisbursed;
private byte[] metaCoding;
super(name, regularCoding);
}
public int capacity() {
}
/** Declare predicted or needed capacity. */
}
public int length() {
return length;
}
protected int valuesRemainingForDebug() {
return length - valuesDisbursed;
}
protected int valueAtForDebug(int i) {
return values[i];
}
// Only one use for this.
assert(this == archive_header_S);
assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO);
assert(i < length); // must have already output a dummy
}
assert(assertCanChangeLength(this));
assert(length == 0);
}
/** Collect one value, or store one decoded value. */
protected void addValue(int x) {
assert(assertCanChangeLength(this));
}
private boolean canVaryCoding() {
if (!optVaryCodings) return false;
if (length == 0) return false;
// Can't read band_headers w/o the archive header:
if (this == archive_header_0) return false;
if (this == archive_header_S) return false;
if (this == archive_header_1) return false;
// BYTE1 bands can't vary codings, but the others can.
// All that's needed for the initial escape is at least
// 256 negative values or more than 256 non-negative values
}
private boolean shouldVaryCoding() {
assert(canVaryCoding());
return false;
return true;
}
boolean canVary = canVaryCoding();
if (!canVary || !shouldVaryCoding()) {
} else {
assert(canVary);
if (verbose > 1)
}
outputSize = -1;
} else {
regularCoding, name(),
sizes);
outputSize = -1;
}
// Compute and save the meta-coding bytes also.
if (bandCoding != regularCoding) {
if (verbose > 1) {
}
} else if (canVary &&
// Need an explicit default.
} else {
// Common case: Zero bytes of meta coding.
}
}
}
assert((outputSize < 0) ||
!(bandCoding instanceof Coding) ||
: (bandCoding+" : "+
outputSize+" != "+
);
// Compute outputSize of the escape value X, if any.
// First byte XB of meta-coding is treated specially,
// but any other bytes go into the band headers band.
// This must be done before any other output happens.
if (outputSize >= 0)
// Other bytes go into band_headers.
}
}
}
protected long computeOutputSize() {
outputSize += computeEscapeSize();
return outputSize;
}
protected int computeEscapeSize() {
}
long len0 = 0;
if (out == outputCounter) {
}
// We need an explicit band header, either because
// there is a non-default coding method, or because
// the first value would be parsed as an escape value.
//System.out.println("X="+X+" XB="+XB+" in "+this);
}
if (out == outputCounter) {
}
if (optDumpBands) dumpBand();
}
length = valuesExpected();
if (verbose > 1)
if (!canVaryCoding()) {
} else {
if (XB < 0) {
// Do not consume this value. No alternate coding.
XB = _meta_default;
} else if (XB == _meta_default) {
} else {
if (verbose > 2)
// This is really used only by dumpBands.
int p0 = bandHeaderBytePos0;
int p1 = bandHeaderBytePos;
}
}
if (bandCoding != regularCoding) {
if (verbose > 1)
}
if (optDumpBands) dumpBand();
}
public void doneDisbursing() {
super.doneDisbursing();
}
assert(optDumpBands);
" size="+outputSize()+
if (metaCoding != noMetaCoding) {
}
}
}
}
}
/** Disburse one value. */
protected int getValue() {
assert(phase() == DISBURSE_PHASE);
assert(valuesDisbursed < length);
return values[valuesDisbursed++];
}
/** Reset for another pass over the same value set. */
public void resetForSecondPass() {
assert(phase() == DISBURSE_PHASE);
valuesDisbursed = 0;
}
}
}
public int capacity() {
}
}
public void destroy() {
lengthForDebug = length();
}
public int length() {
}
public void reset() {
}
protected int valuesRemainingForDebug() {
}
// No-op.
}
protected long computeOutputSize() {
// do not cache
}
if (length() == 0) return;
if (optDumpBands) dumpBand();
destroy(); // done with the bits!
}
assert(optDumpBands);
if (bytesForDump != null)
else
}
}
int vex = valuesExpected();
if (vex == 0) return;
if (verbose > 1) {
lengthForDebug = -1;
}
while (vex > 0) {
}
if (optDumpBands) dumpBand();
}
public void readyToDisburse() {
super.readyToDisburse();
}
public void doneDisbursing() {
super.doneDisbursing();
if (optDumpBands
try {
dumpBand();
} catch (IOException ee) {
throw new RuntimeException(ee);
}
}
}
// alternative to readFrom:
assert(assertReadyToReadFrom(this, in));
if (optDumpBands) {
// Tap the stream.
bytesForDump = new ByteArrayOutputStream();
public int read() throws IOException {
return ch;
}
return nr;
}
};
}
super.readyToDisburse();
}
assert(phase() == COLLECT_PHASE);
return bytes;
}
assert(phase() == DISBURSE_PHASE);
return in;
}
int b = getInputStream().read();
if (b < 0) throw new EOFException();
return b;
}
assert(b == (b & 0xFF));
collectorStream().write(b);
}
return "byte "+super.toString();
}
}
super(name, regularCoding);
}
public void putInt(int x) {
assert(phase() == COLLECT_PHASE);
addValue(x);
}
public int getInt() {
return getValue();
}
/** Return the sum of all values in this band. */
public int getIntTotal() {
assert(phase() == DISBURSE_PHASE);
// assert that this is the whole pass; no other reads allowed
assert(valuesRemainingForDebug() == length());
int total = 0;
for (int k = length(); k > 0; k--) {
}
return total;
}
/** Return the occurrence count of a specific value in this band. */
assert(phase() == DISBURSE_PHASE);
// assert that this is the whole pass; no other reads allowed
assert(valuesRemainingForDebug() == length());
int total = 0;
for (int k = length(); k > 0; k--) {
total += 1;
}
}
return total;
}
}
int total = 0;
}
return total;
}
boolean nullOK;
super(name, regularCoding);
if (cpTag != CONSTANT_None)
setBandIndex(this, cpTag);
}
}
}
}
super.readDataFrom(in);
assert(assertValidCPRefs(this));
}
/** Write a constant pool reference. */
}
}
}
}
}
}
int nonNullCode; // NNC is the coding which assumes nulls are rare
if (e == null) {
} else {
}
// If nulls are expected, increment, to make -1 code turn to 0.
}
// Inverse to encodeRefOrNull...
if (nonNullCode == -1) {
return null;
} else {
}
}
}
// Bootstrap support for CPRefBands. These are needed to record
// intended CP indexes, before the CP has been created.
if (verbose > 2)
return coding;
}
if (verbose > 2)
return e;
}
if (codingChooser == null) {
&& this instanceof PackageWriter) {
// Twist the random state based on my first file.
// This sends each segment off in a different direction.
}
}
}
return codingChooser;
}
int[] sizes) {
assert(optVaryCodings);
if (effort <= MIN_EFFORT) {
return regular;
}
}
}
static final byte[] noMetaCoding = {};
// The first value in a band is always coded with the default coding D.
// If this first value X is an escape value, it actually represents the
// first (and perhaps only) byte of a meta-coding.
//
// If D.S != 0 and D includes the range [-256..-1],
// the escape values are in that range,
// and the first byte XB is -1-X.
//
// If D.S == 0 and D includes the range [(D.L)..(D.L)+255],
// the escape values are in that range,
// and XB is X-(D.L).
//
// This representation is designed so that a band header is unlikely
// to be confused with the initial value of a headerless band,
// and yet so that a band header is likely to occupy only a byte or two.
//
// Result is in [0..255] if XB was successfully extracted, else -1.
// See section "Coding Specifier Meta-Encoding" in the JSR 200 spec.
// The first value in a band is always coded with the default coding D.
// If this first value X is an escape value, it actually represents the
// first (and perhaps only) byte of a meta-coding.
// Result is in [0..255] if XB was successfully extracted, else -1.
return -1; // degenerate regular coding (BYTE1)
if (regularCoding.S() != 0) {
int XB = -1-X;
return XB;
}
} else {
int L = regularCoding.L();
int XB = X-L;
return XB;
}
}
return -1; // negative value for failure
}
// Inverse to decodeEscapeValue().
int X;
if (regularCoding.S() != 0) {
X = -1-XB;
} else {
int L = regularCoding.L();
X = XB+L;
}
return X;
}
static {
boolean checkXB = false;
assert(checkXB = true);
if (checkXB) {
Coding D = basicCodings[i];
if (D == null) continue;
if (D.B() == 1) continue;
if (D.L() == 0) continue;
// The following exercises decodeEscapeValue also:
encodeEscapeValue(XB, D);
}
}
}
}
super(name, regularCoding);
}
super.init();
// This is all just to keep the asserts happy:
setCapacity(0);
if (phase() == EXPECT_PHASE) {
// Fast forward:
}
return this;
}
int size() {
return bandCount;
}
assert(i < bandCount);
return bands[i];
}
}
}
}
return b;
}
return b;
}
return b;
}
return b;
}
return b;
}
byte cpTag) {
return b;
}
return b;
}
// coding decision pass
for (int i = 0; i < bandCount; i++) {
b.chooseBandCodings();
}
}
protected long computeOutputSize() {
// coding decision pass
long sum = 0;
for (int i = 0; i < bandCount; i++) {
long bsize = b.outputSize();
assert(bsize >= 0) : b;
}
// do not cache
return sum;
}
long preCount = 0;
for (int i = 0; i < bandCount; i++) {
if (outputCounter != null) {
}
}
}
}
assert(false); // not called?
for (int i = 0; i < bandCount; i++) {
}
}
}
}
}
/**
* An output stream which counts the number of bytes written.
*/
private static
// (should go public under the name CountingOutputStream?)
private long count;
super(out);
}
count++;
}
}
}
}
// Wrap a byte-counter around the output stream.
out = outputCounter;
if (verbose > 0) {
}
}
// random AO_XXX bits, decoded from the archive header
protected int archiveOptions;
// archiveSize1 sizes most of the archive [archive_options..file_bits).
// Length contributions from optional header fields:
// Common structure of attribute band groups:
switch (which) {
case AB_FLAGS_HI:
case AB_FLAGS_LO:
case AB_ATTR_COUNT:
case AB_ATTR_INDEXES:
case AB_ATTR_CALLS:
default:
assert(false); break;
}
return b;
}
static private final boolean NULL_IS_OK = true;
// file header (various random bytes)
// constant pool contents
CPRefBand cp_Signature_classes = cp_bands.newCPRefBand("cp_Signature_classes", UDELTA5, CONSTANT_Class);
CPRefBand cp_Imethod_desc = cp_bands.newCPRefBand("cp_Imethod_desc", UDELTA5, CONSTANT_NameandType);
// bands for carrying attribute definitions:
CPRefBand attr_definition_name = attr_definition_bands.newCPRefBand("attr_definition_name", CONSTANT_Utf8);
CPRefBand attr_definition_layout = attr_definition_bands.newCPRefBand("attr_definition_layout", CONSTANT_Utf8);
// bands for hardwired InnerClasses attribute (shared across the package)
// These bands contain data only where flags sets ACC_IC_LONG_FORM:
CPRefBand ic_outer_class = ic_bands.newCPRefBand("ic_outer_class", DELTA5, CONSTANT_Class, NULL_IS_OK);
// bands for carrying class schema information:
// bands for class members
// bands for predefined field attributes
CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_Literal);
CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand("field_Signature_RS", CONSTANT_Signature);
MultiBand field_metadata_bands = field_attr_bands.newMultiBand("(field_metadata_bands)", UNSIGNED5);
// band for predefined method attributes
CPRefBand method_Exceptions_RC = method_attr_bands.newCPRefBand("method_Exceptions_RC", CONSTANT_Class);
CPRefBand method_Signature_RS = method_attr_bands.newCPRefBand("method_Signature_RS", CONSTANT_Signature);
MultiBand method_metadata_bands = method_attr_bands.newMultiBand("(method_metadata_bands)", UNSIGNED5);
// band for predefined SourceFile and other class attributes
CPRefBand class_SourceFile_RUN = class_attr_bands.newCPRefBand("class_SourceFile_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
CPRefBand class_EnclosingMethod_RC = class_attr_bands.newCPRefBand("class_EnclosingMethod_RC", CONSTANT_Class);
CPRefBand class_EnclosingMethod_RDN = class_attr_bands.newCPRefBand("class_EnclosingMethod_RDN", UNSIGNED5, CONSTANT_NameandType, NULL_IS_OK);
CPRefBand class_Signature_RS = class_attr_bands.newCPRefBand("class_Signature_RS", CONSTANT_Signature);
MultiBand class_metadata_bands = class_attr_bands.newMultiBand("(class_metadata_bands)", UNSIGNED5);
CPRefBand class_InnerClasses_RC = class_attr_bands.newCPRefBand("class_InnerClasses_RC", CONSTANT_Class);
CPRefBand class_InnerClasses_outer_RCN = class_attr_bands.newCPRefBand("class_InnerClasses_outer_RCN", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
CPRefBand class_InnerClasses_name_RUN = class_attr_bands.newCPRefBand("class_InnerClasses_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
IntBand class_ClassFile_version_minor_H = class_attr_bands.newIntBand("class_ClassFile_version_minor_H");
IntBand class_ClassFile_version_major_H = class_attr_bands.newIntBand("class_ClassFile_version_major_H");
CPRefBand code_handler_class_RCN = code_bands.newCPRefBand("code_handler_class_RCN", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
IntBand code_StackMapTable_offset = stackmap_bands.newIntBand("code_StackMapTable_offset", UNSIGNED5);
CPRefBand code_StackMapTable_RC = stackmap_bands.newCPRefBand("code_StackMapTable_RC", CONSTANT_Class);
// bands for predefined LineNumberTable attribute
IntBand code_LineNumberTable_bci_P = code_attr_bands.newIntBand("code_LineNumberTable_bci_P", BCI5);
// bands for predefined LocalVariable{Type}Table attributes
IntBand code_LocalVariableTable_bci_P = code_attr_bands.newIntBand("code_LocalVariableTable_bci_P", BCI5);
IntBand code_LocalVariableTable_span_O = code_attr_bands.newIntBand("code_LocalVariableTable_span_O", BRANCH5);
CPRefBand code_LocalVariableTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTable_name_RU", CONSTANT_Utf8);
CPRefBand code_LocalVariableTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTable_type_RS", CONSTANT_Signature);
IntBand code_LocalVariableTypeTable_N = code_attr_bands.newIntBand("code_LocalVariableTypeTable_N");
IntBand code_LocalVariableTypeTable_bci_P = code_attr_bands.newIntBand("code_LocalVariableTypeTable_bci_P", BCI5);
IntBand code_LocalVariableTypeTable_span_O = code_attr_bands.newIntBand("code_LocalVariableTypeTable_span_O", BRANCH5);
CPRefBand code_LocalVariableTypeTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_name_RU", CONSTANT_Utf8);
CPRefBand code_LocalVariableTypeTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_type_RS", CONSTANT_Signature);
IntBand code_LocalVariableTypeTable_slot = code_attr_bands.newIntBand("code_LocalVariableTypeTable_slot");
// bands for bytecodes
// remaining bands provide typed opcode fields required by the bc_codes
// Most CP refs exhibit some correlation, and benefit from delta coding.
// The notable exceptions are class and method references.
// ldc* operands:
// nulls produced by bc_classref are taken to mean the current class
CPRefBand bc_classref = bc_bands.newCPRefBand("bc_classref", UNSIGNED5, CONSTANT_Class, NULL_IS_OK); // new, *anew*, c*cast, i*of, ldc
CPRefBand bc_fieldref = bc_bands.newCPRefBand("bc_fieldref", DELTA5, CONSTANT_Fieldref); // get*, put*
CPRefBand bc_imethodref = bc_bands.newCPRefBand("bc_imethodref", DELTA5, CONSTANT_InterfaceMethodref); // invokeinterface
// _self_linker_op family
CPRefBand bc_thisfield = bc_bands.newCPRefBand("bc_thisfield", CONSTANT_None); // any field within cur. class
CPRefBand bc_superfield = bc_bands.newCPRefBand("bc_superfield", CONSTANT_None); // any field within superclass
CPRefBand bc_thismethod = bc_bands.newCPRefBand("bc_thismethod", CONSTANT_None); // any method within cur. class
CPRefBand bc_supermethod = bc_bands.newCPRefBand("bc_supermethod", CONSTANT_None); // any method within superclass
// bc_invokeinit family:
// escapes
// bands for carrying resource files and file attributes:
// End of band definitions!
/** Given CP indexes, distribute tag-specific indexes to bands. */
protected void setBandIndexes() {
// Handle prior calls to setBandIndex:
}
if (verbose > 3) {
}
}
if (which == CONSTANT_Literal) {
// I.e., attribute layouts KQ (no null) or KQN (null ok).
allKQBands.add(b);
} else if (needPredefIndex != null) {
} else {
// Not in predefinition mode; getCPIndex now works.
}
}
if (f != null) {
byte tag = f.getLiteralTag();
if (verbose > 2)
}
// Typically, allKQBands is the singleton of field_ConstantValue_KQ.
}
}
// Table of bands which contain metadata.
{
}
// Attribute layouts.
// Each index limit is either 32 or 63, depending on AO_HAVE_XXX_FLAGS_HI.
// Which flag bits are taken over by attributes?
// Which flag bits have been taken over explicitly?
// What pseudo-attribute bits are there to watch for?
protected int attrClassFileVersionMask;
// Mapping from Attribute.Layout to Band[] (layout element bands).
// Well-known attributes:
// Mapping from Attribute.Layout to Integer (inverse of attrDefs)
// Mapping from attribute index (<32 are flag bits) to attributes.
new FixedList<>(ATTR_CONTEXT_LIMIT);
{
for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
assert(attrIndexLimit[i] == 0);
}
// Add predefined attribute definitions:
"InnerClasses", "");
new Band[] { class_SourceFile_RUN },
"SourceFile", "RUNH");
new Band[] {
},
"EnclosingMethod", "RCHRDNH");
new Band[] {
},
".ClassFile.version", "HH");
new Band[] { class_Signature_RS },
"Signature", "RSH");
"Deprecated", "");
//predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null,
// "Synthetic", "");
".Overflow", "");
new Band[] { field_ConstantValue_KQ },
"ConstantValue", "KQH");
new Band[] { field_Signature_RS },
"Signature", "RSH");
"Deprecated", "");
//predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null,
// "Synthetic", "");
".Overflow", "");
"Code", "");
new Band[] {
},
"Exceptions", "NH[RCH]");
new Band[] { method_Signature_RS },
"Signature", "RSH");
"Deprecated", "");
//predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null,
// "Synthetic", "");
".Overflow", "");
if (xxx_metadata_bands == null)
continue; // no code attrs
// These arguments cause the bands to be built
// automatically for this complicated layout:
"RuntimeVisibleAnnotations"));
"RuntimeInvisibleAnnotations"));
if (ctype != ATTR_CONTEXT_METHOD)
continue;
"method_RVPA_", xxx_metadata_bands,
"RuntimeVisibleParameterAnnotations"));
"method_RIPA_", xxx_metadata_bands,
"RuntimeInvisibleParameterAnnotations"));
"method_AD_", xxx_metadata_bands,
"AnnotationDefault"));
}
new Band[] {
},
"LineNumberTable", "NH[PHH]");
new Band[] {
},
"LocalVariableTable", "NH[PHOHRUHRSHH]");
new Band[] {
},
"LocalVariableTypeTable", "NH[PHOHRUHRSHH]");
".Overflow", "");
// Clear the record of having seen these definitions,
// so they may be redefined without error.
for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
attrDefSeen[i] = 0;
}
// Set up the special masks:
for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
}
}
private void adjustToMajver() {
if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) {
// Revoke definition of pre-1.6 attribute type.
}
}
protected void initAttrIndexLimit() {
for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
}
}
switch (ctype) {
case ATTR_CONTEXT_CLASS:
assert(mask == AO_HAVE_CLASS_FLAGS_HI); break;
case ATTR_CONTEXT_FIELD:
assert(mask == AO_HAVE_FIELD_FLAGS_HI); break;
case ATTR_CONTEXT_METHOD:
assert(mask == AO_HAVE_METHOD_FLAGS_HI); break;
case ATTR_CONTEXT_CODE:
assert(mask == AO_HAVE_CODE_FLAGS_HI); break;
default:
assert(false);
}
}
// Remove nulls and non-predefs.
}
return res;
}
// Overflow attrs are never predefined.
// If the bit is set, it was explicitly def'd.
}
protected void adjustSpecialAttrMasks() {
// Clear special masks if new definitions have been seen for them.
// It is possible to clear the overflow mask (bit 16).
for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
attrOverflowMask[i] &= ~ attrDefSeen[i];
}
}
byte[] bytes = {
};
}
}
}
return true;
}
boolean wantIntBand = true;
switch (e.kind) {
} else if (e.len == 1) {
}
break;
} else {
}
break;
break;
break;
break;
} else if (e.len == 1) {
}
break;
assert(b == null);
return true; // no direct band
assert(b == null);
return true; // no direct band
assert(b == null);
return true; // no direct band
wantIntBand = false;
assert(b instanceof CPRefBand);
break;
default: assert(false);
}
assert(b.regularCoding == rc)
: (e+" // "+b);
if (wantIntBand)
assert(b instanceof IntBand);
return true;
}
private
// Use Attribute.find to get uniquification of layouts.
//def.predef = true;
if (index >= 0) {
}
}
// Let's make sure the band types match:
return def;
}
// This version takes bandPrefix/addHere instead of prebuilt Band[] ab.
private
//Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
addHere),
}
private
if (verbose > 1) {
" attribute on bit "+index);
}
// Clear the def bit. (For predefs, it's already clear.)
assert(index < 64);
ab[j].doneWithUnusedBand();
}
}
// Bands which contain non-predefined attrs.
{
}
// Create bands for all non-predefined attrs.
void makeNewAttributeBands() {
// Retract special flag bit bindings, if they were taken over.
// Note: attrDefSeen is always a subset of attrFlagMask.
// There are already predefined bands here.
continue;
}
if (verbose > 1)
// We won't be using these predefined bands.
prevAB[j].doneWithUnusedBand();
}
}
}
}
//System.out.println(prevForAssertMap);
}
private
for (int i = 0; i < nb; i++) {
}
return newAB;
}
// Recursive helper, operates on a "body" or other sequence of elems:
private
{
int tem;
}
switch (e.kind) {
break;
// PH: transmit R(bci), store bci
} else {
// POH: transmit D(R(bci)), store bci
}
// Note: No case for BYTE1 here.
break;
// OH: transmit D(R(bci)), store D(bci)
// Note: No case for BYTE1 here.
break;
break;
break;
break;
// If it's not a duplicate body, make the bands.
}
continue; // no new band to make
// Note: No case for BYTE1 here.
break;
continue; // no new band to make
continue; // no new band to make
default: assert(false); continue;
}
if (verbose > 1) {
}
}
}
private
} else if (e.len == 1) {
} else {
}
}
if (index == ATTR_INDEX_OVERFLOW) {
// Overflow attribute.
if (verbose > 0)
return index;
}
// Detect redefinitions:
}
// Adding a new fixed attribute.
+": "+def
// Remove index binding of any previous fixed attr.
return index;
}
// encodings found in the code_headers band
private static final int[][] shortCodeLimits = {
{ 12, 12 }, // s<12, l<12, e=0 [1..144]
{ 8, 8 }, // s<8, l<8, e=1 [145..208]
{ 7, 7 }, // s<7, l<7, e=2 [209..256]
};
// return 0 if it won't encode, else a number in [1..255]
int sc = shortCodeHeader_h_base(h);
assert(shortCodeHeader_max_stack(sc) == s);
assert(shortCodeHeader_handler_count(sc) == h);
return sc;
}
for (int h = 0; ; h++) {
return h;
}
}
int h = shortCodeHeader_handler_count(sc);
}
int h = shortCodeHeader_handler_count(sc);
}
private static int shortCodeHeader_h_base(int h) {
assert(h <= shortCodeLimits.length);
int sc = 1;
}
return sc;
}
// utilities for accessing the bc_label band:
}
}
case CONSTANT_Class:
return bc_classref;
case CONSTANT_Fieldref:
return bc_fieldref;
case CONSTANT_Methodref:
return bc_methodref;
return bc_imethodref;
case CONSTANT_Literal:
switch (bc) {
return bc_intref;
return bc_floatref;
case _lldc2_w:
return bc_longref;
case _dldc2_w:
return bc_doubleref;
return bc_stringref;
return bc_classref;
}
break;
}
assert(false);
return null;
}
if (!isSuper)
else
}
////////////////////////////////////////////////////////////////////
static int nextSeqForDebug;
}
}
}
}
// DEBUG ONLY: Validate me at each length change.
switch (b.phase) {
case COLLECT_PHASE:
case READ_PHASE:
return true;
}
return false;
}
// DEBUG ONLY: Validate a phase.
if (b.phase() != phaseExpected) {
return false;
}
return true;
}
// DEBUG ONLY: Tells whether verbosity is turned on.
static int verbose() {
}
// DEBUG ONLY: Validate me at each phase change.
/// Writing phases:
// Ready to collect data from the input classes.
assert(!b.isReader());
assert(b.capacity() >= 0);
assert(b.length() == 0);
return true;
assert(b.length() == 0);
return true;
// Data is all collected. Ready to write bytes to disk.
return true;
// Done writing to disk. Ready to reset, in principle.
return true;
/// Reading phases:
assert(b.isReader());
assert(b.capacity() < 0);
return true;
// Ready to read values from disk.
assert(b.length() <= 0);
return true;
// Ready to disburse values.
assert(b.valuesRemainingForDebug() == b.length());
return true;
// Done disbursing values. Ready to reset, in principle.
assert(assertDoneDisbursing(b));
return true;
}
else
return false;
}
if (b.phase != DISBURSE_PHASE) {
}
int left = b.valuesRemainingForDebug();
if (left > 0) {
}
if (b instanceof MultiBand) {
}
}
}
return true;
}
if (b instanceof MultiBand) {
}
return;
}
if (b instanceof CPRefBand) {
}
"UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" };
if (rci >= 0)
else
}
// DEBUG ONLY: Record something about the band order.
if (prevForAssertMap == null)
prevForAssertMap = new HashMap<>();
prevForAssertMap.put(b, p);
return true;
}
// DEBUG ONLY: Validate next input band.
// Any previous band must be done reading before this one starts.
}
// Verify synchronization between reader & writer:
int ch;
}
}
return false;
}
}
return true;
}
// DEBUG ONLY: Make sure a bunch of cprefs are correct.
for (int i = 0; i < b.length(); i++) {
int v = b.valueAtForDebug(i);
if (v < 0 || v >= limit) {
"["+i+"] = "+v+" in "+b);
return false;
}
}
return true;
}
// DEBUG ONLY: Maybe write a debugging cookie to next output band.
// Any previous band must be done writing before this one starts.
}
// Verify synchronization between reader & writer:
}
}
return true;
}
}
}
}
}
for (int i = 0; i < len; i++) {
if (i % 10 == 0)
else
}
}
for (int i = 0; i < len; i++) {
for (int j = 0; j < s.length(); j++) {
} else if (ch == '\n') {
} else if (ch == '\t') {
} else if (ch == '\r') {
} else {
}
}
}
}
// Utilities for reallocating:
return na;
}
}
return na;
}
protected static int[] realloc(int[] a) {
}
return na;
}
protected static byte[] realloc(byte[] a) {
}
}