--- old/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java 2016-12-15 09:19:11.983063674 +0000 +++ new/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java 2016-12-15 09:19:11.854054849 +0000 @@ -68,12 +68,18 @@ = 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); } @@ -86,46 +92,70 @@ int codeOff, Label[] labels) { - ModuleAttribute attr = new ModuleAttribute(); - - // module_name - String mn = cr.readUTF8(off, buf).replace('/', '.'); + // 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; - if (open) { - builder = JLMA.newOpenModuleBuilder(mn, false); - } else { - builder = JLMA.newModuleBuilder(mn, false); + 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 mods; - if (flags == 0) { + if (requires_flags == 0) { mods = Collections.emptySet(); } else { mods = new HashSet<>(); - if ((flags & ACC_TRANSITIVE) != 0) + if ((requires_flags & ACC_TRANSITIVE) != 0) mods.add(Requires.Modifier.TRANSITIVE); - if ((flags & ACC_STATIC_PHASE) != 0) + if ((requires_flags & ACC_STATIC_PHASE) != 0) mods.add(Requires.Modifier.STATIC); - if ((flags & ACC_SYNTHETIC) != 0) + if ((requires_flags & ACC_SYNTHETIC) != 0) mods.add(Requires.Modifier.SYNTHETIC); - if ((flags & ACC_MANDATED) != 0) + if ((requires_flags & ACC_MANDATED) != 0) mods.add(Requires.Modifier.MANDATED); } - builder.requires(mods, dn); - off += 4; + + + // 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] @@ -133,19 +163,20 @@ off += 2; if (exports_count > 0) { for (int i=0; i mods; - if (flags == 0) { + if (exports_flags == 0) { mods = Collections.emptySet(); } else { mods = new HashSet<>(); - if ((flags & ACC_SYNTHETIC) != 0) + if ((exports_flags & ACC_SYNTHETIC) != 0) mods.add(Exports.Modifier.SYNTHETIC); - if ((flags & ACC_MANDATED) != 0) + if ((exports_flags & ACC_MANDATED) != 0) mods.add(Exports.Modifier.MANDATED); } @@ -154,7 +185,7 @@ if (exports_to_count > 0) { Set targets = new HashSet<>(); for (int j=0; j 0) { for (int i=0; i mods; - if (flags == 0) { + if (opens_flags == 0) { mods = Collections.emptySet(); } else { mods = new HashSet<>(); - if ((flags & ACC_SYNTHETIC) != 0) + if ((opens_flags & ACC_SYNTHETIC) != 0) mods.add(Opens.Modifier.SYNTHETIC); - if ((flags & ACC_MANDATED) != 0) + if ((opens_flags & ACC_MANDATED) != 0) mods.add(Opens.Modifier.MANDATED); } @@ -191,7 +223,7 @@ if (opens_to_count > 0) { Set targets = new HashSet<>(); for (int j=0; j ts = e.targets(); attr.putShort(ts.size()); - ts.forEach(t -> attr.putShort(cw.newUTF8(t.replace('.', '/')))); + 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.newUTF8(pkg)); + attr.putShort(cw.newPackage(pkg)); - int flags = 0; + int opens_flags = 0; if (obj.modifiers().contains(Opens.Modifier.SYNTHETIC)) - flags |= ACC_SYNTHETIC; + opens_flags |= ACC_SYNTHETIC; if (obj.modifiers().contains(Opens.Modifier.MANDATED)) - flags |= ACC_MANDATED; - attr.putShort(flags); + opens_flags |= ACC_MANDATED; + attr.putShort(opens_flags); if (obj.isQualified()) { Set ts = obj.targets(); attr.putShort(ts.size()); - ts.forEach(t -> attr.putShort(cw.newUTF8(t.replace('.', '/')))); + ts.forEach(target -> attr.putShort(cw.newModule(target))); } else { attr.putShort(0); } @@ -369,7 +417,7 @@ * * // the number of entries in the packages table * u2 packages_count; - * { // index to CONSTANT_CONSTANT_utf8_info structure with the package name + * { // index to CONSTANT_Package_info structure with the package name * u2 package_index * } packages[package_count]; * @@ -402,7 +450,7 @@ // packages Set packages = new HashSet<>(); for (int i=0; i p.replace('.', '/')) - .forEach(p -> attr.putShort(cw.newUTF8(p))); + .forEach(p -> attr.putShort(cw.newPackage(p))); return attr; } @@ -435,61 +483,6 @@ } /** - * ModuleVersion attribute. - * - *
 {@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;
-     * }
-     *
-     * } 
- */ - 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. * *
 {@code
@@ -526,7 +519,7 @@
                                  int codeOff,
                                  Label[] labels)
         {
-            String value = cr.readClass(off, buf);
+            String value = cr.readClass(off, buf).replace('/', '.');
             return new ModuleMainClassAttribute(value);
         }
 
@@ -538,7 +531,7 @@
                                    int maxLocals)
         {
             ByteVector attr = new ByteVector();
-            int index = cw.newClass(mainClass);
+            int index = cw.newClass(mainClass.replace('.', '/'));
             attr.putShort(index);
             return attr;
         }
@@ -555,11 +548,11 @@
      *   u2 attribute_name_index;
      *   u4 attribute_length;
      *
-     *   // index to CONSTANT_CONSTANT_utf8_info structure with the OS name
+     *   // index to CONSTANT_utf8_info structure with the OS name
      *   u2 os_name_index;
-     *   // index to CONSTANT_CONSTANT_utf8_info structure with the OS arch
+     *   // index to CONSTANT_utf8_info structure with the OS arch
      *   u2 os_arch_index
-     *   // index to CONSTANT_CONSTANT_utf8_info structure with the OS version
+     *   // index to CONSTANT_utf8_info structure with the OS version
      *   u2 os_version_index;
      * }
      *
@@ -656,7 +649,7 @@
      *
      *   // the number of entries in the hashes table
      *   u2 hashes_count;
-     *   {   u2 module_name_index
+     *   {   u2 module_name_index (index to CONSTANT_Module_info structure)
      *       u2 hash_length;
      *       u1 hash[hash_length];
      *   } hashes[hashes_count];
@@ -691,7 +684,7 @@
 
             Map map = new HashMap<>();
             for (int i=0; i