changeset 19:f788f629bb40 7.0-b02

CODETOOLS-7902070 jasm incorrectly processes class file versions inlined into jasm's files with more than one class, contributed by: leonid.kuskov@oracle.com
author afedorch
date Tue, 28 Nov 2017 15:03:21 -0800
parents 51618da7aecc
children 872f704a0d9a
files src/org/openjdk/asmtools/jasm/CFVersion.java src/org/openjdk/asmtools/jasm/ClassData.java src/org/openjdk/asmtools/jasm/Main.java src/org/openjdk/asmtools/jasm/Parser.java
diffstat 4 files changed, 46 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/openjdk/asmtools/jasm/CFVersion.java	Wed Nov 08 16:44:53 2017 -0800
+++ b/src/org/openjdk/asmtools/jasm/CFVersion.java	Tue Nov 28 15:03:21 2017 -0800
@@ -25,7 +25,7 @@
 /*
  * Class File Version
  */
-public class CFVersion {
+public class CFVersion implements Cloneable{
     /**
      * Default versions of class file
      */
@@ -37,6 +37,7 @@
 
     private short major_version;
     private short minor_version;
+    private boolean frozen = false;
 
     public CFVersion() {
         major_version = UNDEFINED_VERSION;
@@ -44,17 +45,18 @@
     }
 
     public CFVersion(short major_version, short minor_version) {
+        frozen = true;
         this.major_version = major_version;
         this.minor_version = minor_version;
     }
 
     public void setMajorVersion(short major_version) {
-        if ( !isSet() )
+        if ( !frozen )
             this.major_version = major_version;
     }
 
     public void setMinorVersion(short minor_version) {
-        if ( !isSet() )
+        if (!frozen)
             this.minor_version = minor_version;
     }
 
@@ -74,7 +76,7 @@
     }
 
     public void initClassDefaults() {
-        if( ! isSet()) {
+        if( !isSet() ) {
             major_version = DEFAULT_MAJOR_VERSION;
             minor_version = DEFAULT_MINOR_VERSION;
         }
@@ -87,4 +89,12 @@
     public short major_version() {
         return this.major_version;
     }
+
+    public CFVersion clone() {
+        try {
+            return (CFVersion)super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }
--- a/src/org/openjdk/asmtools/jasm/ClassData.java	Wed Nov 08 16:44:53 2017 -0800
+++ b/src/org/openjdk/asmtools/jasm/ClassData.java	Tue Nov 28 15:03:21 2017 -0800
@@ -41,7 +41,7 @@
 
     /*-------------------------------------------------------- */
     /* ClassData Fields */
-    CFVersion cfv = new CFVersion();
+    CFVersion cfv;
     ConstantPool.ConstCell me, father;
     String myClassName;
     AttrData sourceFileNameAttr;
@@ -83,7 +83,7 @@
         }
         this.father = father;
         this.interfaces = interfaces;
-
+        // Set default class file version if it is not set.
         cfv.initClassDefaults();
     }
 
@@ -93,43 +93,26 @@
         this.me = pool.FindCellClassByName("module-info");
         // super_class: zero
         this.father = new ConstantPool.ConstCell(0);
-
         cfv.initModuleDefaults();
     }
 
     /**
-     * default constructor
-     *
-     * @param env
-     */
-    public ClassData(Environment env) {
-        super(null, 0);  // for a class, these get inited in the super - later.
-        cls = this;
-
-        this.env = env;
-        pool = new ConstantPool(env);
-        cdos = new CDOutputStream();
-
-    }
-
-
-    /**
      * canonical default constructor
      *
      * @param env The error reporting environment.
      * @param cfv The class file version that this class file supports.
      */
     public ClassData(Environment env, CFVersion cfv) {
-        this(env);
+        super(null, 0);  // for a class, these get inited in the super - later.
+        cls = this;
+
+        this.env = env;
         this.cfv = cfv;
+
+        pool = new ConstantPool(env);
+        cdos = new CDOutputStream();
     }
 
-    public ClassData(Environment env, int acc, ConstantPool.ConstCell me, ConstantPool.ConstCell father, ArrayList<Argument> impls) {
-        this(env);
-        init(acc, me, father, impls);
-    }
-
-
     /* *********************************************** */
     /**
      * isInterface
--- a/src/org/openjdk/asmtools/jasm/Main.java	Wed Nov 08 16:44:53 2017 -0800
+++ b/src/org/openjdk/asmtools/jasm/Main.java	Tue Nov 28 15:03:21 2017 -0800
@@ -237,7 +237,6 @@
         strict = false;
         props = null;
         nwarnings = 0;
-        cfv = new CFVersion();
         bytelimit = 0;
     }
 
@@ -261,7 +260,7 @@
                     sf = new Environment(new File(inpname), out, nowarn);
                     sf.traceFlag = traceFlag;
                     sf.debugInfoFlag = debugInfoFlag;
-                    p = new Parser(sf, cfv);
+                    p = new Parser(sf, cfv.clone() );
                     p.setDebugFlags(debugScanner, debugMembers, debugCP, debugAnnot, debugInstr);
                     p.parseFile();
                 } catch (FileNotFoundException ex) {
--- a/src/org/openjdk/asmtools/jasm/Parser.java	Wed Nov 08 16:44:53 2017 -0800
+++ b/src/org/openjdk/asmtools/jasm/Parser.java	Tue Nov 28 15:03:21 2017 -0800
@@ -102,7 +102,7 @@
     private boolean                     explicitcp = false;
     private String                      moduleName = null;
     private ModuleAttr                  moduleAttribute;
-    private CFVersion                   cfv;
+    private CFVersion                   currentCFV;
 
 
     /** other parser components */
@@ -119,10 +119,10 @@
      */
     protected Parser(Environment sf, CFVersion cfVersion) throws IOException {
         super.init(new Scanner(sf), this, sf);
-        this.cfv = cfVersion;
-        this.annotParser = new ParserAnnotation(scanner, this, env);
-        this.cpParser = new ParserCP(scanner, this, env);
-        this.instrParser = new ParserInstr(scanner, this, cpParser, env);
+        this.currentCFV   = cfVersion;
+        this.annotParser  = new ParserAnnotation(scanner, this, env);
+        this.cpParser     = new ParserCP(scanner, this, env);
+        this.instrParser  = new ParserInstr(scanner, this, cpParser, env);
     }
 
 
@@ -160,7 +160,7 @@
             if (scanner.token != Token.INTVAL) {
                 break parse_ver;
             }
-            cfv.setMajorVersion((short)scanner.intValue);
+            currentCFV.setMajorVersion((short)scanner.intValue);
             scanner.scan();
             if (scanner.token != Token.COLON) {
                 break parse_ver;
@@ -169,9 +169,9 @@
             if (scanner.token != Token.INTVAL) {
                 break parse_ver;
             }
-            cfv.setMinorVersion((short)scanner.intValue);
+            currentCFV.setMinorVersion((short)scanner.intValue);
             scanner.scan();
-            debugScan("     [Parser.parseVersionPkg]: " + cfv.asString());
+            debugScan("     [Parser.parseVersionPkg]: " + currentCFV.asString());
             return;
         }
         env.error(scanner.pos, "version.expected");
@@ -190,7 +190,7 @@
             if (scanner.token != Token.INTVAL) {
                 break parse_ver;
             }
-            cfv.setMajorVersion((short)scanner.intValue);
+            cd.cfv.setMajorVersion((short)scanner.intValue);
             scanner.scan();
             if (scanner.token != Token.COLON) {
                 break parse_ver;
@@ -199,9 +199,9 @@
             if (scanner.token != Token.INTVAL) {
                 break parse_ver;
             }
-            cfv.setMinorVersion((short)scanner.intValue);
+            cd.cfv.setMinorVersion((short)scanner.intValue);
             scanner.scan();
-            debugStr( "parseVersion: " + cfv.asString());
+            debugStr( "parseVersion: " + cd.cfv.asString());
             return;
         }
         env.error(scanner.pos, "version.expected");
@@ -1117,7 +1117,7 @@
         Modifiers.checkClassModifiers(env, mod, scanner);
 
         if (cd == null) {
-            cd = new ClassData(env, cfv);
+            cd = new ClassData(env, currentCFV.clone());
             pool = cd.pool;
         }
 
@@ -1274,7 +1274,7 @@
   private void parseModule() throws IOException {
     debugStr("   [Parser.parseModule]:  Begin ");
     if (cd == null) {
-      cd = new ClassData(env, cfv);
+      cd = new ClassData(env, currentCFV.clone());
       pool = cd.pool;
     }
     if (clsAnnttns != null) {
@@ -1593,7 +1593,6 @@
             // Fix any bootstrap Method references too
             cd.relinkBootstrapMethods();
         }
-
         cd.endClass();
         clsDataList.add(cd);
         cd = null;
@@ -1626,7 +1625,7 @@
             // a package annotation, or a class annotation
             if (scanner.token == Token.ANNOTATION) {
                 if (cd == null) {
-                    cd = new ClassData(env, cfv);
+                    cd = new ClassData(env, currentCFV.clone());
                     pool = cd.pool;
                 }
                 pkgAnnttns = annotParser.scanAnnotations();
@@ -1663,17 +1662,18 @@
 
             // package-info
             if (sourceName.endsWith("package-info.jasm")) {
-                env.traceln("Creating \"package-info.jasm\": package: " + pkg + " " + cfv.asString());
+                env.traceln("Creating \"package-info.jasm\": package: " + pkg + " " + currentCFV.asString());
 
                 if (cd == null) {
-                    cd = new ClassData(env, cfv);
+                    cd = new ClassData(env, currentCFV.clone());
                     pool = cd.pool;
                 } else {
-                    cd.cfv = cfv;
+                    cd.cfv = currentCFV.clone();
                 }
                 ConstCell me = pool.FindCellClassByName(pkgPrefix + "package-info");
 
-                if (cfv.major_version() > 49) {
+                // Interface package-info should be marked synthetic and abstract
+                if (currentCFV.major_version() > 49) {
                     mod |= SYNTHETIC_ATTRIBUTE;
                 }
                 cd.init(mod, me, new ConstCell(0), null);
@@ -1707,8 +1707,10 @@
                     // Parse annotations
                     if (scanner.token == Token.ANNOTATION) {
                         if (cd == null) {
-                            cd = new ClassData(env, cfv);
+                            cd = new ClassData(env, currentCFV.clone());
                             pool = cd.pool;
+                        } else {
+                            cd.cfv = currentCFV.clone();
                         }
                         clsAnnttns = annotParser.scanAnnotations();
                     }