< prev index next >
src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java
Print this page
*** 66,81 ****
--- 66,87 ----
public static class ModuleAttribute extends Attribute {
private static final JavaLangModuleAccess JLMA
= SharedSecrets.getJavaLangModuleAccess();
private ModuleDescriptor descriptor;
+ private Version replacementVersion;
public ModuleAttribute(ModuleDescriptor descriptor) {
super(MODULE);
this.descriptor = descriptor;
}
+ public ModuleAttribute(Version v) {
+ super(MODULE);
+ this.replacementVersion = v;
+ }
+
public ModuleAttribute() {
super(MODULE);
}
@Override
*** 84,162 ****
int len,
char[] buf,
int codeOff,
Label[] labels)
{
! ModuleAttribute attr = new ModuleAttribute();
!
! // module_name
! String mn = cr.readUTF8(off, buf).replace('/', '.');
off += 2;
// module_flags
int module_flags = cr.readUnsignedShort(off);
boolean open = ((module_flags & ACC_OPEN) != 0);
off += 2;
! ModuleDescriptor.Builder builder;
! if (open) {
! builder = JLMA.newOpenModuleBuilder(mn, false);
! } else {
! builder = JLMA.newModuleBuilder(mn, false);
}
// requires_count and requires[requires_count]
int requires_count = cr.readUnsignedShort(off);
off += 2;
for (int i=0; i<requires_count; i++) {
! String dn = cr.readUTF8(off, buf).replace('/', '.');
! int flags = cr.readUnsignedShort(off + 2);
Set<Requires.Modifier> mods;
! if (flags == 0) {
mods = Collections.emptySet();
} else {
mods = new HashSet<>();
! if ((flags & ACC_TRANSITIVE) != 0)
mods.add(Requires.Modifier.TRANSITIVE);
! if ((flags & ACC_STATIC_PHASE) != 0)
mods.add(Requires.Modifier.STATIC);
! if ((flags & ACC_SYNTHETIC) != 0)
mods.add(Requires.Modifier.SYNTHETIC);
! if ((flags & ACC_MANDATED) != 0)
mods.add(Requires.Modifier.MANDATED);
}
builder.requires(mods, dn);
! off += 4;
}
// exports_count and exports[exports_count]
int exports_count = cr.readUnsignedShort(off);
off += 2;
if (exports_count > 0) {
for (int i=0; i<exports_count; i++) {
! String pkg = cr.readUTF8(off, buf).replace('/', '.');
off += 2;
! int flags = cr.readUnsignedShort(off);
off += 2;
Set<Exports.Modifier> mods;
! if (flags == 0) {
mods = Collections.emptySet();
} else {
mods = new HashSet<>();
! if ((flags & ACC_SYNTHETIC) != 0)
mods.add(Exports.Modifier.SYNTHETIC);
! if ((flags & ACC_MANDATED) != 0)
mods.add(Exports.Modifier.MANDATED);
}
int exports_to_count = cr.readUnsignedShort(off);
off += 2;
if (exports_to_count > 0) {
Set<String> targets = new HashSet<>();
for (int j=0; j<exports_to_count; j++) {
! String t = cr.readUTF8(off, buf).replace('/', '.');
off += 2;
targets.add(t);
}
builder.exports(mods, pkg, targets);
} else {
--- 90,193 ----
int len,
char[] buf,
int codeOff,
Label[] labels)
{
! // module_name (CONSTANT_Module_info)
! String mn = cr.readModule(off, buf);
off += 2;
// module_flags
int module_flags = cr.readUnsignedShort(off);
boolean open = ((module_flags & ACC_OPEN) != 0);
+ boolean synthetic = ((module_flags & ACC_SYNTHETIC) != 0);
off += 2;
! ModuleDescriptor.Builder builder = JLMA.newModuleBuilder(mn,
! false,
! open,
! synthetic);
!
! // module_version
! String module_version = cr.readUTF8(off, buf);
! off += 2;
! if (replacementVersion != null) {
! builder.version(replacementVersion);
! } else if (module_version != null) {
! builder.version(module_version);
}
// requires_count and requires[requires_count]
int requires_count = cr.readUnsignedShort(off);
off += 2;
for (int i=0; i<requires_count; i++) {
! // CONSTANT_Module_info
! String dn = cr.readModule(off, buf);
! off += 2;
!
! // requires_flags
! int requires_flags = cr.readUnsignedShort(off);
! off += 2;
Set<Requires.Modifier> mods;
! if (requires_flags == 0) {
mods = Collections.emptySet();
} else {
mods = new HashSet<>();
! if ((requires_flags & ACC_TRANSITIVE) != 0)
mods.add(Requires.Modifier.TRANSITIVE);
! if ((requires_flags & ACC_STATIC_PHASE) != 0)
mods.add(Requires.Modifier.STATIC);
! if ((requires_flags & ACC_SYNTHETIC) != 0)
mods.add(Requires.Modifier.SYNTHETIC);
! if ((requires_flags & ACC_MANDATED) != 0)
mods.add(Requires.Modifier.MANDATED);
}
+
+
+ // requires_version
+ Version compiledVersion = null;
+ String requires_version = cr.readUTF8(off, buf);
+ off += 2;
+ if (requires_version != null) {
+ compiledVersion = Version.parse(requires_version);
+ }
+
+ if (compiledVersion == null) {
builder.requires(mods, dn);
! } else {
! builder.requires(mods, dn, compiledVersion);
! }
}
// exports_count and exports[exports_count]
int exports_count = cr.readUnsignedShort(off);
off += 2;
if (exports_count > 0) {
for (int i=0; i<exports_count; i++) {
! // CONSTANT_Package_info
! String pkg = cr.readPackage(off, buf).replace('/', '.');
off += 2;
! int exports_flags = cr.readUnsignedShort(off);
off += 2;
Set<Exports.Modifier> mods;
! if (exports_flags == 0) {
mods = Collections.emptySet();
} else {
mods = new HashSet<>();
! if ((exports_flags & ACC_SYNTHETIC) != 0)
mods.add(Exports.Modifier.SYNTHETIC);
! if ((exports_flags & ACC_MANDATED) != 0)
mods.add(Exports.Modifier.MANDATED);
}
int exports_to_count = cr.readUnsignedShort(off);
off += 2;
if (exports_to_count > 0) {
Set<String> targets = new HashSet<>();
for (int j=0; j<exports_to_count; j++) {
! String t = cr.readModule(off, buf);
off += 2;
targets.add(t);
}
builder.exports(mods, pkg, targets);
} else {
*** 168,199 ****
// opens_count and opens[opens_count]
int open_count = cr.readUnsignedShort(off);
off += 2;
if (open_count > 0) {
for (int i=0; i<open_count; i++) {
! String pkg = cr.readUTF8(off, buf).replace('/', '.');
off += 2;
! int flags = cr.readUnsignedShort(off);
off += 2;
Set<Opens.Modifier> mods;
! if (flags == 0) {
mods = Collections.emptySet();
} else {
mods = new HashSet<>();
! if ((flags & ACC_SYNTHETIC) != 0)
mods.add(Opens.Modifier.SYNTHETIC);
! if ((flags & ACC_MANDATED) != 0)
mods.add(Opens.Modifier.MANDATED);
}
int opens_to_count = cr.readUnsignedShort(off);
off += 2;
if (opens_to_count > 0) {
Set<String> targets = new HashSet<>();
for (int j=0; j<opens_to_count; j++) {
! String t = cr.readUTF8(off, buf).replace('/', '.');
off += 2;
targets.add(t);
}
builder.opens(mods, pkg, targets);
} else {
--- 199,231 ----
// opens_count and opens[opens_count]
int open_count = cr.readUnsignedShort(off);
off += 2;
if (open_count > 0) {
for (int i=0; i<open_count; i++) {
! // CONSTANT_Package_info
! String pkg = cr.readPackage(off, buf).replace('/', '.');
off += 2;
! int opens_flags = cr.readUnsignedShort(off);
off += 2;
Set<Opens.Modifier> mods;
! if (opens_flags == 0) {
mods = Collections.emptySet();
} else {
mods = new HashSet<>();
! if ((opens_flags & ACC_SYNTHETIC) != 0)
mods.add(Opens.Modifier.SYNTHETIC);
! if ((opens_flags & ACC_MANDATED) != 0)
mods.add(Opens.Modifier.MANDATED);
}
int opens_to_count = cr.readUnsignedShort(off);
off += 2;
if (opens_to_count > 0) {
Set<String> targets = new HashSet<>();
for (int j=0; j<opens_to_count; j++) {
! String t = cr.readModule(off, buf);
off += 2;
targets.add(t);
}
builder.opens(mods, pkg, targets);
} else {
*** 230,241 ****
}
builder.provides(service, providers);
}
}
! attr.descriptor = builder.build();
! return attr;
}
@Override
protected ByteVector write(ClassWriter cw,
byte[] code,
--- 262,272 ----
}
builder.provides(service, providers);
}
}
! return new ModuleAttribute(builder.build());
}
@Override
protected ByteVector write(ClassWriter cw,
byte[] code,
*** 246,326 ****
assert descriptor != null;
ByteVector attr = new ByteVector();
// module_name
String mn = descriptor.name();
! int module_name_index = cw.newUTF8(mn.replace('.', '/'));
attr.putShort(module_name_index);
// module_flags
int module_flags = 0;
if (descriptor.isOpen())
module_flags |= ACC_OPEN;
if (descriptor.isSynthetic())
module_flags |= ACC_SYNTHETIC;
attr.putShort(module_flags);
// requires_count
attr.putShort(descriptor.requires().size());
// requires[requires_count]
! for (Requires md : descriptor.requires()) {
! String dn = md.name();
! int flags = 0;
! if (md.modifiers().contains(Requires.Modifier.TRANSITIVE))
! flags |= ACC_TRANSITIVE;
! if (md.modifiers().contains(Requires.Modifier.STATIC))
! flags |= ACC_STATIC_PHASE;
! if (md.modifiers().contains(Requires.Modifier.SYNTHETIC))
! flags |= ACC_SYNTHETIC;
! if (md.modifiers().contains(Requires.Modifier.MANDATED))
! flags |= ACC_MANDATED;
! int index = cw.newUTF8(dn.replace('.', '/'));
! attr.putShort(index);
! attr.putShort(flags);
}
// exports_count and exports[exports_count];
attr.putShort(descriptor.exports().size());
for (Exports e : descriptor.exports()) {
String pkg = e.source().replace('.', '/');
! attr.putShort(cw.newUTF8(pkg));
! int flags = 0;
if (e.modifiers().contains(Exports.Modifier.SYNTHETIC))
! flags |= ACC_SYNTHETIC;
if (e.modifiers().contains(Exports.Modifier.MANDATED))
! flags |= ACC_MANDATED;
! attr.putShort(flags);
if (e.isQualified()) {
Set<String> ts = e.targets();
attr.putShort(ts.size());
! ts.forEach(t -> attr.putShort(cw.newUTF8(t.replace('.', '/'))));
} else {
attr.putShort(0);
}
}
-
// opens_counts and opens[opens_counts]
attr.putShort(descriptor.opens().size());
for (Opens obj : descriptor.opens()) {
String pkg = obj.source().replace('.', '/');
! attr.putShort(cw.newUTF8(pkg));
! int flags = 0;
if (obj.modifiers().contains(Opens.Modifier.SYNTHETIC))
! flags |= ACC_SYNTHETIC;
if (obj.modifiers().contains(Opens.Modifier.MANDATED))
! flags |= ACC_MANDATED;
! attr.putShort(flags);
if (obj.isQualified()) {
Set<String> ts = obj.targets();
attr.putShort(ts.size());
! ts.forEach(t -> attr.putShort(cw.newUTF8(t.replace('.', '/'))));
} else {
attr.putShort(0);
}
}
--- 277,374 ----
assert descriptor != null;
ByteVector attr = new ByteVector();
// module_name
String mn = descriptor.name();
! int module_name_index = cw.newModule(mn);
attr.putShort(module_name_index);
// module_flags
int module_flags = 0;
if (descriptor.isOpen())
module_flags |= ACC_OPEN;
if (descriptor.isSynthetic())
module_flags |= ACC_SYNTHETIC;
attr.putShort(module_flags);
+ // module_version
+ Version v = descriptor.version().orElse(null);
+ if (v == null) {
+ attr.putShort(0);
+ } else {
+ int module_version_index = cw.newUTF8(v.toString());
+ attr.putShort(module_version_index);
+ }
+
// requires_count
attr.putShort(descriptor.requires().size());
// requires[requires_count]
! for (Requires r : descriptor.requires()) {
! int requires_index = cw.newModule(r.name());
! attr.putShort(requires_index);
!
! int requires_flags = 0;
! if (r.modifiers().contains(Requires.Modifier.TRANSITIVE))
! requires_flags |= ACC_TRANSITIVE;
! if (r.modifiers().contains(Requires.Modifier.STATIC))
! requires_flags |= ACC_STATIC_PHASE;
! if (r.modifiers().contains(Requires.Modifier.SYNTHETIC))
! requires_flags |= ACC_SYNTHETIC;
! if (r.modifiers().contains(Requires.Modifier.MANDATED))
! requires_flags |= ACC_MANDATED;
! attr.putShort(requires_flags);
!
! int requires_version_index;
! v = r.compiledVersion().orElse(null);
! if (v == null) {
! requires_version_index = 0;
! } else {
! requires_version_index = cw.newUTF8(v.toString());
! }
! attr.putShort(requires_version_index);
}
// exports_count and exports[exports_count];
attr.putShort(descriptor.exports().size());
for (Exports e : descriptor.exports()) {
String pkg = e.source().replace('.', '/');
! attr.putShort(cw.newPackage(pkg));
! int exports_flags = 0;
if (e.modifiers().contains(Exports.Modifier.SYNTHETIC))
! exports_flags |= ACC_SYNTHETIC;
if (e.modifiers().contains(Exports.Modifier.MANDATED))
! exports_flags |= ACC_MANDATED;
! attr.putShort(exports_flags);
if (e.isQualified()) {
Set<String> ts = e.targets();
attr.putShort(ts.size());
! ts.forEach(target -> attr.putShort(cw.newModule(target)));
} else {
attr.putShort(0);
}
}
// opens_counts and opens[opens_counts]
attr.putShort(descriptor.opens().size());
for (Opens obj : descriptor.opens()) {
String pkg = obj.source().replace('.', '/');
! attr.putShort(cw.newPackage(pkg));
! int opens_flags = 0;
if (obj.modifiers().contains(Opens.Modifier.SYNTHETIC))
! opens_flags |= ACC_SYNTHETIC;
if (obj.modifiers().contains(Opens.Modifier.MANDATED))
! opens_flags |= ACC_MANDATED;
! attr.putShort(opens_flags);
if (obj.isQualified()) {
Set<String> ts = obj.targets();
attr.putShort(ts.size());
! ts.forEach(target -> attr.putShort(cw.newModule(target)));
} else {
attr.putShort(0);
}
}
*** 367,377 ****
* u2 attribute_name_index;
* u4 attribute_length;
*
* // the number of entries in the packages table
* u2 packages_count;
! * { // index to CONSTANT_CONSTANT_utf8_info structure with the package name
* u2 package_index
* } packages[package_count];
*
* }</pre>
*/
--- 415,425 ----
* u2 attribute_name_index;
* u4 attribute_length;
*
* // the number of entries in the packages table
* u2 packages_count;
! * { // index to CONSTANT_Package_info structure with the package name
* u2 package_index
* } packages[package_count];
*
* }</pre>
*/
*** 400,410 ****
off += 2;
// packages
Set<String> packages = new HashSet<>();
for (int i=0; i<package_count; i++) {
! String pkg = cr.readUTF8(off, buf).replace('/', '.');
packages.add(pkg);
off += 2;
}
return new ModulePackagesAttribute(packages);
--- 448,458 ----
off += 2;
// packages
Set<String> packages = new HashSet<>();
for (int i=0; i<package_count; i++) {
! String pkg = cr.readPackage(off, buf).replace('/', '.');
packages.add(pkg);
off += 2;
}
return new ModulePackagesAttribute(packages);
*** 425,497 ****
attr.putShort(packages.size());
// packages
packages.stream()
.map(p -> p.replace('.', '/'))
! .forEach(p -> attr.putShort(cw.newUTF8(p)));
return attr;
}
}
/**
- * ModuleVersion attribute.
- *
- * <pre> {@code
- *
- * ModuleVersion_attribute {
- * // index to CONSTANT_utf8_info structure in constant pool representing
- * // the string "ModuleVersion"
- * u2 attribute_name_index;
- * u4 attribute_length;
- *
- * // index to CONSTANT_CONSTANT_utf8_info structure with the version
- * u2 version_index;
- * }
- *
- * } </pre>
- */
- public static class ModuleVersionAttribute extends Attribute {
- private final Version version;
-
- public ModuleVersionAttribute(Version version) {
- super(MODULE_VERSION);
- this.version = version;
- }
-
- public ModuleVersionAttribute() {
- this(null);
- }
-
- @Override
- protected Attribute read(ClassReader cr,
- int off,
- int len,
- char[] buf,
- int codeOff,
- Label[] labels)
- {
- String value = cr.readUTF8(off, buf);
- return new ModuleVersionAttribute(Version.parse(value));
- }
-
- @Override
- protected ByteVector write(ClassWriter cw,
- byte[] code,
- int len,
- int maxStack,
- int maxLocals)
- {
- ByteVector attr = new ByteVector();
- int index = cw.newUTF8(version.toString());
- attr.putShort(index);
- return attr;
- }
- }
-
- /**
* ModuleMainClass attribute.
*
* <pre> {@code
*
* MainClass_attribute {
--- 473,490 ----
attr.putShort(packages.size());
// packages
packages.stream()
.map(p -> p.replace('.', '/'))
! .forEach(p -> attr.putShort(cw.newPackage(p)));
return attr;
}
}
/**
* ModuleMainClass attribute.
*
* <pre> {@code
*
* MainClass_attribute {
*** 524,534 ****
int len,
char[] buf,
int codeOff,
Label[] labels)
{
! String value = cr.readClass(off, buf);
return new ModuleMainClassAttribute(value);
}
@Override
protected ByteVector write(ClassWriter cw,
--- 517,527 ----
int len,
char[] buf,
int codeOff,
Label[] labels)
{
! String value = cr.readClass(off, buf).replace('/', '.');
return new ModuleMainClassAttribute(value);
}
@Override
protected ByteVector write(ClassWriter cw,
*** 536,546 ****
int len,
int maxStack,
int maxLocals)
{
ByteVector attr = new ByteVector();
! int index = cw.newClass(mainClass);
attr.putShort(index);
return attr;
}
}
--- 529,539 ----
int len,
int maxStack,
int maxLocals)
{
ByteVector attr = new ByteVector();
! int index = cw.newClass(mainClass.replace('.', '/'));
attr.putShort(index);
return attr;
}
}
*** 553,567 ****
* // index to CONSTANT_utf8_info structure in constant pool representing
* // the string "ModuleTarget"
* u2 attribute_name_index;
* u4 attribute_length;
*
! * // index to CONSTANT_CONSTANT_utf8_info structure with the OS name
* u2 os_name_index;
! * // index to CONSTANT_CONSTANT_utf8_info structure with the OS arch
* u2 os_arch_index
! * // index to CONSTANT_CONSTANT_utf8_info structure with the OS version
* u2 os_version_index;
* }
*
* } </pre>
*/
--- 546,560 ----
* // index to CONSTANT_utf8_info structure in constant pool representing
* // the string "ModuleTarget"
* u2 attribute_name_index;
* u4 attribute_length;
*
! * // index to CONSTANT_utf8_info structure with the OS name
* u2 os_name_index;
! * // index to CONSTANT_utf8_info structure with the OS arch
* u2 os_arch_index
! * // index to CONSTANT_utf8_info structure with the OS version
* u2 os_version_index;
* }
*
* } </pre>
*/
*** 654,664 ****
* // index to CONSTANT_utf8_info structure with algorithm name
* u2 algorithm_index;
*
* // the number of entries in the hashes table
* u2 hashes_count;
! * { u2 module_name_index
* u2 hash_length;
* u1 hash[hash_length];
* } hashes[hashes_count];
*
* } </pre>
--- 647,657 ----
* // index to CONSTANT_utf8_info structure with algorithm name
* u2 algorithm_index;
*
* // the number of entries in the hashes table
* u2 hashes_count;
! * { u2 module_name_index (index to CONSTANT_Module_info structure)
* u2 hash_length;
* u1 hash[hash_length];
* } hashes[hashes_count];
*
* } </pre>
*** 689,699 ****
int hashes_count = cr.readUnsignedShort(off);
off += 2;
Map<String, byte[]> map = new HashMap<>();
for (int i=0; i<hashes_count; i++) {
! String mn = cr.readUTF8(off, buf).replace('/', '.');
off += 2;
int hash_length = cr.readUnsignedShort(off);
off += 2;
byte[] hash = new byte[hash_length];
--- 682,692 ----
int hashes_count = cr.readUnsignedShort(off);
off += 2;
Map<String, byte[]> map = new HashMap<>();
for (int i=0; i<hashes_count; i++) {
! String mn = cr.readModule(off, buf);
off += 2;
int hash_length = cr.readUnsignedShort(off);
off += 2;
byte[] hash = new byte[hash_length];
*** 726,736 ****
attr.putShort(names.size());
for (String mn : names) {
byte[] hash = hashes.hashFor(mn);
assert hash != null;
! attr.putShort(cw.newUTF8(mn.replace('.', '/')));
attr.putShort(hash.length);
for (byte b: hash) {
attr.putByte(b);
}
--- 719,729 ----
attr.putShort(names.size());
for (String mn : names) {
byte[] hash = hashes.hashFor(mn);
assert hash != null;
! attr.putShort(cw.newModule(mn));
attr.putShort(hash.length);
for (byte b: hash) {
attr.putByte(b);
}
*** 738,743 ****
--- 731,790 ----
return attr;
}
}
+ /**
+ * ModuleResolution_attribute {
+ * u2 attribute_name_index; // "ModuleResolution"
+ * u4 attribute_length; // 2
+ * u2 resolution_flags;
+ *
+ * The value of the resolution_flags item is a mask of flags used to denote
+ * properties of module resolution. The flags are as follows:
+ *
+ * // Optional
+ * 0x0001 (DO_NOT_RESOLVE_BY_DEFAULT)
+ *
+ * // At most one of:
+ * 0x0002 (WARN_DEPRECATED)
+ * 0x0004 (WARN_DEPRECATED_FOR_REMOVAL)
+ * 0x0008 (WARN_INCUBATING)
+ */
+ static class ModuleResolutionAttribute extends Attribute {
+ private final int value;
+
+ ModuleResolutionAttribute() {
+ super(MODULE_RESOLUTION);
+ value = 0;
+ }
+
+ ModuleResolutionAttribute(int value) {
+ super(MODULE_RESOLUTION);
+ this.value = value;
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr,
+ int off,
+ int len,
+ char[] buf,
+ int codeOff,
+ Label[] labels)
+ {
+ int flags = cr.readUnsignedShort(off);
+ return new ModuleResolutionAttribute(flags);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw,
+ byte[] code,
+ int len,
+ int maxStack,
+ int maxLocals)
+ {
+ ByteVector attr = new ByteVector();
+ attr.putShort(value);
+ return attr;
+ }
+ }
}
< prev index next >