8335939: Hide element writing across the ClassFile API
Reviewed-by: asotona
This commit is contained in:
parent
e83b4b236e
commit
a2a236f904
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -51,7 +51,6 @@ import jdk.internal.javac.PreviewFeature;
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface Annotation
|
||||
extends WritableElement<Annotation>
|
||||
permits TypeAnnotation, AnnotationImpl {
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,7 +41,6 @@ import jdk.internal.javac.PreviewFeature;
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface AnnotationElement
|
||||
extends WritableElement<AnnotationElement>
|
||||
permits AnnotationImpl.AnnotationElementImpl {
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -49,7 +49,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
* @since 22
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface AnnotationValue extends WritableElement<AnnotationValue>
|
||||
public sealed interface AnnotationValue
|
||||
permits AnnotationValue.OfAnnotation, AnnotationValue.OfArray,
|
||||
AnnotationValue.OfConstant, AnnotationValue.OfClass,
|
||||
AnnotationValue.OfEnum {
|
||||
|
@ -80,7 +80,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface Attribute<A extends Attribute<A>>
|
||||
extends WritableElement<A>
|
||||
extends ClassFileElement
|
||||
permits AnnotationDefaultAttribute, BootstrapMethodsAttribute,
|
||||
CharacterRangeTableAttribute, CodeAttribute, CompilationIDAttribute,
|
||||
ConstantValueAttribute, DeprecatedAttribute, EnclosingMethodAttribute,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,7 +43,6 @@ import jdk.internal.javac.PreviewFeature;
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface BootstrapMethodEntry
|
||||
extends WritableElement<BootstrapMethodEntry>
|
||||
permits BootstrapMethodEntryImpl {
|
||||
|
||||
/**
|
||||
|
@ -24,8 +24,6 @@
|
||||
*/
|
||||
package java.lang.classfile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import java.lang.classfile.constantpool.ConstantPool;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
import java.lang.classfile.constantpool.PoolEntry;
|
||||
@ -110,13 +108,6 @@ public sealed interface BufWriter
|
||||
*/
|
||||
void writeBytes(byte[] arr);
|
||||
|
||||
/**
|
||||
* Write the contents of another {@link BufWriter} to the buffer
|
||||
*
|
||||
* @param other the other {@linkplain BufWriter}
|
||||
*/
|
||||
void writeBytes(BufWriter other);
|
||||
|
||||
/**
|
||||
* Write a range of a byte array to the buffer
|
||||
*
|
||||
@ -166,38 +157,8 @@ public sealed interface BufWriter
|
||||
*/
|
||||
void writeIndexOrZero(PoolEntry entry);
|
||||
|
||||
/**
|
||||
* Write a list of entities to the buffer. The length of the list is
|
||||
* written as a {@code u2}, followed by the bytes corresponding to each
|
||||
* element in the list. Writing of the entities is delegated to the entry.
|
||||
*
|
||||
* @param list the entities
|
||||
* @param <T> the type of entity
|
||||
*/
|
||||
<T extends WritableElement<?>> void writeList(List<T> list);
|
||||
|
||||
/**
|
||||
* Write a list of constant pool entry indexes to the buffer. The length
|
||||
* of the list is written as a {@code u2}, followed by a {@code u2} for each
|
||||
* entry in the list.
|
||||
*
|
||||
* @param list the list of entries
|
||||
* @throws IllegalArgumentException if any entry has invalid index
|
||||
*/
|
||||
void writeListIndices(List<? extends PoolEntry> list);
|
||||
|
||||
/**
|
||||
* {@return the number of bytes that have been written to the buffer}
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Copy the contents of the buffer into a byte array.
|
||||
*
|
||||
* @param array the byte array
|
||||
* @param bufferOffset the offset into the array at which to write the
|
||||
* contents of the buffer
|
||||
* @throws IndexOutOfBoundsException if copying outside of the array bounds
|
||||
*/
|
||||
void copyTo(byte[] array, int bufferOffset);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,6 +39,6 @@ import jdk.internal.javac.PreviewFeature;
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface ClassFileElement
|
||||
permits AttributedElement, CompoundElement, WritableElement,
|
||||
permits AttributedElement, CompoundElement, Attribute,
|
||||
ClassElement, CodeElement, FieldElement, MethodElement {
|
||||
}
|
||||
|
@ -189,19 +189,4 @@ public sealed interface ClassReader extends ConstantPool
|
||||
* @param len the length of the range
|
||||
*/
|
||||
void copyBytesTo(BufWriter buf, int offset, int len);
|
||||
|
||||
/**
|
||||
* Compare a range of bytes from the classfile to a range of bytes within
|
||||
* a {@link BufWriter}.
|
||||
*
|
||||
* @param bufWriter the {@linkplain BufWriter}
|
||||
* @param bufWriterOffset the offset within the {@linkplain BufWriter}
|
||||
* @param classReaderOffset the offset within the classfile
|
||||
* @param length the length of the range
|
||||
* @return whether the two ranges were identical
|
||||
*/
|
||||
boolean compare(BufWriter bufWriter,
|
||||
int bufWriterOffset,
|
||||
int classReaderOffset,
|
||||
int length);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -59,12 +59,6 @@ public abstract non-sealed class CustomAttribute<T extends CustomAttribute<T>>
|
||||
return mapper.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void writeTo(BufWriter buf) {
|
||||
mapper.writeAttribute(buf, (T) this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("CustomAttribute[name=%s]", mapper.name());
|
||||
|
@ -42,7 +42,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface FieldModel
|
||||
extends WritableElement<FieldModel>, CompoundElement<FieldElement>, AttributedElement, ClassElement
|
||||
extends CompoundElement<FieldElement>, AttributedElement, ClassElement
|
||||
permits BufferedFieldBuilder.Model, FieldImpl {
|
||||
|
||||
/** {@return the access flags} */
|
||||
|
@ -42,7 +42,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface MethodModel
|
||||
extends WritableElement<MethodModel>, CompoundElement<MethodElement>, AttributedElement, ClassElement
|
||||
extends CompoundElement<MethodElement>, AttributedElement, ClassElement
|
||||
permits BufferedMethodBuilder.Model, MethodImpl {
|
||||
|
||||
/** {@return the access flags} */
|
||||
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
package java.lang.classfile;
|
||||
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
import java.lang.classfile.constantpool.PoolEntry;
|
||||
import jdk.internal.classfile.impl.DirectFieldBuilder;
|
||||
import jdk.internal.classfile.impl.DirectMethodBuilder;
|
||||
import jdk.internal.javac.PreviewFeature;
|
||||
|
||||
/**
|
||||
* A classfile element that can encode itself as a stream of bytes in the
|
||||
* encoding expected by the classfile format.
|
||||
*
|
||||
* @param <T> the type of the entity
|
||||
*
|
||||
* @sealedGraph
|
||||
* @since 22
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface WritableElement<T> extends ClassFileElement
|
||||
permits Annotation, AnnotationElement, AnnotationValue, Attribute,
|
||||
PoolEntry, BootstrapMethodEntry, FieldModel, MethodModel,
|
||||
ConstantPoolBuilder, DirectFieldBuilder, DirectMethodBuilder {
|
||||
/**
|
||||
* Writes the element to the specified writer
|
||||
*
|
||||
* @param buf the writer
|
||||
*/
|
||||
void writeTo(BufWriter buf);
|
||||
}
|
@ -33,13 +33,11 @@ import java.lang.constant.MethodTypeDesc;
|
||||
import java.util.List;
|
||||
|
||||
import java.lang.classfile.BootstrapMethodEntry;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassBuilder;
|
||||
import java.lang.classfile.ClassModel;
|
||||
import jdk.internal.classfile.impl.ClassReaderImpl;
|
||||
import java.lang.constant.ModuleDesc;
|
||||
import java.lang.constant.PackageDesc;
|
||||
import java.lang.classfile.WritableElement;
|
||||
import jdk.internal.classfile.impl.AbstractPoolEntry.ClassEntryImpl;
|
||||
import jdk.internal.classfile.impl.AbstractPoolEntry.NameAndTypeEntryImpl;
|
||||
import jdk.internal.classfile.impl.SplitConstantPool;
|
||||
@ -61,7 +59,7 @@ import static java.util.Objects.requireNonNull;
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface ConstantPoolBuilder
|
||||
extends ConstantPool, WritableElement<ConstantPool>
|
||||
extends ConstantPool
|
||||
permits SplitConstantPool, TemporaryConstantPool {
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,6 @@
|
||||
*/
|
||||
package java.lang.classfile.constantpool;
|
||||
|
||||
import java.lang.classfile.WritableElement;
|
||||
import jdk.internal.javac.PreviewFeature;
|
||||
|
||||
/**
|
||||
@ -34,7 +33,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
* @since 22
|
||||
*/
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface PoolEntry extends WritableElement<PoolEntry>
|
||||
public sealed interface PoolEntry
|
||||
permits AnnotationConstantValueEntry, DynamicConstantPoolEntry,
|
||||
LoadableConstantEntry, MemberRefEntry, ModuleEntry, NameAndTypeEntry,
|
||||
PackageEntry {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,9 +24,6 @@
|
||||
*/
|
||||
package java.lang.classfile.instruction;
|
||||
|
||||
import java.lang.constant.ClassDesc;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.classfile.CodeElement;
|
||||
import java.lang.classfile.CodeModel;
|
||||
@ -34,6 +31,8 @@ import java.lang.classfile.Label;
|
||||
import java.lang.classfile.PseudoInstruction;
|
||||
import java.lang.classfile.attribute.LocalVariableTableAttribute;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
import java.lang.constant.ClassDesc;
|
||||
|
||||
import jdk.internal.classfile.impl.AbstractPseudoInstruction;
|
||||
import jdk.internal.classfile.impl.BoundLocalVariable;
|
||||
import jdk.internal.classfile.impl.TemporaryConstantPool;
|
||||
@ -84,14 +83,6 @@ public sealed interface LocalVariable extends PseudoInstruction
|
||||
*/
|
||||
Label endScope();
|
||||
|
||||
/**
|
||||
* Writes the local variable to the specified writer
|
||||
*
|
||||
* @param buf the writer
|
||||
* @return true if the variable has been written
|
||||
*/
|
||||
boolean writeTo(BufWriter buf);
|
||||
|
||||
/**
|
||||
* {@return a local variable pseudo-instruction}
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,6 @@
|
||||
*/
|
||||
package java.lang.classfile.instruction;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.classfile.CodeElement;
|
||||
import java.lang.classfile.CodeModel;
|
||||
@ -33,6 +32,7 @@ import java.lang.classfile.PseudoInstruction;
|
||||
import java.lang.classfile.Signature;
|
||||
import java.lang.classfile.attribute.LocalVariableTypeTableAttribute;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
import jdk.internal.classfile.impl.AbstractPseudoInstruction;
|
||||
import jdk.internal.classfile.impl.BoundLocalVariableType;
|
||||
import jdk.internal.classfile.impl.TemporaryConstantPool;
|
||||
@ -81,14 +81,6 @@ public sealed interface LocalVariableType extends PseudoInstruction
|
||||
*/
|
||||
Label endScope();
|
||||
|
||||
/**
|
||||
* Writes the local variable to the specified writer
|
||||
*
|
||||
* @param buf the writer
|
||||
* @return true if the variable has been written
|
||||
*/
|
||||
boolean writeTo(BufWriter buf);
|
||||
|
||||
/**
|
||||
* {@return a local variable type pseudo-instruction}
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -101,7 +101,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, AnnotationDefaultAttribute attr) {
|
||||
attr.defaultValue().writeTo(buf);
|
||||
AnnotationReader.writeAnnotationValue((BufWriterImpl) buf, attr.defaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +119,11 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, BootstrapMethodsAttribute attr) {
|
||||
buf.writeList(attr.bootstrapMethods());
|
||||
var b = (BufWriterImpl) buf;
|
||||
b.writeU2(attr.bootstrapMethodsSize());
|
||||
for (var bsm : attr.bootstrapMethods()) {
|
||||
((BootstrapMethodEntryImpl) bsm).writeTo(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +258,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, ExceptionsAttribute attr) {
|
||||
buf.writeListIndices(attr.exceptions());
|
||||
Util.writeListIndices(buf, attr.exceptions());
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,19 +412,19 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
for (ModuleExportInfo export : attr.exports()) {
|
||||
buf.writeIndex(export.exportedPackage());
|
||||
buf.writeU2(export.exportsFlagsMask());
|
||||
buf.writeListIndices(export.exportsTo());
|
||||
Util.writeListIndices(buf, export.exportsTo());
|
||||
}
|
||||
buf.writeU2(attr.opens().size());
|
||||
for (ModuleOpenInfo open : attr.opens()) {
|
||||
buf.writeIndex(open.openedPackage());
|
||||
buf.writeU2(open.opensFlagsMask());
|
||||
buf.writeListIndices(open.opensTo());
|
||||
Util.writeListIndices(buf, open.opensTo());
|
||||
}
|
||||
buf.writeListIndices(attr.uses());
|
||||
Util.writeListIndices(buf, attr.uses());
|
||||
buf.writeU2(attr.provides().size());
|
||||
for (ModuleProvideInfo provide : attr.provides()) {
|
||||
buf.writeIndex(provide.provides());
|
||||
buf.writeListIndices(provide.providesWith());
|
||||
Util.writeListIndices(buf, provide.providesWith());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -482,7 +486,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, ModulePackagesAttribute attr) {
|
||||
buf.writeListIndices(attr.packages());
|
||||
Util.writeListIndices(buf, attr.packages());
|
||||
}
|
||||
}
|
||||
|
||||
@ -554,7 +558,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, NestMembersAttribute attr) {
|
||||
buf.writeListIndices(attr.nestMembers());
|
||||
Util.writeListIndices(buf, attr.nestMembers());
|
||||
}
|
||||
}
|
||||
|
||||
@ -572,7 +576,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, PermittedSubclassesAttribute attr) {
|
||||
buf.writeListIndices(attr.permittedSubclasses());
|
||||
Util.writeListIndices(buf, attr.permittedSubclasses());
|
||||
}
|
||||
}
|
||||
|
||||
@ -595,7 +599,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
for (RecordComponentInfo info : components) {
|
||||
buf.writeIndex(info.name());
|
||||
buf.writeIndex(info.descriptor());
|
||||
buf.writeList(info.attributes());
|
||||
Util.writeAttributes((BufWriterImpl) buf, info.attributes());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -614,7 +618,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, RuntimeInvisibleAnnotationsAttribute attr) {
|
||||
buf.writeList(attr.annotations());
|
||||
AnnotationReader.writeAnnotations(buf, attr.annotations());
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,7 +639,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
List<List<Annotation>> lists = attr.parameterAnnotations();
|
||||
buf.writeU1(lists.size());
|
||||
for (List<Annotation> list : lists)
|
||||
buf.writeList(list);
|
||||
AnnotationReader.writeAnnotations(buf, list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -653,7 +657,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, RuntimeInvisibleTypeAnnotationsAttribute attr) {
|
||||
buf.writeList(attr.annotations());
|
||||
AnnotationReader.writeAnnotations(buf, attr.annotations());
|
||||
}
|
||||
}
|
||||
|
||||
@ -671,7 +675,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, RuntimeVisibleAnnotationsAttribute attr) {
|
||||
buf.writeList(attr.annotations());
|
||||
AnnotationReader.writeAnnotations(buf, attr.annotations());
|
||||
}
|
||||
}
|
||||
|
||||
@ -692,7 +696,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
List<List<Annotation>> lists = attr.parameterAnnotations();
|
||||
buf.writeU1(lists.size());
|
||||
for (List<Annotation> list : lists)
|
||||
buf.writeList(list);
|
||||
AnnotationReader.writeAnnotations(buf, list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -710,7 +714,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
protected void writeBody(BufWriter buf, RuntimeVisibleTypeAnnotationsAttribute attr) {
|
||||
buf.writeList(attr.annotations());
|
||||
AnnotationReader.writeAnnotations(buf, attr.annotations());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,12 +24,11 @@
|
||||
*/
|
||||
package jdk.internal.classfile.impl;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.Label;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
public class AbstractBoundLocalVariable
|
||||
extends AbstractElement {
|
||||
extends AbstractElement implements Util.WritableLocalVariable {
|
||||
protected final CodeImpl code;
|
||||
protected final int offset;
|
||||
private Utf8Entry nameEntry;
|
||||
@ -80,8 +79,9 @@ public class AbstractBoundLocalVariable
|
||||
return code.classReader.readU2(offset + 8);
|
||||
}
|
||||
|
||||
public boolean writeTo(BufWriter b) {
|
||||
var lc = ((BufWriterImpl)b).labelContext();
|
||||
@Override
|
||||
public boolean writeLocalTo(BufWriterImpl b) {
|
||||
var lc = b.labelContext();
|
||||
int startBci = lc.labelToBci(startScope());
|
||||
int endBci = lc.labelToBci(endScope());
|
||||
if (startBci == -1 || endBci == -1) {
|
||||
|
@ -34,7 +34,6 @@ import java.lang.classfile.constantpool.ClassEntry;
|
||||
import java.lang.classfile.constantpool.ConstantDynamicEntry;
|
||||
import java.lang.classfile.constantpool.ConstantPool;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.constantpool.DoubleEntry;
|
||||
import java.lang.classfile.constantpool.FieldRefEntry;
|
||||
import java.lang.classfile.constantpool.FloatEntry;
|
||||
@ -123,6 +122,8 @@ public abstract sealed class AbstractPoolEntry {
|
||||
return (tag == ClassFile.TAG_LONG || tag == ClassFile.TAG_DOUBLE) ? 2 : 1;
|
||||
}
|
||||
|
||||
abstract void writeTo(BufWriterImpl buf);
|
||||
|
||||
abstract PoolEntry clone(ConstantPoolBuilder cp);
|
||||
|
||||
public static final class Utf8EntryImpl extends AbstractPoolEntry implements Utf8Entry {
|
||||
@ -407,7 +408,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
if (rawBytes != null) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeU2(rawLen);
|
||||
@ -478,7 +479,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
return ref1;
|
||||
}
|
||||
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeU2(ref1.index());
|
||||
}
|
||||
@ -508,7 +509,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
return ref2;
|
||||
}
|
||||
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeU2(ref1.index());
|
||||
pool.writeU2(ref2.index());
|
||||
@ -814,7 +815,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
return nameAndType;
|
||||
}
|
||||
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeU2(bsmIndex);
|
||||
pool.writeU2(nameAndType.index());
|
||||
@ -919,7 +920,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeU1(refKind);
|
||||
pool.writeU2(reference.index());
|
||||
@ -1069,7 +1070,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeInt(val);
|
||||
}
|
||||
@ -1102,7 +1103,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeFloat(val);
|
||||
}
|
||||
@ -1134,7 +1135,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeLong(val);
|
||||
}
|
||||
@ -1166,7 +1167,7 @@ public abstract sealed class AbstractPoolEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter pool) {
|
||||
void writeTo(BufWriterImpl pool) {
|
||||
pool.writeU1(tag);
|
||||
pool.writeDouble(val);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -154,7 +154,8 @@ public abstract sealed class AbstractPseudoInstruction
|
||||
|
||||
}
|
||||
|
||||
private abstract static sealed class AbstractLocalPseudo extends AbstractPseudoInstruction {
|
||||
private abstract static sealed class AbstractLocalPseudo extends AbstractPseudoInstruction
|
||||
implements Util.WritableLocalVariable {
|
||||
protected final int slot;
|
||||
protected final Utf8Entry name;
|
||||
protected final Utf8Entry descriptor;
|
||||
@ -189,8 +190,9 @@ public abstract sealed class AbstractPseudoInstruction
|
||||
return endScope;
|
||||
}
|
||||
|
||||
public boolean writeTo(BufWriter b) {
|
||||
var lc = ((BufWriterImpl)b).labelContext();
|
||||
@Override
|
||||
public boolean writeLocalTo(BufWriterImpl b) {
|
||||
var lc = b.labelContext();
|
||||
int startBci = lc.labelToBci(startScope());
|
||||
int endBci = lc.labelToBci(endScope());
|
||||
if (startBci == -1 || endBci == -1) {
|
||||
|
@ -35,7 +35,7 @@ import java.lang.classfile.CompoundElement;
|
||||
|
||||
public abstract sealed class AbstractUnboundModel<E extends ClassFileElement>
|
||||
extends AbstractElement
|
||||
implements CompoundElement<E>, AttributedElement
|
||||
implements CompoundElement<E>, AttributedElement, Util.Writable
|
||||
permits BufferedCodeBuilder.Model, BufferedFieldBuilder.Model, BufferedMethodBuilder.Model {
|
||||
private final List<E> elements;
|
||||
private List<Attribute<?>> attributes;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,7 +32,7 @@ import java.util.List;
|
||||
|
||||
import static java.lang.classfile.ClassFile.*;
|
||||
|
||||
public final class AnnotationImpl implements Annotation {
|
||||
public final class AnnotationImpl implements Annotation, Util.Writable {
|
||||
private final Utf8Entry className;
|
||||
private final List<AnnotationElement> elements;
|
||||
|
||||
@ -53,9 +53,13 @@ public final class AnnotationImpl implements Annotation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
buf.writeIndex(className());
|
||||
buf.writeList(elements());
|
||||
buf.writeU2(elements().size());
|
||||
for (var e : elements) {
|
||||
buf.writeIndex(e.name());
|
||||
AnnotationReader.writeAnnotationValue(buf, e.value());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -81,16 +85,16 @@ public final class AnnotationImpl implements Annotation {
|
||||
|
||||
public record AnnotationElementImpl(Utf8Entry name,
|
||||
AnnotationValue value)
|
||||
implements AnnotationElement {
|
||||
implements AnnotationElement, Util.Writable {
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
buf.writeIndex(name());
|
||||
value().writeTo(buf);
|
||||
AnnotationReader.writeAnnotationValue(buf, value());
|
||||
}
|
||||
}
|
||||
|
||||
public sealed interface OfConstantImpl extends AnnotationValue.OfConstant
|
||||
public sealed interface OfConstantImpl extends AnnotationValue.OfConstant, Util.Writable
|
||||
permits AnnotationImpl.OfStringImpl, AnnotationImpl.OfDoubleImpl,
|
||||
AnnotationImpl.OfFloatImpl, AnnotationImpl.OfLongImpl,
|
||||
AnnotationImpl.OfIntegerImpl, AnnotationImpl.OfShortImpl,
|
||||
@ -98,7 +102,7 @@ public final class AnnotationImpl implements Annotation {
|
||||
AnnotationImpl.OfBooleanImpl {
|
||||
|
||||
@Override
|
||||
default void writeTo(BufWriter buf) {
|
||||
default void writeTo(BufWriterImpl buf) {
|
||||
buf.writeU1(tag());
|
||||
buf.writeIndex(constant());
|
||||
}
|
||||
@ -237,7 +241,7 @@ public final class AnnotationImpl implements Annotation {
|
||||
}
|
||||
|
||||
public record OfArrayImpl(List<AnnotationValue> values)
|
||||
implements AnnotationValue.OfArray {
|
||||
implements AnnotationValue.OfArray, Util.Writable {
|
||||
|
||||
public OfArrayImpl(List<AnnotationValue> values) {
|
||||
this.values = List.copyOf(values);
|
||||
@ -249,22 +253,25 @@ public final class AnnotationImpl implements Annotation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
buf.writeU1(tag());
|
||||
buf.writeList(values);
|
||||
buf.writeU2(values.size());
|
||||
for (var e : values) {
|
||||
AnnotationReader.writeAnnotationValue(buf, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public record OfEnumImpl(Utf8Entry className, Utf8Entry constantName)
|
||||
implements AnnotationValue.OfEnum {
|
||||
implements AnnotationValue.OfEnum, Util.Writable {
|
||||
@Override
|
||||
public char tag() {
|
||||
return AEV_ENUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
buf.writeU1(tag());
|
||||
buf.writeIndex(className);
|
||||
buf.writeIndex(constantName);
|
||||
@ -273,29 +280,29 @@ public final class AnnotationImpl implements Annotation {
|
||||
}
|
||||
|
||||
public record OfAnnotationImpl(Annotation annotation)
|
||||
implements AnnotationValue.OfAnnotation {
|
||||
implements AnnotationValue.OfAnnotation, Util.Writable {
|
||||
@Override
|
||||
public char tag() {
|
||||
return AEV_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
buf.writeU1(tag());
|
||||
annotation.writeTo(buf);
|
||||
AnnotationReader.writeAnnotation(buf, annotation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public record OfClassImpl(Utf8Entry className)
|
||||
implements AnnotationValue.OfClass {
|
||||
implements AnnotationValue.OfClass, Util.Writable {
|
||||
@Override
|
||||
public char tag() {
|
||||
return AEV_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
buf.writeU1(tag());
|
||||
buf.writeIndex(className);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ package jdk.internal.classfile.impl;
|
||||
import java.lang.classfile.Annotation;
|
||||
import java.lang.classfile.AnnotationElement;
|
||||
import java.lang.classfile.AnnotationValue;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassReader;
|
||||
import java.lang.classfile.constantpool.*;
|
||||
import java.lang.classfile.TypeAnnotation;
|
||||
@ -39,7 +40,7 @@ import java.lang.classfile.Label;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
|
||||
class AnnotationReader {
|
||||
public final class AnnotationReader {
|
||||
private AnnotationReader() { }
|
||||
|
||||
public static List<Annotation> readAnnotations(ClassReader classReader, int p) {
|
||||
@ -280,4 +281,24 @@ class AnnotationReader {
|
||||
p = skipElementValuePairs(classReader, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
public static void writeAnnotation(BufWriterImpl buf, Annotation annotation) {
|
||||
// handles annotations and type annotations
|
||||
// TODO annotation cleanup later
|
||||
((Util.Writable) annotation).writeTo(buf);
|
||||
}
|
||||
|
||||
public static void writeAnnotations(BufWriter buf, List<? extends Annotation> list) {
|
||||
// handles annotations and type annotations
|
||||
var internalBuf = (BufWriterImpl) buf;
|
||||
internalBuf.writeU2(list.size());
|
||||
for (var e : list) {
|
||||
writeAnnotation(internalBuf, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeAnnotationValue(BufWriterImpl buf, AnnotationValue value) {
|
||||
// TODO annotation cleanup later
|
||||
((Util.Writable) value).writeTo(buf);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,7 +29,6 @@ import java.util.List;
|
||||
|
||||
import java.lang.classfile.Attribute;
|
||||
import java.lang.classfile.AttributeMapper;
|
||||
import java.lang.classfile.BufWriter;
|
||||
|
||||
public class AttributeHolder {
|
||||
private final List<Attribute<?>> attributes = new ArrayList<>();
|
||||
@ -50,10 +49,8 @@ public class AttributeHolder {
|
||||
return attributes.size();
|
||||
}
|
||||
|
||||
public void writeTo(BufWriter buf) {
|
||||
buf.writeU2(attributes.size());
|
||||
for (Attribute<?> a : attributes)
|
||||
a.writeTo(buf);
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
Util.writeAttributes(buf, attributes);
|
||||
}
|
||||
|
||||
boolean isPresent(AttributeMapper<?> am) {
|
||||
|
@ -28,7 +28,6 @@ import java.util.List;
|
||||
|
||||
import java.lang.classfile.constantpool.ConstantPool;
|
||||
import java.lang.classfile.BootstrapMethodEntry;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.constantpool.LoadableConstantEntry;
|
||||
import java.lang.classfile.constantpool.MethodHandleEntry;
|
||||
|
||||
@ -87,9 +86,8 @@ public final class BootstrapMethodEntryImpl implements BootstrapMethodEntry {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter writer) {
|
||||
void writeTo(BufWriterImpl writer) {
|
||||
writer.writeIndex(bootstrapMethod());
|
||||
writer.writeListIndices(arguments());
|
||||
Util.writeListIndices(writer, arguments());
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ import static java.lang.classfile.Attributes.*;
|
||||
|
||||
public abstract sealed class BoundAttribute<T extends Attribute<T>>
|
||||
extends AbstractElement
|
||||
implements Attribute<T> {
|
||||
implements Attribute<T>, Util.Writable {
|
||||
|
||||
static final int NAME_AND_LENGTH_PREFIX = 6;
|
||||
private final AttributeMapper<T> mapper;
|
||||
@ -101,7 +101,7 @@ public abstract sealed class BoundAttribute<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
if (!buf.canWriteDirect(classReader))
|
||||
attributeMapper().writeAttribute(buf, (T) this);
|
||||
else
|
||||
|
@ -27,10 +27,8 @@ package jdk.internal.classfile.impl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.WritableElement;
|
||||
import java.lang.classfile.constantpool.ClassEntry;
|
||||
import java.lang.classfile.constantpool.ConstantPool;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
@ -126,10 +124,8 @@ public final class BufWriterImpl implements BufWriter {
|
||||
writeBytes(arr, 0, arr.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(BufWriter other) {
|
||||
BufWriterImpl o = (BufWriterImpl) other;
|
||||
writeBytes(o.elems, 0, o.offset);
|
||||
public void writeBytes(BufWriterImpl other) {
|
||||
writeBytes(other.elems, 0, other.offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -175,7 +171,6 @@ public final class BufWriterImpl implements BufWriter {
|
||||
return ByteBuffer.wrap(elems, 0, offset).slice();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(byte[] array, int bufferOffset) {
|
||||
System.arraycopy(elems, 0, array, bufferOffset, size());
|
||||
}
|
||||
@ -198,20 +193,4 @@ public final class BufWriterImpl implements BufWriter {
|
||||
else
|
||||
writeIndex(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public<T extends WritableElement<?>> void writeList(List<T> list) {
|
||||
writeU2(list.size());
|
||||
for (T t : list) {
|
||||
t.writeTo(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeListIndices(List<? extends PoolEntry> list) {
|
||||
writeU2(list.size());
|
||||
for (PoolEntry info : list) {
|
||||
writeIndex(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
*/
|
||||
package jdk.internal.classfile.impl;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.CodeBuilder;
|
||||
import java.lang.classfile.CodeElement;
|
||||
import java.lang.classfile.CodeModel;
|
||||
@ -201,7 +200,8 @@ public final class BufferedCodeBuilder
|
||||
});
|
||||
}
|
||||
|
||||
public void writeTo(BufWriter buf) {
|
||||
@Override
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
DirectCodeBuilder.build(methodInfo, cb -> elements.forEach(cb), constantPool, context, null).writeTo(buf);
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ public final class BufferedFieldBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
DirectFieldBuilder fb = new DirectFieldBuilder(constantPool, context, name, desc, null);
|
||||
elements.forEach(fb);
|
||||
fb.writeTo(buf);
|
||||
|
@ -33,7 +33,6 @@ import java.util.function.Consumer;
|
||||
|
||||
import java.lang.classfile.AccessFlags;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassModel;
|
||||
import java.lang.classfile.CodeBuilder;
|
||||
import java.lang.classfile.CodeModel;
|
||||
@ -211,7 +210,7 @@ public final class BufferedMethodBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
DirectMethodBuilder mb = new DirectMethodBuilder(constantPool, context, name, desc, methodFlags(), null);
|
||||
elements.forEach(mb);
|
||||
mb.writeTo(buf);
|
||||
|
@ -321,12 +321,13 @@ public final class ClassReaderImpl
|
||||
return containedClass;
|
||||
}
|
||||
|
||||
boolean writeBootstrapMethods(BufWriter buf) {
|
||||
boolean writeBootstrapMethods(BufWriterImpl buf) {
|
||||
Optional<BootstrapMethodsAttribute> a
|
||||
= containedClass.findAttribute(Attributes.bootstrapMethods());
|
||||
if (a.isEmpty())
|
||||
return false;
|
||||
a.get().writeTo(buf);
|
||||
// BootstrapMethodAttribute implementations are all internal writable
|
||||
((Util.Writable) a.get()).writeTo(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -465,13 +466,12 @@ public final class ClassReaderImpl
|
||||
return entryByIndex(index, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean compare(BufWriter bufWriter,
|
||||
public boolean compare(BufWriterImpl bufWriter,
|
||||
int bufWriterOffset,
|
||||
int classReaderOffset,
|
||||
int length) {
|
||||
try {
|
||||
return Arrays.equals(((BufWriterImpl) bufWriter).elems,
|
||||
return Arrays.equals(bufWriter.elems,
|
||||
bufWriterOffset, bufWriterOffset + length,
|
||||
buffer, classReaderOffset, classReaderOffset + length);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
|
@ -141,7 +141,7 @@ public final class CodeImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
if (buf.canWriteDirect(classReader)) {
|
||||
super.writeTo(buf);
|
||||
}
|
||||
@ -154,7 +154,7 @@ public final class CodeImpl
|
||||
}
|
||||
},
|
||||
(SplitConstantPool)buf.constantPool(),
|
||||
((BufWriterImpl)buf).context(),
|
||||
buf.context(),
|
||||
null).writeTo(buf);
|
||||
}
|
||||
}
|
||||
@ -210,7 +210,7 @@ public final class CodeImpl
|
||||
return exceptionTable;
|
||||
}
|
||||
|
||||
public boolean compareCodeBytes(BufWriter buf, int offset, int len) {
|
||||
public boolean compareCodeBytes(BufWriterImpl buf, int offset, int len) {
|
||||
return codeLength == len
|
||||
&& classReader.compare(buf, offset, codeStart, codeLength);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,7 +31,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassBuilder;
|
||||
import java.lang.classfile.ClassElement;
|
||||
import java.lang.classfile.ClassModel;
|
||||
@ -44,7 +43,6 @@ import java.lang.classfile.FieldTransform;
|
||||
import java.lang.classfile.MethodBuilder;
|
||||
import java.lang.classfile.MethodModel;
|
||||
import java.lang.classfile.MethodTransform;
|
||||
import java.lang.classfile.WritableElement;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
public final class DirectClassBuilder
|
||||
@ -52,8 +50,8 @@ public final class DirectClassBuilder
|
||||
implements ClassBuilder {
|
||||
|
||||
final ClassEntry thisClassEntry;
|
||||
private final List<WritableElement<FieldModel>> fields = new ArrayList<>();
|
||||
private final List<WritableElement<MethodModel>> methods = new ArrayList<>();
|
||||
private final List<Util.Writable> fields = new ArrayList<>();
|
||||
private final List<Util.Writable> methods = new ArrayList<>();
|
||||
private ClassEntry superclassEntry;
|
||||
private List<ClassEntry> interfaceEntries;
|
||||
private int majorVersion;
|
||||
@ -78,7 +76,7 @@ public final class DirectClassBuilder
|
||||
if (element instanceof AbstractElement ae) {
|
||||
ae.writeTo(this);
|
||||
} else {
|
||||
writeAttribute((CustomAttribute)element);
|
||||
writeAttribute((CustomAttribute<?>) element);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -120,12 +118,12 @@ public final class DirectClassBuilder
|
||||
|
||||
// internal / for use by elements
|
||||
|
||||
public ClassBuilder withField(WritableElement<FieldModel> field) {
|
||||
ClassBuilder withField(Util.Writable field) {
|
||||
fields.add(field);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClassBuilder withMethod(WritableElement<MethodModel> method) {
|
||||
ClassBuilder withMethod(Util.Writable method) {
|
||||
methods.add(method);
|
||||
return this;
|
||||
}
|
||||
@ -172,13 +170,13 @@ public final class DirectClassBuilder
|
||||
|
||||
// We maintain two writers, and then we join them at the end
|
||||
int size = sizeHint == 0 ? 256 : sizeHint;
|
||||
BufWriter head = new BufWriterImpl(constantPool, context, size);
|
||||
BufWriterImpl head = new BufWriterImpl(constantPool, context, size);
|
||||
BufWriterImpl tail = new BufWriterImpl(constantPool, context, size, thisClassEntry, majorVersion);
|
||||
|
||||
// The tail consists of fields and methods, and attributes
|
||||
// This should trigger all the CP/BSM mutation
|
||||
tail.writeList(fields);
|
||||
tail.writeList(methods);
|
||||
Util.writeList(tail, fields);
|
||||
Util.writeList(tail, methods);
|
||||
int attributesOffset = tail.size();
|
||||
attributes.writeTo(tail);
|
||||
|
||||
@ -197,7 +195,7 @@ public final class DirectClassBuilder
|
||||
head.writeU2(flags);
|
||||
head.writeIndex(thisClassEntry);
|
||||
head.writeIndexOrZero(superclass);
|
||||
head.writeListIndices(ies);
|
||||
Util.writeListIndices(head, ies);
|
||||
|
||||
// Join head and tail into an exact-size buffer
|
||||
byte[] result = new byte[head.size() + tail.size()];
|
||||
|
@ -24,7 +24,6 @@
|
||||
*/
|
||||
package jdk.internal.classfile.impl;
|
||||
|
||||
import java.lang.constant.MethodTypeDesc;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@ -36,20 +35,17 @@ import java.util.function.Function;
|
||||
|
||||
import java.lang.classfile.Attribute;
|
||||
import java.lang.classfile.Attributes;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.classfile.CodeBuilder;
|
||||
import java.lang.classfile.CodeElement;
|
||||
import java.lang.classfile.CodeModel;
|
||||
import java.lang.classfile.CustomAttribute;
|
||||
import java.lang.classfile.Instruction;
|
||||
import java.lang.classfile.Label;
|
||||
import java.lang.classfile.Opcode;
|
||||
import java.lang.classfile.TypeKind;
|
||||
import java.lang.classfile.instruction.SwitchCase;
|
||||
import java.lang.classfile.attribute.CodeAttribute;
|
||||
import java.lang.classfile.attribute.LineNumberTableAttribute;
|
||||
import java.lang.classfile.attribute.StackMapTableAttribute;
|
||||
import java.lang.classfile.constantpool.ClassEntry;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
import java.lang.classfile.constantpool.DoubleEntry;
|
||||
@ -83,7 +79,7 @@ public final class DirectCodeBuilder
|
||||
private final boolean transformFwdJumps, transformBackJumps;
|
||||
private final Label startLabel, endLabel;
|
||||
final MethodInfo methodInfo;
|
||||
final BufWriter bytecodesBufWriter;
|
||||
final BufWriterImpl bytecodesBufWriter;
|
||||
private CodeAttribute mruParent;
|
||||
private int[] mruParentTable;
|
||||
private Map<CodeAttribute, int[]> parentMap;
|
||||
@ -100,7 +96,7 @@ public final class DirectCodeBuilder
|
||||
allocLocal(TypeKind) bumps by nSlots
|
||||
*/
|
||||
|
||||
public static Attribute<CodeAttribute> build(MethodInfo methodInfo,
|
||||
public static UnboundAttribute<CodeAttribute> build(MethodInfo methodInfo,
|
||||
Consumer<? super CodeBuilder> handler,
|
||||
SplitConstantPool constantPool,
|
||||
ClassFileImpl context,
|
||||
@ -144,7 +140,7 @@ public final class DirectCodeBuilder
|
||||
if (element instanceof AbstractElement ae) {
|
||||
ae.writeTo(this);
|
||||
} else {
|
||||
writeAttribute((CustomAttribute)element);
|
||||
writeAttribute((CustomAttribute<?>) element);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -193,9 +189,9 @@ public final class DirectCodeBuilder
|
||||
return methodInfo;
|
||||
}
|
||||
|
||||
private Attribute<CodeAttribute> content = null;
|
||||
private UnboundAttribute<CodeAttribute> content = null;
|
||||
|
||||
private void writeExceptionHandlers(BufWriter buf) {
|
||||
private void writeExceptionHandlers(BufWriterImpl buf) {
|
||||
int pos = buf.size();
|
||||
int handlersSize = handlers.size();
|
||||
buf.writeU2(handlersSize);
|
||||
@ -233,7 +229,7 @@ public final class DirectCodeBuilder
|
||||
Attribute<?> a = new UnboundAttribute.AdHocAttribute<>(Attributes.characterRangeTable()) {
|
||||
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
int pos = b.size();
|
||||
int crSize = characterRanges.size();
|
||||
b.writeU2(crSize);
|
||||
@ -264,12 +260,12 @@ public final class DirectCodeBuilder
|
||||
if (!localVariables.isEmpty()) {
|
||||
Attribute<?> a = new UnboundAttribute.AdHocAttribute<>(Attributes.localVariableTable()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
int pos = b.size();
|
||||
int lvSize = localVariables.size();
|
||||
b.writeU2(lvSize);
|
||||
for (LocalVariable l : localVariables) {
|
||||
if (!l.writeTo(b)) {
|
||||
if (!Util.writeLocalVariable(b, l)) {
|
||||
if (context.deadLabelsOption() == ClassFile.DeadLabelsOption.DROP_DEAD_LABELS) {
|
||||
lvSize--;
|
||||
} else {
|
||||
@ -287,12 +283,12 @@ public final class DirectCodeBuilder
|
||||
if (!localVariableTypes.isEmpty()) {
|
||||
Attribute<?> a = new UnboundAttribute.AdHocAttribute<>(Attributes.localVariableTypeTable()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
int pos = b.size();
|
||||
int lvtSize = localVariableTypes.size();
|
||||
b.writeU2(localVariableTypes.size());
|
||||
for (LocalVariableType l : localVariableTypes) {
|
||||
if (!l.writeTo(b)) {
|
||||
if (!Util.writeLocalVariable(b, l)) {
|
||||
if (context.deadLabelsOption() == ClassFile.DeadLabelsOption.DROP_DEAD_LABELS) {
|
||||
lvtSize--;
|
||||
} else {
|
||||
@ -352,8 +348,7 @@ public final class DirectCodeBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
BufWriterImpl buf = (BufWriterImpl) b;
|
||||
public void writeBody(BufWriterImpl buf) {
|
||||
buf.setLabelContext(DirectCodeBuilder.this);
|
||||
|
||||
int codeLength = curPc();
|
||||
@ -389,8 +384,8 @@ public final class DirectCodeBuilder
|
||||
|
||||
buf.writeInt(codeLength);
|
||||
buf.writeBytes(bytecodesBufWriter);
|
||||
writeExceptionHandlers(b);
|
||||
attributes.writeTo(b);
|
||||
writeExceptionHandlers(buf);
|
||||
attributes.writeTo(buf);
|
||||
buf.setLabelContext(null);
|
||||
}
|
||||
};
|
||||
@ -427,12 +422,12 @@ public final class DirectCodeBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter b) {
|
||||
public void writeTo(BufWriterImpl b) {
|
||||
b.writeIndex(b.constantPool().utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE));
|
||||
push();
|
||||
b.writeInt(buf.size() + 2);
|
||||
@ -447,7 +442,7 @@ public final class DirectCodeBuilder
|
||||
codeAttributesMatch = cai.codeLength == curPc()
|
||||
&& cai.compareCodeBytes(bytecodesBufWriter, 0, codeLength);
|
||||
if (codeAttributesMatch) {
|
||||
BufWriter bw = new BufWriterImpl(constantPool, context);
|
||||
var bw = new BufWriterImpl(constantPool, context);
|
||||
writeExceptionHandlers(bw);
|
||||
codeAttributesMatch = cai.classReader.compare(bw, 0, cai.exceptionHandlerPos, bw.size());
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,17 +27,15 @@ package jdk.internal.classfile.impl;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.CustomAttribute;
|
||||
import java.lang.classfile.FieldBuilder;
|
||||
import java.lang.classfile.FieldElement;
|
||||
import java.lang.classfile.FieldModel;
|
||||
import java.lang.classfile.WritableElement;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
public final class DirectFieldBuilder
|
||||
extends AbstractDirectBuilder<FieldModel>
|
||||
implements TerminalFieldBuilder, WritableElement<FieldModel> {
|
||||
implements TerminalFieldBuilder, Util.Writable {
|
||||
private final Utf8Entry name;
|
||||
private final Utf8Entry desc;
|
||||
private int flags;
|
||||
@ -59,7 +57,7 @@ public final class DirectFieldBuilder
|
||||
if (element instanceof AbstractElement ae) {
|
||||
ae.writeTo(this);
|
||||
} else {
|
||||
writeAttribute((CustomAttribute)element);
|
||||
writeAttribute((CustomAttribute<?>) element);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -74,7 +72,7 @@ public final class DirectFieldBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
buf.writeU2(flags);
|
||||
buf.writeIndex(name);
|
||||
buf.writeIndex(desc);
|
||||
|
@ -28,7 +28,6 @@ package jdk.internal.classfile.impl;
|
||||
import java.lang.constant.MethodTypeDesc;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.classfile.CodeBuilder;
|
||||
import java.lang.classfile.CodeModel;
|
||||
@ -37,12 +36,11 @@ import java.lang.classfile.CustomAttribute;
|
||||
import java.lang.classfile.MethodBuilder;
|
||||
import java.lang.classfile.MethodElement;
|
||||
import java.lang.classfile.MethodModel;
|
||||
import java.lang.classfile.WritableElement;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
public final class DirectMethodBuilder
|
||||
extends AbstractDirectBuilder<MethodModel>
|
||||
implements TerminalMethodBuilder, WritableElement<MethodModel> {
|
||||
implements TerminalMethodBuilder, Util.Writable {
|
||||
|
||||
final Utf8Entry name;
|
||||
final Utf8Entry desc;
|
||||
@ -115,7 +113,7 @@ public final class DirectMethodBuilder
|
||||
if (element instanceof AbstractElement ae) {
|
||||
ae.writeTo(this);
|
||||
} else {
|
||||
writeAttribute((CustomAttribute)element);
|
||||
writeAttribute((CustomAttribute<?>) element);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -148,8 +146,7 @@ public final class DirectMethodBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter b) {
|
||||
BufWriterImpl buf = (BufWriterImpl) b;
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
buf.writeU2(flags);
|
||||
buf.writeIndex(name);
|
||||
buf.writeIndex(desc);
|
||||
|
@ -33,7 +33,7 @@ import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
public final class FieldImpl
|
||||
extends AbstractElement
|
||||
implements FieldModel {
|
||||
implements FieldModel, Util.Writable {
|
||||
|
||||
private final ClassReader reader;
|
||||
private final int startPos, endPos, attributesPos;
|
||||
@ -78,7 +78,7 @@ public final class FieldImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
if (buf.canWriteDirect(reader)) {
|
||||
reader.copyBytesTo(buf, startPos, endPos - startPos);
|
||||
}
|
||||
@ -86,7 +86,7 @@ public final class FieldImpl
|
||||
buf.writeU2(flags().flagsMask());
|
||||
buf.writeIndex(fieldName());
|
||||
buf.writeIndex(fieldType());
|
||||
buf.writeList(attributes());
|
||||
Util.writeAttributes(buf, attributes());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ import java.util.function.Consumer;
|
||||
|
||||
public final class MethodImpl
|
||||
extends AbstractElement
|
||||
implements MethodModel, MethodInfo {
|
||||
implements MethodModel, MethodInfo, Util.Writable {
|
||||
|
||||
private final ClassReader reader;
|
||||
private final int startPos, endPos, attributesPos;
|
||||
@ -101,8 +101,7 @@ public final class MethodImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter b) {
|
||||
BufWriterImpl buf = (BufWriterImpl) b;
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
if (buf.canWriteDirect(reader)) {
|
||||
reader.copyBytesTo(buf, startPos, endPos - startPos);
|
||||
}
|
||||
@ -110,7 +109,7 @@ public final class MethodImpl
|
||||
buf.writeU2(flags().flagsMask());
|
||||
buf.writeIndex(methodName());
|
||||
buf.writeIndex(methodType());
|
||||
buf.writeList(attributes());
|
||||
Util.writeAttributes(buf, attributes());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,10 @@ import java.lang.constant.MethodTypeDesc;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import java.lang.classfile.Attribute;
|
||||
import java.lang.classfile.Attributes;
|
||||
import java.lang.classfile.ClassReader;
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.classfile.BootstrapMethodEntry;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.attribute.BootstrapMethodsAttribute;
|
||||
import java.lang.classfile.constantpool.*;
|
||||
import java.util.Objects;
|
||||
@ -135,7 +133,7 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
|
||||
return this == other || parent == other;
|
||||
}
|
||||
|
||||
public boolean writeBootstrapMethods(BufWriter buf) {
|
||||
public boolean writeBootstrapMethods(BufWriterImpl buf) {
|
||||
if (bsmSize == 0)
|
||||
return false;
|
||||
int pos = buf.size();
|
||||
@ -148,11 +146,11 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
|
||||
buf.patchInt(pos + 6, 2, bsmSize);
|
||||
}
|
||||
else {
|
||||
Attribute<BootstrapMethodsAttribute> a
|
||||
UnboundAttribute<BootstrapMethodsAttribute> a
|
||||
= new UnboundAttribute.AdHocAttribute<>(Attributes.bootstrapMethods()) {
|
||||
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
buf.writeU2(bsmSize);
|
||||
for (int i = 0; i < bsmSize; i++)
|
||||
bootstrapMethodEntry(i).writeTo(buf);
|
||||
@ -163,8 +161,7 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
void writeTo(BufWriterImpl buf) {
|
||||
int writeFrom = 1;
|
||||
if (size() >= 65536) {
|
||||
throw new IllegalArgumentException(String.format("Constant pool is too large %d", size()));
|
||||
@ -175,7 +172,7 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
|
||||
writeFrom = parent.size();
|
||||
}
|
||||
for (int i = writeFrom; i < size(); ) {
|
||||
PoolEntry info = entryByIndex(i);
|
||||
var info = (AbstractPoolEntry) entryByIndex(i);
|
||||
info.writeTo(buf);
|
||||
i += info.width();
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public final class StackCounter {
|
||||
dcb.methodInfo.methodName().stringValue(),
|
||||
dcb.methodInfo.methodTypeSymbol(),
|
||||
(dcb.methodInfo.methodFlags() & ACC_STATIC) != 0,
|
||||
((BufWriterImpl) dcb.bytecodesBufWriter).asByteBuffer(),
|
||||
dcb.bytecodesBufWriter.asByteBuffer(),
|
||||
dcb.constantPool,
|
||||
dcb.handlers);
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ public final class StackMapGenerator {
|
||||
dcb.methodInfo.methodName().stringValue(),
|
||||
dcb.methodInfo.methodTypeSymbol(),
|
||||
(dcb.methodInfo.methodFlags() & ACC_STATIC) != 0,
|
||||
((BufWriterImpl) dcb.bytecodesBufWriter).asByteBuffer(),
|
||||
dcb.bytecodesBufWriter.asByteBuffer(),
|
||||
dcb.constantPool,
|
||||
dcb.context,
|
||||
dcb.handlers);
|
||||
@ -383,7 +383,7 @@ public final class StackMapGenerator {
|
||||
public Attribute<? extends StackMapTableAttribute> stackMapTableAttribute() {
|
||||
return frames.isEmpty() ? null : new UnboundAttribute.AdHocAttribute<>(Attributes.stackMapTable()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(frames.size());
|
||||
Frame prevFrame = new Frame(classHierarchy);
|
||||
prevFrame.setLocalsFromArg(methodName, methodDesc, isStatic, thisType);
|
||||
|
@ -189,9 +189,4 @@ public final class TemporaryConstantPool implements ConstantPoolBuilder {
|
||||
public boolean canWriteDirect(ConstantPool constantPool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,7 +35,6 @@ import java.lang.classfile.Attribute;
|
||||
import java.lang.classfile.AttributeMapper;
|
||||
import java.lang.classfile.Attributes;
|
||||
import java.lang.classfile.BootstrapMethodEntry;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.constantpool.ClassEntry;
|
||||
import java.lang.classfile.Label;
|
||||
import java.lang.classfile.TypeAnnotation;
|
||||
@ -95,7 +94,7 @@ import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
extends AbstractElement
|
||||
implements Attribute<T> {
|
||||
implements Attribute<T>, Util.Writable {
|
||||
protected final AttributeMapper<T> mapper;
|
||||
|
||||
public UnboundAttribute(AttributeMapper<T> mapper) {
|
||||
@ -114,7 +113,7 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeTo(BufWriter buf) {
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
mapper.writeAttribute(buf, (T) this);
|
||||
}
|
||||
|
||||
@ -752,7 +751,7 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
public record UnboundTypeAnnotation(TargetInfo targetInfo,
|
||||
List<TypePathComponent> targetPath,
|
||||
Utf8Entry className,
|
||||
List<AnnotationElement> elements) implements TypeAnnotation {
|
||||
List<AnnotationElement> elements) implements TypeAnnotation, Util.Writable {
|
||||
|
||||
public UnboundTypeAnnotation(TargetInfo targetInfo, List<TypePathComponent> targetPath,
|
||||
Utf8Entry className, List<AnnotationElement> elements) {
|
||||
@ -769,8 +768,8 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter buf) {
|
||||
LabelContext lr = ((BufWriterImpl) buf).labelContext();
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
LabelContext lr = buf.labelContext();
|
||||
// target_type
|
||||
buf.writeU1(targetInfo.targetType().targetTypeValue());
|
||||
|
||||
@ -818,7 +817,7 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
buf.writeU2(elements.size());
|
||||
for (AnnotationElement pair : elements()) {
|
||||
buf.writeIndex(pair.name());
|
||||
pair.value().writeTo(buf);
|
||||
AnnotationReader.writeAnnotationValue(buf, pair.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -904,10 +903,10 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
super(mapper);
|
||||
}
|
||||
|
||||
public abstract void writeBody(BufWriter b);
|
||||
public abstract void writeBody(BufWriterImpl b);
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriter b) {
|
||||
public void writeTo(BufWriterImpl b) {
|
||||
b.writeIndex(b.constantPool().utf8Entry(mapper.name()));
|
||||
b.writeInt(0);
|
||||
int start = b.size();
|
||||
|
@ -24,6 +24,9 @@
|
||||
*/
|
||||
package jdk.internal.classfile.impl;
|
||||
|
||||
import java.lang.classfile.CustomAttribute;
|
||||
import java.lang.classfile.PseudoInstruction;
|
||||
import java.lang.classfile.constantpool.PoolEntry;
|
||||
import java.lang.constant.ClassDesc;
|
||||
import java.lang.constant.MethodTypeDesc;
|
||||
import java.util.AbstractList;
|
||||
@ -47,7 +50,6 @@ import jdk.internal.access.SharedSecrets;
|
||||
import static java.lang.classfile.ClassFile.ACC_STATIC;
|
||||
import java.lang.classfile.attribute.CodeAttribute;
|
||||
import java.lang.classfile.components.ClassPrinter;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@ -188,6 +190,31 @@ public class Util {
|
||||
return ((AbstractPoolEntry.NameAndTypeEntryImpl)nat).methodTypeSymbol();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> void writeAttribute(BufWriterImpl writer, Attribute<?> attr) {
|
||||
if (attr instanceof CustomAttribute<?> ca) {
|
||||
var mapper = (AttributeMapper<T>) ca.attributeMapper();
|
||||
mapper.writeAttribute(writer, (T) ca);
|
||||
} else {
|
||||
assert attr instanceof BoundAttribute || attr instanceof UnboundAttribute;
|
||||
((Writable) attr).writeTo(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeAttributes(BufWriterImpl buf, List<? extends Attribute<?>> list) {
|
||||
buf.writeU2(list.size());
|
||||
for (var e : list) {
|
||||
writeAttribute(buf, e);
|
||||
}
|
||||
}
|
||||
|
||||
static void writeList(BufWriterImpl buf, List<Writable> list) {
|
||||
buf.writeU2(list.size());
|
||||
for (var e : list) {
|
||||
e.writeTo(buf);
|
||||
}
|
||||
}
|
||||
|
||||
public static int slotSize(ClassDesc desc) {
|
||||
return switch (desc.descriptorString().charAt(0)) {
|
||||
case 'V' -> 0;
|
||||
@ -216,7 +243,7 @@ public class Util {
|
||||
clb.withMethod(methodName, methodDesc, acc, mb ->
|
||||
((DirectMethodBuilder)mb).writeAttribute(new UnboundAttribute.AdHocAttribute<CodeAttribute>(Attributes.code()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(-1);//max stack
|
||||
b.writeU2(-1);//max locals
|
||||
b.writeInt(bytecode.limit());
|
||||
@ -237,4 +264,28 @@ public class Util {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeListIndices(BufWriter writer, List<? extends PoolEntry> list) {
|
||||
writer.writeU2(list.size());
|
||||
for (PoolEntry info : list) {
|
||||
writer.writeIndex(info);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean writeLocalVariable(BufWriterImpl buf, PseudoInstruction lvOrLvt) {
|
||||
return ((WritableLocalVariable) lvOrLvt).writeLocalTo(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic interface for objects to write to a
|
||||
* buf writer. Do not implement unless necessary,
|
||||
* as this writeTo is public, which can be troublesome.
|
||||
*/
|
||||
interface Writable {
|
||||
void writeTo(BufWriterImpl writer);
|
||||
}
|
||||
|
||||
interface WritableLocalVariable {
|
||||
boolean writeLocalTo(BufWriterImpl buf);
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
* @summary Testing BoundAttributes
|
||||
* @run junit BoundAttributeTest
|
||||
*/
|
||||
import jdk.internal.classfile.impl.BufWriterImpl;
|
||||
import jdk.internal.classfile.impl.DirectClassBuilder;
|
||||
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@ -34,7 +35,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
|
||||
import java.lang.classfile.Attributes;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.classfile.ClassModel;
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.classfile.CodeBuilder;
|
||||
@ -84,7 +84,7 @@ class BoundAttributeTest {
|
||||
var oneClass = cp.classEntry(oneClassString);
|
||||
((DirectClassBuilder) clb).writeAttribute(new UnboundAttribute.AdHocAttribute<>(Attributes.nestMembers()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(2);
|
||||
b.writeIndex(oneClass);
|
||||
b.writeIndex(oneClassString);
|
||||
|
@ -31,6 +31,8 @@
|
||||
import helpers.ClassRecord;
|
||||
import helpers.ClassRecord.CompatibilityFilter;
|
||||
import helpers.Transforms;
|
||||
import jdk.internal.classfile.impl.BufWriterImpl;
|
||||
import jdk.internal.classfile.impl.Util;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.api.parallel.Execution;
|
||||
@ -85,7 +87,7 @@ class CorpusTest {
|
||||
switch (coe) {
|
||||
case LineNumber ln -> dcob.writeAttribute(new UnboundAttribute.AdHocAttribute<>(Attributes.lineNumberTable()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(1);
|
||||
b.writeU2(curPc);
|
||||
b.writeU2(ln.line());
|
||||
@ -93,16 +95,16 @@ class CorpusTest {
|
||||
});
|
||||
case LocalVariable lv -> dcob.writeAttribute(new UnboundAttribute.AdHocAttribute<>(Attributes.localVariableTable()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(1);
|
||||
lv.writeTo(b);
|
||||
Util.writeLocalVariable(b, lv);
|
||||
}
|
||||
});
|
||||
case LocalVariableType lvt -> dcob.writeAttribute(new UnboundAttribute.AdHocAttribute<>(Attributes.localVariableTypeTable()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(1);
|
||||
lvt.writeTo(b);
|
||||
Util.writeLocalVariable(b, lvt);
|
||||
}
|
||||
});
|
||||
default -> cob.with(coe);
|
||||
|
@ -28,7 +28,6 @@
|
||||
* @run junit LimitsTest
|
||||
*/
|
||||
import java.lang.classfile.Attributes;
|
||||
import java.lang.classfile.BufWriter;
|
||||
import java.lang.constant.ClassDesc;
|
||||
import java.lang.constant.ConstantDescs;
|
||||
import java.lang.constant.MethodTypeDesc;
|
||||
@ -44,6 +43,8 @@ import java.lang.classfile.constantpool.ConstantPoolException;
|
||||
import java.lang.classfile.constantpool.IntegerEntry;
|
||||
import java.lang.classfile.instruction.LocalVariable;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.internal.classfile.impl.BufWriterImpl;
|
||||
import jdk.internal.classfile.impl.DirectCodeBuilder;
|
||||
import jdk.internal.classfile.impl.DirectMethodBuilder;
|
||||
import jdk.internal.classfile.impl.LabelContext;
|
||||
@ -130,7 +131,7 @@ class LimitsTest {
|
||||
"lookupSwitchMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, mb ->
|
||||
((DirectMethodBuilder)mb).writeAttribute(new UnboundAttribute.AdHocAttribute<CodeAttribute>(Attributes.code()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(-1);//max stack
|
||||
b.writeU2(-1);//max locals
|
||||
b.writeInt(16);
|
||||
@ -155,7 +156,7 @@ class LimitsTest {
|
||||
"tableSwitchMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, mb ->
|
||||
((DirectMethodBuilder)mb).writeAttribute(new UnboundAttribute.AdHocAttribute<CodeAttribute>(Attributes.code()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(-1);//max stack
|
||||
b.writeU2(-1);//max locals
|
||||
b.writeInt(16);
|
||||
@ -173,7 +174,7 @@ class LimitsTest {
|
||||
"tableSwitchMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, mb ->
|
||||
((DirectMethodBuilder)mb).writeAttribute(new UnboundAttribute.AdHocAttribute<CodeAttribute>(Attributes.code()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(-1);//max stack
|
||||
b.writeU2(-1);//max locals
|
||||
b.writeInt(20);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,11 +39,8 @@ import java.lang.classfile.AccessFlags;
|
||||
import java.lang.reflect.AccessFlag;
|
||||
import java.lang.classfile.ClassModel;
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.classfile.Opcode;
|
||||
import java.lang.classfile.TypeKind;
|
||||
import helpers.ByteArrayClassLoader;
|
||||
import java.lang.classfile.attribute.SourceFileAttribute;
|
||||
import jdk.internal.classfile.impl.DirectClassBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
@ -75,7 +72,7 @@ class LowAdaptTest {
|
||||
byte[] clazz = cc.build(ClassDesc.of(test), cb -> {
|
||||
cb.withFlags(AccessFlag.PUBLIC);
|
||||
cb.with(SourceFileAttribute.of("/some/madeup/TestClass.java"));
|
||||
cl.methods().forEach(m -> ((DirectClassBuilder) cb).withMethod(m));
|
||||
cl.methods().forEach(cb::with);
|
||||
|
||||
cb.withMethod("doit", MethodTypeDesc.of(CD_int, CD_int),
|
||||
AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(),
|
||||
|
@ -47,6 +47,8 @@ import java.lang.classfile.*;
|
||||
import java.lang.classfile.attribute.*;
|
||||
import java.lang.classfile.components.ClassPrinter;
|
||||
import java.lang.constant.ModuleDesc;
|
||||
|
||||
import jdk.internal.classfile.impl.BufWriterImpl;
|
||||
import jdk.internal.classfile.impl.DirectClassBuilder;
|
||||
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -103,7 +105,7 @@ class VerifierSelfTest {
|
||||
var bytes = cc.build(ClassDesc.of("InvalidAttrLocationClass"), cb ->
|
||||
((DirectClassBuilder)cb).writeAttribute(new UnboundAttribute.AdHocAttribute<LocalVariableTableAttribute>(Attributes.localVariableTable()) {
|
||||
@Override
|
||||
public void writeBody(BufWriter b) {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(0);
|
||||
}
|
||||
}));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -70,8 +70,8 @@ public class AnnotationDefaultVerifier {
|
||||
|
||||
private abstract class TestElementValue {
|
||||
public void testLength(TestResult testCase, AnnotationDefaultAttribute attr) {
|
||||
BufWriter buf = new BufWriterImpl(ConstantPoolBuilder.of(), (ClassFileImpl) ClassFile.of());
|
||||
attr.defaultValue().writeTo(buf);
|
||||
var buf = new BufWriterImpl(ConstantPoolBuilder.of(), (ClassFileImpl) ClassFile.of());
|
||||
AnnotationReader.writeAnnotationValue(buf, attr.defaultValue());
|
||||
testCase.checkEquals(((BoundAttribute<?>)attr).payloadLen(), buf.size(),
|
||||
"attribute_length");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user