Added support for a new kind of Java programing component: the module, contributed by: leonid.kuskov@oracle.com

This commit is contained in:
afedorch 2017-10-06 15:15:23 -07:00
parent ed085afa2b
commit d9900f26df
37 changed files with 2808 additions and 2287 deletions

@ -5,3 +5,4 @@ re:.*\.log$
re:.*\.pyc$ re:.*\.pyc$
re:.*\.swp$ re:.*\.swp$
re:.*\.DS_Store$ re:.*\.DS_Store$
re:.*\iml$

@ -1,7 +1,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- <!--
Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it This code is free software; you can redistribute it and/or modify it
@ -106,7 +106,7 @@ table.Screen { margin-top: 0.5em; margin-bottom: 0.5em;
<h1>Release Notes</h1> <h1>Release Notes</h1>
<h2>AsmTools</h2> <h2>AsmTools</h2>
</h2> </h2>
<h2>November 2014</h2> <h2>October 2017</h2>
</center> </center>
</td> </td>
</tr> </tr>
@ -190,7 +190,7 @@ See the (
<p> <p>
Using ASM Tools requires a properly configured, certified Java Using ASM Tools requires a properly configured, certified Java
Platform, Standard Edition (Java SE&#8482; platform) runtime environment Platform, Standard Edition (Java SE&#8482; platform) runtime environment
version 1.7 or later, or a Java SE platform 7.0 runtime environment. version 1.8 or later, or a Java SE platform 8.0 runtime environment.
</p> </p>
<p class="nav-link">[<a href="#_top">Top</a>]</p> <p class="nav-link">[<a href="#_top">Top</a>]</p>
<a name="installation"></a> <a name="installation"></a>
@ -316,9 +316,9 @@ OpenJDK ASM Tools</a> main page for updated and more detailed information.
<p><a name="building" id="building"></a></p> <p><a name="building" id="building"></a></p>
<h2>Building the Sources</h2> <h2>Building the Sources</h2>
<p> <p>
Building the sources requires Ant version 1.8 or later (1.8.2 is current at the Building the sources requires Ant version 1.8 or later (1.10.1 is current at the
time of writing), and the built-in build is compatible with using an IDE. time of writing), and the built-in build is compatible with using an IDE.
The sources are designed for Java 7 and if you invoke <code>ant</code> with this The sources are designed for Java 8 and if you invoke <code>ant</code> with this
runtime, your chance of encountering an abnormal conditions due to your runtime runtime, your chance of encountering an abnormal conditions due to your runtime
or compiler (or javadoc) version. or compiler (or javadoc) version.
</p> </p>
@ -328,7 +328,7 @@ General requirements:
</p> </p>
<ul> <ul>
<li>ant, version 1.8 or later <li>ant, version 1.8 or later
<li>Java 7 runtime and compiler (minimum and recommended) <li>Java 8 runtime and compiler (minimum and recommended)
<li>10MB free disk space (3MB for source tree, 7MB for build output) <li>10MB free disk space (3MB for source tree, 7MB for build output)
</ul> </ul>
@ -348,7 +348,7 @@ A common variation of the build command to force <code>ant</code> to use a parti
installation of Java on your machine: installation of Java on your machine:
</p> </p>
<pre> <pre>
# JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home ANTHOME=/usr/share/ant ant # JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home ANTHOME=/usr/share/ant ant
</pre> </pre>
This example for common *nix shells (<code>zsh, bash, sh</code>), alter it as needed for your This example for common *nix shells (<code>zsh, bash, sh</code>), alter it as needed for your
command environment. You can test your invocation of <code>ant</code> by running it with command environment. You can test your invocation of <code>ant</code> by running it with
@ -368,7 +368,7 @@ specify in your IDE for building.
<hr> <hr>
<hr noshade="noshade"> <hr noshade="noshade">
<p><a href="legal/copyright.txt">Copyright</a> &copy; 2008, 2014, Oracle and/or its affiliates. All rights reserved. <p><a href="legal/copyright.txt">Copyright</a> &copy; 2008, 2017, Oracle and/or its affiliates. All rights reserved.
Use is subject to license terms.The majority of the Assember Tools project is released under the <A Use is subject to license terms.The majority of the Assember Tools project is released under the <A
HREF="http://openjdk.java.net/legal/gplv2+ce.html">GNU HREF="http://openjdk.java.net/legal/gplv2+ce.html">GNU
General Public License Version 2 (GPLv2)</A></p> General Public License Version 2 (GPLv2)</A></p>

@ -1,4 +1,4 @@
# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,6 @@
PRODUCT_NAME = asmtools PRODUCT_NAME = asmtools
PRODUCT_JAR_NAME = asmtools.jar PRODUCT_JAR_NAME = asmtools.jar
PRODUCT_VERSION = 6.0 PRODUCT_VERSION = 6.0
PRODUCT_MILESTONE = beta PRODUCT_MILESTONE = fcs
PRODUCT_BUILDNUMBER = b01 PRODUCT_BUILDNUMBER = b01
PRODUCT_NAME_LONG = Java Assembler Tools PRODUCT_NAME_LONG = Java Assembler Tools

@ -0,0 +1,438 @@
/*
* Copyright (c) 2016, 2017, 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.
*
* 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 org.openjdk.asmtools.common;
import java.util.*;
import java.util.stream.Collectors;
import static java.lang.String.format;
/**
* Internal presentation of a module
*/
public final class Module {
//* A module name and module_flags
public final Header header;
//* A service dependence's of this module
public final Set<Uses> uses;
//* Modules on which the current module has a dependence.
public final Set<Dependence> requires;
//* A module exports, may be qualified or unqualified.
public final Map<Exported, Set<String>> exports;
//* Packages, to be opened by the current module
public final Map<Opened, Set<String>> opens;
//* A service that a module provides one or more implementations of.
public final Map<Provided, Set<String>> provides;
private Module(Builder builder) {
this.header = builder.header;
this.requires = Collections.unmodifiableSet(builder.requires);
this.exports = Collections.unmodifiableMap(builder.exports);
this.opens = Collections.unmodifiableMap(builder.opens);
this.uses = Collections.unmodifiableSet(builder.uses);
this.provides = Collections.unmodifiableMap(builder.provides);
}
public String getModuleFlags () {
return Modifier.getModuleModifiers(header.getFlags());
}
public String getModuleName () { return header.getModuleName(); }
public String getModuleVersion() { return header.getModuleVersion(); };
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
int l = 0;
requires.stream()
.sorted()
.forEach(d -> sb.append(format(" requires %s;%s%n",
d.toString(),
d.getModuleVersion() == null ? "" : " // @" + d.getModuleVersion())));
//
l = newLine(sb,l);
exports.entrySet().stream()
.filter(e -> e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" exports %s;%n", e.getKey().toString()))
.forEach(sb::append);
exports.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" exports %s to%n%s;%n", e.getKey().toString(),
e.getValue().stream().sorted()
.map(mn -> format(" %s", mn))
.collect(Collectors.joining(",\n"))))
.forEach(sb::append);
//
l = newLine(sb,l);
opens.entrySet().stream()
.filter(e -> e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" opens %s;%n", e.getKey().toString()))
.forEach(sb::append);
opens.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" opens %s to%n%s;%n", e.getKey().toString(),
e.getValue().stream().sorted()
.map(mn -> format(" %s", mn))
.collect(Collectors.joining(",\n"))))
.forEach(sb::append);
//
l = newLine(sb,l);
uses.stream().sorted()
.map(s -> format(" uses %s;%n", s))
.forEach(sb::append);
//
l = newLine(sb,l);
provides.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" provides %s with%n%s;%n", e.getKey().toString(),
e.getValue().stream().sorted()
.map(mn -> format(" %s", mn))
.collect(Collectors.joining(",\n"))))
.forEach(sb::append);
//
if( Character.isWhitespace(sb.charAt(sb.length()-1)) )
sb.deleteCharAt(sb.length()-1);
return sb.toString();
}
private int newLine(StringBuilder sb, int length) {
if(sb.length() > length) {
sb.append("\n");
return sb.length() + 1;
}
return length;
}
/**
* Modules flags
*/
public enum Modifier {
ACC_NONE(0x0000, "", ""),
ACC_OPEN(0x0020, "open", "ACC_OPEN"),
ACC_TRANSITIVE(0x0020, "transitive", "ACC_TRANSITIVE"),
ACC_STATIC_PHASE(0x0040, "static", "ACC_STATIC_PHASE"),
ACC_SYNTHETIC(0x1000, "", "ACC_SYNTHETIC"),
ACC_MANDATED(0x8000, "", "ACC_MANDATED");
private final int value;
private final String keyword;
private final String flag;
Modifier(int value, String keyword, String flagName) {
this.value = value;
this.keyword = keyword;
this.flag = flagName;
}
public int asInt() { return value; }
public static String getModuleModifiers(int flag) {
return asString(flag, false, ACC_TRANSITIVE);
}
public static String getModuleFlags(int flag) {
return asString(flag, true, ACC_TRANSITIVE);
}
public static String getStatementModifiers(int flag) {
return asString(flag, false, ACC_OPEN);
}
public static String getStatementFlags(int flag) {
return asString(flag, true, ACC_OPEN);
}
private static String asString(int value, boolean flagFormat, Modifier skipped ) {
String buf = "";
for(Module.Modifier m : values()) {
if( m != skipped && (value & m.value) != 0) {
buf += ((flagFormat) ? m.flag : m.keyword) + " ";
value ^= m.value;
}
}
if( flagFormat && value != 0 )
buf += String.format("0x%04X ", value);
return buf;
}
}
// A module header consists of a module name and module flags
public final static class Header extends VersionedFlaggedTargetType{
Header(String typeName, int flag) { this(typeName, flag, null); }
Header(String typeName, int flag, String moduleVersion) { super(typeName, flag, moduleVersion); }
public String getModuleName() { return getTypeName(); }
public int getModuleFlags() { return getFlags(); }
public String getModuleVersion() { return getVersion(); }
}
//* A module on which the current module has a dependence.
public final static class Dependence extends VersionedFlaggedTargetType {
public Dependence(String moduleName, int flag) {this(moduleName, flag, null);}
public Dependence(String moduleName, int flag, String moduleVersion) {super(moduleName, flag, moduleVersion);}
public Dependence(String moduleName, boolean transitive, boolean staticPhase) { this(moduleName,transitive,staticPhase,null);}
public Dependence(String moduleName, boolean transitive, boolean staticPhase, String moduleVersion) {
this(moduleName,
(transitive ? Modifier.ACC_TRANSITIVE.value : Modifier.ACC_NONE.value) |
(staticPhase ? Modifier.ACC_STATIC_PHASE.value : Modifier.ACC_NONE.value), moduleVersion);
}
public String getModuleVersion() { return getVersion(); }
}
public final static class Uses extends TargetType {
public Uses(String typeName) { super(typeName); }
}
//* A provided type of the current module.
public final static class Provided extends TargetType {
public Provided(String typeName) { super(typeName); }
}
//* An opened package of the current module.
public final static class Opened extends FlaggedTargetType {
public Opened(String typeName) {
super(typeName, 0);
}
public Opened(String typeName, int opensFlags) {
super(typeName, opensFlags);
}
}
//* An exported package of the current module.
public final static class Exported extends FlaggedTargetType {
public Exported(String typeName) {
super(typeName, 0);
}
public Exported(String typeName, int exportsFlags) {
super(typeName, exportsFlags);
}
}
public static class VersionedFlaggedTargetType extends FlaggedTargetType {
private String version;
VersionedFlaggedTargetType(String typeName, int flag) {
this(typeName,flag, null);
}
VersionedFlaggedTargetType(String typeName, int flag, String version) {
super(typeName, flag);
this.version = version != null && !version.isEmpty() ? version : null;
}
public String getVersion() { return version; }
@Override
public int hashCode() {
int code = version == null ? 0 : version.hashCode();
return code + super.hashCode();
}
}
public static class FlaggedTargetType extends TargetType {
private int flag;
FlaggedTargetType(String typeName, int flag) {
super(typeName);
this.flag = flag;
}
public boolean isFlagged() {
return true;
}
public int getFlags() {
return flag;
}
public void setFlag(int value) { flag = value; }
@Override
public int hashCode() {
return super.hashCode() + flag;
}
@Override
public boolean equals(Object o) {
return super.equals(o) && ((FlaggedTargetType) o).flag == this.flag;
}
@Override
public String toString() {
return Modifier.getStatementModifiers(this.flag)+ super.toString();
}
}
public static class TargetType implements Comparable<TargetType> {
private String typeName;
TargetType(String typeName) { this.typeName = typeName; }
public String getTypeName() {
return typeName;
}
public void setTypeName(String value) { typeName = value; }
public boolean isFlagged() {
return false;
}
@Override
public int hashCode() { return typeName.hashCode() * 11; }
@Override
public boolean equals(Object o) {
if (o instanceof TargetType) {
TargetType t = (TargetType) o;
return this.typeName.equals(t.getTypeName());
}
return false;
}
@Override
public int compareTo(TargetType t) {
return this.typeName.compareTo(t.getTypeName());
}
@Override
public String toString() {
return typeName;
}
}
/**
* The module builder.
*/
public static final class Builder {
final Header header;
final Set<Dependence> requires = new HashSet<>();
final Map<Exported, Set<String>> exports = new HashMap<>();
final Map<Opened, Set<String>> opens = new HashMap<>();
final Set<Uses> uses = new HashSet<>();
final Map<Provided, Set<String>> provides = new HashMap<>();
public Builder() {
this("", Modifier.ACC_NONE.asInt(), null);
}
public Builder(String moduleName, int moduleFlags, String moduleVersion) {
header = new Header( moduleName,moduleFlags, moduleVersion);
}
public Builder setModuleFlags(int moduleFlags) {
header.setFlag(header.getFlags() | moduleFlags);
return this;
}
public Builder setModuleFlags(Modifier... moduleFlags) {
for (Modifier m : moduleFlags)
setModuleFlags(m.value);
return this;
}
public Builder setModuleName(String value) {
header.setTypeName(value);
return this;
}
public Builder require(String d, boolean transitive, boolean staticPhase, String version) {
requires.add(new Dependence(d, transitive, staticPhase, version));
return this;
}
public Builder require(String d, int requiresFlag, String version) {
requires.add(new Dependence(d, requiresFlag, version));
return this;
}
public Builder require(String d, int requiresFlag) {
requires.add(new Dependence(d, requiresFlag, null));
return this;
}
public Builder opens(Opened p, Set<String> ms) {
return add(opens, p, ms);
}
public Builder opens(String packageName, int exportFlags, Set<String> ms) {
return add(opens, new Opened(packageName, exportFlags), ms);
}
public Builder opens(String packageName, int exportFlags) {
return add(opens, new Opened(packageName, exportFlags), new HashSet<>());
}
public Builder exports(Exported p, Set<String> ms) {
return add(exports, p, ms);
}
public Builder exports(String packageName, int exportFlags, Set<String> ms) {
return add(exports, new Exported(packageName, exportFlags), ms);
}
public Builder exports(String packageName, int exportFlags) {
return add(exports, new Exported(packageName, exportFlags), new HashSet<>());
}
public Builder uses(String serviceName) {
uses.add(new Uses(serviceName));
return this;
}
public Builder uses(Set<String> serviceNames) {
uses.addAll(serviceNames.stream().map(Uses::new).collect(Collectors.toList()));
return this;
}
public Builder provides(Provided t, Set<String> implementations) {
return add(provides, t, implementations);
}
public Builder provides(String serviceName, Set<String> implementations) {
return add(provides, new Provided(serviceName), implementations);
}
/**
* @return The new module
*/
public Module build() {
return new Module(this);
}
private <T extends TargetType> Builder add( Map<T, Set<String>> collection, T source, Set<String> target) {
Objects.requireNonNull(source);
Objects.requireNonNull(target);
if (!collection.containsKey(source))
collection.put(source, new HashSet<>());
collection.get(source).addAll(target);
return this;
}
}
}

@ -0,0 +1,90 @@
/*
* Copyright (c) 2017, 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.
*
* 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 org.openjdk.asmtools.jasm;
/*
* Class File Version
*/
public class CFVersion {
/**
* Default versions of class file
*/
public static final short DEFAULT_MAJOR_VERSION = 45;
public static final short DEFAULT_MINOR_VERSION = 3;
public static final short DEFAULT_MODULE_MAJOR_VERSION = 53;
public static final short DEFAULT_MODULE_MINOR_VERSION = 0;
public static final short UNDEFINED_VERSION = -1;
private short major_version;
private short minor_version;
public CFVersion() {
major_version = UNDEFINED_VERSION;
minor_version = UNDEFINED_VERSION;
}
public CFVersion(short major_version, short minor_version) {
this.major_version = major_version;
this.minor_version = minor_version;
}
public void setMajorVersion(short major_version) {
if ( !isSet() )
this.major_version = major_version;
}
public void setMinorVersion(short minor_version) {
if ( !isSet() )
this.minor_version = minor_version;
}
private boolean isSet() {
return this.major_version != UNDEFINED_VERSION && this.minor_version != UNDEFINED_VERSION;
}
public String asString() {
return (isSet()) ? this.major_version + ":" +this.minor_version : "(undef):(undef)";
}
public void initModuleDefaults() {
if( ! isSet()) {
major_version = DEFAULT_MODULE_MAJOR_VERSION;
minor_version = DEFAULT_MODULE_MINOR_VERSION;
}
}
public void initClassDefaults() {
if( ! isSet()) {
major_version = DEFAULT_MAJOR_VERSION;
minor_version = DEFAULT_MINOR_VERSION;
}
}
public short minor_version() {
return this.minor_version;
}
public short major_version() {
return this.major_version;
}
}

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -61,5 +61,4 @@ public interface CheckedDataOutputStream {
public void writeUTF(String s) throws IOException; public void writeUTF(String s) throws IOException;
// public int writeUTF(String str, DataOutput out) throws IOException;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,7 @@ package org.openjdk.asmtools.jasm;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MAJOR_VERSION; import static org.openjdk.asmtools.jasm.Constants.*;
import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MINOR_VERSION;
import static org.openjdk.asmtools.jasm.Tables.*; import static org.openjdk.asmtools.jasm.Tables.*;
/** /**
@ -43,8 +42,7 @@ class ClassData extends MemberData {
/*-------------------------------------------------------- */ /*-------------------------------------------------------- */
/* ClassData Fields */ /* ClassData Fields */
short major_version = DEFAULT_MAJOR_VERSION; CFVersion cfv = new CFVersion();
short minor_version = DEFAULT_MINOR_VERSION;
ConstantPool.ConstCell me, father; ConstantPool.ConstCell me, father;
String myClassName; String myClassName;
AttrData sourceFileNameAttr; AttrData sourceFileNameAttr;
@ -86,12 +84,18 @@ class ClassData extends MemberData {
} }
this.father = father; this.father = father;
this.interfaces = interfaces; this.interfaces = interfaces;
cfv.initClassDefaults();
} }
public final void initAsModule(ConstantPool.ConstCell me) { public final void initAsModule() {
this.access = RuntimeConstants.ACC_MODULE; this.access = RuntimeConstants.ACC_MODULE;
this.me = me; // this_class" module-info
this.me = pool.FindCellClassByName("module-info");
// super_class: zero
this.father = new ConstantPool.ConstCell(0); this.father = new ConstantPool.ConstCell(0);
cfv.initModuleDefaults();
} }
/** /**
@ -114,13 +118,11 @@ class ClassData extends MemberData {
* canonical default constructor * canonical default constructor
* *
* @param env The error reporting environment. * @param env The error reporting environment.
* @param major_version The major version that this class file supports. * @param cfv The class file version that this class file supports.
* @param minor_version The minor version that this class file supports
*/ */
public ClassData(Environment env, short major_version, short minor_version) { public ClassData(Environment env, CFVersion cfv) {
this(env); this(env);
this.major_version = major_version; this.cfv = cfv;
this.minor_version = minor_version;
} }
public ClassData(Environment env, int acc, ConstantPool.ConstCell me, ConstantPool.ConstCell father, ArrayList<Argument> impls) { public ClassData(Environment env, int acc, ConstantPool.ConstCell me, ConstantPool.ConstCell father, ArrayList<Argument> impls) {
@ -142,7 +144,6 @@ class ClassData extends MemberData {
return Modifiers.isInterface(access); return Modifiers.isInterface(access);
} }
/* /*
* After a constant pool has been explicitly declared, * After a constant pool has been explicitly declared,
* this method links the Constant_InvokeDynamic constants * this method links the Constant_InvokeDynamic constants
@ -348,8 +349,8 @@ class ClassData extends MemberData {
// Write the header // Write the header
out.writeInt(JAVA_MAGIC); out.writeInt(JAVA_MAGIC);
out.writeShort(minor_version); out.writeShort(cfv.minor_version());
out.writeShort(major_version); out.writeShort(cfv.major_version());
pool.write(out); pool.write(out);
out.writeShort(access); // & MM_CLASS; // Q out.writeShort(access); // & MM_CLASS; // Q
@ -390,6 +391,10 @@ class ClassData extends MemberData {
// Write the attributes // Write the attributes
if( moduleAttribute != null ) { if( moduleAttribute != null ) {
if (annotAttrVis != null)
attrs.add(annotAttrVis);
if (annotAttrInv != null)
attrs.add(annotAttrInv);
attrs.add(moduleAttribute); attrs.add(moduleAttribute);
} else { } else {
attrs.add(sourceFileNameAttr); attrs.add(sourceFileNameAttr);
@ -585,6 +590,5 @@ class ClassData extends MemberData {
* */ * */
} }
}// end class ClassData }// end class ClassData

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -434,7 +434,7 @@ class CodeAttr extends AttrData {
public StackMapData getStackMap() { public StackMapData getStackMap() {
if (curMapEntry == null) { if (curMapEntry == null) {
curMapEntry = new StackMapData(env); curMapEntry = new StackMapData(env);
if (cls.major_version >= SPLIT_VERIFIER_CFV) { if (cls.cfv.major_version() >= SPLIT_VERIFIER_CFV) {
curMapEntry.setIsStackMapTable(true); curMapEntry.setIsStackMapTable(true);
} }
} }
@ -473,7 +473,7 @@ class CodeAttr extends AttrData {
curMapEntry.pc = cur_pc; curMapEntry.pc = cur_pc;
StackMapData prevStackFrame = null; StackMapData prevStackFrame = null;
if (stackMap == null) { if (stackMap == null) {
if (cls.major_version >= SPLIT_VERIFIER_CFV) { if (cls.cfv.major_version() >= SPLIT_VERIFIER_CFV) {
stackMap = new DataVectorAttr<>(cls, AttrTag.ATT_StackMapTable.parsekey()); stackMap = new DataVectorAttr<>(cls, AttrTag.ATT_StackMapTable.parsekey());
} else { } else {
stackMap = new DataVectorAttr<>(cls, AttrTag.ATT_StackMap.parsekey()); stackMap = new DataVectorAttr<>(cls, AttrTag.ATT_StackMap.parsekey());

@ -619,13 +619,21 @@ public class ConstantPool implements Iterable<ConstantPool.ConstCell> {
public R visitInvokedynamic(ConstType tag) { public R visitInvokedynamic(ConstType tag) {
return null; return null;
} }
; ;
// public R visitInvokedynamicTrans() { return null; };
public R visitModule(ConstType tag) {
return null;
}
;
public R visitPackage(ConstType tag) {
return null;
}
;
public void visitDefault(ConstType tag) { public void visitDefault(ConstType tag) {
} }
; ;
} }
/** /**
@ -684,9 +692,12 @@ public class ConstantPool implements Iterable<ConstantPool.ConstCell> {
case CONSTANT_INVOKEDYNAMIC: case CONSTANT_INVOKEDYNAMIC:
retVal = visitInvokedynamic((ConstValue_IndyPair) val); retVal = visitInvokedynamic((ConstValue_IndyPair) val);
break; break;
// case CONSTANT_INVOKEDYNAMIC_TRANS: case CONSTANT_MODULE:
// retVal = visitInvokedynamicTrans((ConstValue_Pair) val); retVal = visitModule((ConstValue_Cell) val);
// break; break;
case CONSTANT_PACKAGE:
retVal = visitPackage((ConstValue_Cell) val);
break;
default: default:
visitDefault(tag); visitDefault(tag);
} }
@ -758,15 +769,17 @@ public class ConstantPool implements Iterable<ConstantPool.ConstCell> {
} }
; ;
public R visitInvokedynamic(ConstValue_IndyPair p) { public R visitInvokedynamic(ConstValue_IndyPair p) { return null;}
return null;
}
; ;
// public R visitInvokedynamicTrans(ConstValue_Pair p) { return null; }; public R visitModule(ConstValue_Cell p) { return null; }
public void visitDefault(ConstType tag) {
} ;
; public R visitPackage(ConstValue_Cell p) { return null; }
;
public void visitDefault(ConstType tag) {}
;
} }
@ -970,9 +983,23 @@ public class ConstantPool implements Iterable<ConstantPool.ConstCell> {
public Void visitInvokedynamic(ConstValue_IndyPair p) { public Void visitInvokedynamic(ConstValue_IndyPair p) {
return null; return null;
} }
; ;
@Override
public Void visitModule(ConstValue_Cell p) {
handleClassRef(p);
return null;
}
;
@Override
public Void visitPackage(ConstValue_Cell p) {
handleClassRef(p);
return null;
}
;
public void handleClassRef(ConstValue_Cell cv) { public void handleClassRef(ConstValue_Cell cv) {
ConstCell clref = cv.cell; ConstCell clref = cv.cell;
if (clref.ref == null) { if (clref.ref == null) {
@ -1170,9 +1197,11 @@ find:
return FindCell(ConstType.CONSTANT_UTF8, str); return FindCell(ConstType.CONSTANT_UTF8, str);
} }
public ConstCell FindCellClassByName(String name) { public ConstCell FindCellClassByName(String name) { return FindCell(ConstType.CONSTANT_CLASS, FindCellAsciz(name)); }
return FindCell(ConstType.CONSTANT_CLASS, FindCellAsciz(name));
} public ConstCell FindCellModuleByName(String name) { return FindCell(ConstType.CONSTANT_MODULE, FindCellAsciz(name)); }
public ConstCell FindCellPackageByName(String name) { return FindCell(ConstType.CONSTANT_PACKAGE, FindCellAsciz(name)); }
public void write(CheckedDataOutputStream out) throws IOException { public void write(CheckedDataOutputStream out) throws IOException {
// Write the constant pool // Write the constant pool
@ -1186,7 +1215,6 @@ find:
if (cell.arg != i) { if (cell.arg != i) {
throw new Parser.CompilerError(env.errorStr("comperr.constcell.invarg", Integer.toString(i), cell.arg)); throw new Parser.CompilerError(env.errorStr("comperr.constcell.invarg", Integer.toString(i), cell.arg));
} }
// System.out.print(" WRITE CONST[" + i + "]:");
value.write(out); value.write(out);
i += value.size(); i += value.size();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,11 +29,6 @@ package org.openjdk.asmtools.jasm;
*/ */
public interface Constants extends RuntimeConstants { public interface Constants extends RuntimeConstants {
/**
* Default version of class file
*/
public static final short DEFAULT_MAJOR_VERSION = 45;
public static final short DEFAULT_MINOR_VERSION = 3;
/** /**
* End of input * End of input

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,11 @@
*/ */
package org.openjdk.asmtools.jasm; package org.openjdk.asmtools.jasm;
import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Optional;
import static org.openjdk.asmtools.jasm.JasmTokens.Token.ALL_TOKENS;
/** /**
* *
@ -61,21 +65,23 @@ public class JasmTokens {
} }
/*-------------------------------------------------------- */ /*-------------------------------------------------------- */
/* Marker - describes the type of token */ /* Marker - describes the type of token */
/* this is rather cosmetic, no function currently. */ /* this is rather cosmetic, no function currently. */
static public enum TokenType { static public enum TokenType {
MODIFIER (0, "Modifier"), MODIFIER (1, "Modifier"),
OPERATOR (1, "Operator"), OPERATOR (2, "Operator"),
VALUE (2, "Value"), VALUE (3, "Value"),
TYPE (3, "Type"), TYPE (4, "Type"),
EXPRESSION (4, "Expression"), EXPRESSION (5, "Expression"),
STATEMENT (5, "Statement"), STATEMENT (6, "Statement"),
DECLARATION (6, "Declaration"), DECLARATION (7, "Declaration"),
PUNCTUATION (7, "Punctuation"), PUNCTUATION (8, "Punctuation"),
SPECIAL (8, "Special"), SPECIAL (9, "Special"),
JASM (9, "Jasm"), JASM (10, "Jasm"),
MISC (10, "Misc"); MISC (11, "Misc"),
JASM_IDENT (12, "Jasm identifier"),
MODULE_NAME (13, "Module Name");
private final Integer value; private final Integer value;
private final String printval; private final String printval;
@ -84,7 +90,6 @@ public class JasmTokens {
value = val; value = val;
printval = print; printval = print;
} }
public String printval() { public String printval() {
return printval; return printval;
} }
@ -95,257 +100,257 @@ public class JasmTokens {
* Scanner Tokens (Definitive List) * Scanner Tokens (Definitive List)
*/ */
static public enum Token { static public enum Token {
EOF (-1, "EOF", "EOF", TokenType.MISC), EOF (-1, "EOF", "EOF", EnumSet.of(TokenType.MISC)),
COMMA (0, "COMMA", ",", TokenType.OPERATOR), COMMA (0, "COMMA", ",", EnumSet.of(TokenType.OPERATOR)),
ASSIGN (1, "ASSIGN", "=", TokenType.OPERATOR), ASSIGN (1, "ASSIGN", "=", EnumSet.of(TokenType.OPERATOR)),
ASGMUL (2, "ASGMUL", "*=", TokenType.OPERATOR), ASGMUL (2, "ASGMUL", "*=", EnumSet.of(TokenType.OPERATOR)),
ASGDIV (3, "ASGDIV", "/=", TokenType.OPERATOR), ASGDIV (3, "ASGDIV", "/=", EnumSet.of(TokenType.OPERATOR)),
ASGREM (4, "ASGREM", "%=", TokenType.OPERATOR), ASGREM (4, "ASGREM", "%=", EnumSet.of(TokenType.OPERATOR)),
ASGADD (5, "ASGADD", "+=", TokenType.OPERATOR), ASGADD (5, "ASGADD", "+=", EnumSet.of(TokenType.OPERATOR)),
ASGSUB (6, "ASGSUB", "-=", TokenType.OPERATOR), ASGSUB (6, "ASGSUB", "-=", EnumSet.of(TokenType.OPERATOR)),
ASGLSHIFT (7, "ASGLSHIFT", "<<=", TokenType.OPERATOR), ASGLSHIFT (7, "ASGLSHIFT", "<<=", EnumSet.of(TokenType.OPERATOR)),
ASGRSHIFT (8, "ASGRSHIFT", ">>=", TokenType.OPERATOR), ASGRSHIFT (8, "ASGRSHIFT", ">>=", EnumSet.of(TokenType.OPERATOR)),
ASGURSHIFT (9, "ASGURSHIFT", "<<<=", TokenType.OPERATOR), ASGURSHIFT (9, "ASGURSHIFT", "<<<=", EnumSet.of(TokenType.OPERATOR)),
ASGBITAND (10, "ASGBITAND", "&=", TokenType.OPERATOR), ASGBITAND (10, "ASGBITAND", "&=", EnumSet.of(TokenType.OPERATOR)),
ASGBITOR (11, "ASGBITOR", "|=", TokenType.OPERATOR), ASGBITOR (11, "ASGBITOR", "|=", EnumSet.of(TokenType.OPERATOR)),
ASGBITXOR (12, "ASGBITXOR", "^=", TokenType.OPERATOR), ASGBITXOR (12, "ASGBITXOR", "^=", EnumSet.of(TokenType.OPERATOR)),
COND (13, "COND", "?:", TokenType.OPERATOR),
OR (14, "OR", "||", TokenType.OPERATOR),
AND (15, "AND", "&&", TokenType.OPERATOR),
BITOR (16, "BITOR", "|", TokenType.OPERATOR),
BITXOR (17, "BITXOR", "^", TokenType.OPERATOR),
BITAND (18, "BITAND", "&", TokenType.OPERATOR),
NE (19, "NE", "!=", TokenType.OPERATOR),
EQ (20, "EQ", "==", TokenType.OPERATOR),
GE (21, "GE", ">=", TokenType.OPERATOR),
GT (22, "GT", ">", TokenType.OPERATOR),
LE (23, "LE", "<=", TokenType.OPERATOR),
LT (24, "LT", "<", TokenType.OPERATOR),
INSTANCEOF (25, "INSTANCEOF", "instanceof", TokenType.OPERATOR),
LSHIFT (26, "LSHIFT", "<<", TokenType.OPERATOR),
RSHIFT (27, "RSHIFT", ">>", TokenType.OPERATOR),
URSHIFT (28, "URSHIFT", "<<<", TokenType.OPERATOR),
ADD (29, "ADD", "+", TokenType.OPERATOR),
SUB (30, "SUB", "-", TokenType.OPERATOR),
DIV (31, "DIV", "/", TokenType.OPERATOR),
REM (32, "REM", "%", TokenType.OPERATOR),
MUL (33, "MUL", "*", TokenType.OPERATOR),
CAST (34, "CAST", "cast", TokenType.OPERATOR),
POS (35, "POS", "+", TokenType.OPERATOR),
NEG (36, "NEG", "-", TokenType.OPERATOR),
NOT (37, "NOT", "!", TokenType.OPERATOR),
BITNOT (38, "BITNOT", "~", TokenType.OPERATOR),
PREINC (39, "PREINC", "++", TokenType.OPERATOR),
PREDEC (40, "PREDEC", "--", TokenType.OPERATOR),
NEWARRAY (41, "NEWARRAY", "new", TokenType.OPERATOR),
NEWINSTANCE (42, "NEWINSTANCE", "new", TokenType.OPERATOR),
NEWFROMNAME (43, "NEWFROMNAME", "new", TokenType.OPERATOR),
POSTINC (44, "POSTINC", "++", TokenType.OPERATOR),
POSTDEC (45, "POSTDEC", "--", TokenType.OPERATOR),
FIELD (46, "FIELD", "field", TokenType.OPERATOR),
METHOD (47, "METHOD", "method", TokenType.OPERATOR),
ARRAYACCESS (48, "ARRAYACCESS", "[]", TokenType.OPERATOR),
NEW (49, "NEW", "new", TokenType.OPERATOR),
INC (50, "INC", "++", TokenType.OPERATOR),
DEC (51, "DEC", "--", TokenType.OPERATOR),
CONVERT (55, "CONVERT", "convert", TokenType.OPERATOR),
EXPR (56, "EXPR", "expr", TokenType.OPERATOR),
ARRAY (57, "ARRAY", "array", TokenType.OPERATOR),
GOTO (58, "GOTO", "goto", TokenType.OPERATOR),
COND (13, "COND", "?:", EnumSet.of(TokenType.OPERATOR)),
OR (14, "OR", "||", EnumSet.of(TokenType.OPERATOR)),
AND (15, "AND", "&&", EnumSet.of(TokenType.OPERATOR)),
BITOR (16, "BITOR", "|", EnumSet.of(TokenType.OPERATOR)),
BITXOR (17, "BITXOR", "^", EnumSet.of(TokenType.OPERATOR)),
BITAND (18, "BITAND", "&", EnumSet.of(TokenType.OPERATOR)),
NE (19, "NE", "!=", EnumSet.of(TokenType.OPERATOR)),
EQ (20, "EQ", "==", EnumSet.of(TokenType.OPERATOR)),
GE (21, "GE", ">=", EnumSet.of(TokenType.OPERATOR)),
GT (22, "GT", ">", EnumSet.of(TokenType.OPERATOR)),
LE (23, "LE", "<=", EnumSet.of(TokenType.OPERATOR)),
LT (24, "LT", "<", EnumSet.of(TokenType.OPERATOR)),
INSTANCEOF (25, "INSTANCEOF", "instanceof", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
LSHIFT (26, "LSHIFT", "<<", EnumSet.of(TokenType.OPERATOR)),
RSHIFT (27, "RSHIFT", ">>", EnumSet.of(TokenType.OPERATOR)),
URSHIFT (28, "URSHIFT", "<<<", EnumSet.of(TokenType.OPERATOR)),
ADD (29, "ADD", "+", EnumSet.of(TokenType.OPERATOR)),
SUB (30, "SUB", "-", EnumSet.of(TokenType.OPERATOR)),
DIV (31, "DIV", "/", EnumSet.of(TokenType.OPERATOR)),
REM (32, "REM", "%", EnumSet.of(TokenType.OPERATOR)),
MUL (33, "MUL", "*", EnumSet.of(TokenType.OPERATOR)),
CAST (34, "CAST", "cast", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
POS (35, "POS", "+", EnumSet.of(TokenType.OPERATOR)),
NEG (36, "NEG", "-", EnumSet.of(TokenType.OPERATOR)),
NOT (37, "NOT", "!", EnumSet.of(TokenType.OPERATOR)),
BITNOT (38, "BITNOT", "~", EnumSet.of(TokenType.OPERATOR)),
PREINC (39, "PREINC", "++", EnumSet.of(TokenType.OPERATOR)),
PREDEC (40, "PREDEC", "--", EnumSet.of(TokenType.OPERATOR)),
NEWARRAY (41, "NEWARRAY", "new", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
NEWINSTANCE (42, "NEWINSTANCE", "new", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
NEWFROMNAME (43, "NEWFROMNAME", "new", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
POSTINC (44, "POSTINC", "++", EnumSet.of(TokenType.OPERATOR)),
POSTDEC (45, "POSTDEC", "--", EnumSet.of(TokenType.OPERATOR)),
FIELD (46, "FIELD", "field", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
METHOD (47, "METHOD", "method", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
ARRAYACCESS (48, "ARRAYACCESS", "[]", EnumSet.of(TokenType.OPERATOR)),
NEW (49, "NEW", "new", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
INC (50, "INC", "++", EnumSet.of(TokenType.OPERATOR)),
DEC (51, "DEC", "--", EnumSet.of(TokenType.OPERATOR)),
CONVERT (55, "CONVERT", "convert", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
EXPR (56, "EXPR", "expr", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
ARRAY (57, "ARRAY", "array", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
GOTO (58, "GOTO", "goto", EnumSet.of(TokenType.OPERATOR, TokenType.MODULE_NAME)),
/* /*
* Value tokens * Value tokens
*/ */
IDENT (60, "IDENT", "Identifier", TokenType.VALUE, KeywordType.VALUE, true), IDENT (60, "IDENT", "Identifier", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME, TokenType.JASM_IDENT), KeywordType.VALUE),
BOOLEANVAL (61, "BOOLEANVAL", "Boolean", TokenType.VALUE, KeywordType.VALUE), BOOLEANVAL (61, "BOOLEANVAL", "Boolean", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME), KeywordType.VALUE),
BYTEVAL (62, "BYTEVAL", "Byte", TokenType.VALUE), BYTEVAL (62, "BYTEVAL", "Byte", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME)),
CHARVAL (63, "CHARVAL", "Char", TokenType.VALUE), CHARVAL (63, "CHARVAL", "Char", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME)),
SHORTVAL (64, "SHORTVAL", "Short", TokenType.VALUE), SHORTVAL (64, "SHORTVAL", "Short", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME)),
INTVAL (65, "INTVAL", "Integer", TokenType.VALUE, KeywordType.VALUE), INTVAL (65, "INTVAL", "Integer", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME), KeywordType.VALUE),
LONGVAL (66, "LONGVAL", "Long", TokenType.VALUE, KeywordType.VALUE), LONGVAL (66, "LONGVAL", "Long", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME), KeywordType.VALUE),
FLOATVAL (67, "FLOATVAL", "Float", TokenType.VALUE, KeywordType.VALUE), FLOATVAL (67, "FLOATVAL", "Float", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME), KeywordType.VALUE),
DOUBLEVAL (68, "DOUBLEVAL", "Double", TokenType.VALUE, KeywordType.VALUE), DOUBLEVAL (68, "DOUBLEVAL", "Double", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME), KeywordType.VALUE),
STRINGVAL (69, "STRINGVAL", "String", TokenType.VALUE, KeywordType.VALUE), STRINGVAL (69, "STRINGVAL", "String", EnumSet.of(TokenType.VALUE, TokenType.MODULE_NAME), KeywordType.VALUE),
/* /*
* Type keywords * Type keywords
*/ */
BYTE (70, "BYTE", "byte", TokenType.TYPE), BYTE (70, "BYTE", "byte", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME )),
CHAR (71, "CHAR", "char", TokenType.TYPE), CHAR (71, "CHAR", "char", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME )),
SHORT (72, "SHORT", "short", TokenType.TYPE), SHORT (72, "SHORT", "short", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME )),
INT (73, "INT", "int", TokenType.TYPE), INT (73, "INT", "int", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME )),
LONG (74, "LONG", "long", TokenType.TYPE), LONG (74, "LONG", "long", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME )),
FLOAT (75, "FLOAT", "float", TokenType.TYPE), FLOAT (75, "FLOAT", "float", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME)),
DOUBLE (76, "DOUBLE", "double", TokenType.TYPE), DOUBLE (76, "DOUBLE", "double", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME)),
VOID (77, "VOID", "void", TokenType.TYPE), VOID (77, "VOID", "void", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME)),
BOOLEAN (78, "BOOLEAN", "boolean", TokenType.TYPE), BOOLEAN (78, "BOOLEAN", "boolean", EnumSet.of(TokenType.TYPE, TokenType.MODULE_NAME)),
/* /*
* Expression keywords * Expression keywords
*/ */
TRUE (80, "TRUE", "true", TokenType.EXPRESSION), TRUE (80, "TRUE", "true", EnumSet.of(TokenType.EXPRESSION, TokenType.MODULE_NAME )),
FALSE (81, "FALSE", "false", TokenType.EXPRESSION), FALSE (81, "FALSE", "false", EnumSet.of(TokenType.EXPRESSION, TokenType.MODULE_NAME )),
THIS (82, "THIS", "this", TokenType.EXPRESSION), THIS (82, "THIS", "this", EnumSet.of(TokenType.EXPRESSION, TokenType.MODULE_NAME )),
SUPER (83, "SUPER", "super", TokenType.MODIFIER, KeywordType.KEYWORD), SUPER (83, "SUPER", "super", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
NULL (84, "NULL", "null", TokenType.EXPRESSION), NULL (84, "NULL", "null", EnumSet.of(TokenType.EXPRESSION, TokenType.MODULE_NAME )),
/* /*
* Statement keywords * Statement keywords
*/ */
IF (90, "IF", "if", TokenType.STATEMENT), IF (90, "IF", "if", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
ELSE (91, "ELSE", "else", TokenType.STATEMENT), ELSE (91, "ELSE", "else", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
FOR (92, "FOR", "for", TokenType.STATEMENT), FOR (92, "FOR", "for", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
WHILE (93, "WHILE", "while", TokenType.STATEMENT), WHILE (93, "WHILE", "while", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
DO (94, "DO", "do", TokenType.STATEMENT), DO (94, "DO", "do", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
SWITCH (95, "SWITCH", "switch", TokenType.STATEMENT), SWITCH (95, "SWITCH", "switch", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
CASE (96, "CASE", "case", TokenType.STATEMENT), CASE (96, "CASE", "case", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
DEFAULT (97, "DEFAULT", "default", TokenType.STATEMENT, KeywordType.KEYWORD), DEFAULT (97, "DEFAULT", "default", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
BREAK (98, "BREAK", "break", TokenType.STATEMENT), BREAK (98, "BREAK", "break", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
CONTINUE (99, "CONTINUE", "continue", TokenType.STATEMENT), CONTINUE (99, "CONTINUE", "continue", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
RETURN (100, "RETURN", "return", TokenType.STATEMENT), RETURN (100, "RETURN", "return", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
TRY (101, "TRY", "try", TokenType.STATEMENT), TRY (101, "TRY", "try", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
CATCH (102, "CATCH", "catch", TokenType.STATEMENT),
FINALLY (103, "FINALLY", "finally", TokenType.STATEMENT), CATCH (102, "CATCH", "catch", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
THROW (104, "THROW", "throw", TokenType.STATEMENT), FINALLY (103, "FINALLY", "finally", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
STAT (105, "STAT", "stat", TokenType.STATEMENT), THROW (104, "THROW", "throw", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
EXPRESSION (106, "EXPRESSION", "expression", TokenType.STATEMENT), STAT (105, "STAT", "stat", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
DECLARATION (107, "DECLARATION", "declaration", TokenType.STATEMENT), EXPRESSION (106, "EXPRESSION", "expression", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
VARDECLARATION (108, "VARDECLARATION", "vdeclaration", TokenType.STATEMENT), DECLARATION (107, "DECLARATION", "declaration", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
VARDECLARATION (108, "VARDECLARATION", "vdeclaration", EnumSet.of(TokenType.STATEMENT, TokenType.MODULE_NAME )),
/* /*
* Declaration keywords * Declaration keywords
*/ */
IMPORT (110, "IMPORT", "import", TokenType.DECLARATION), IMPORT (110, "IMPORT", "import", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME )),
CLASS (111, "CLASS", "class", TokenType.DECLARATION, KeywordType.KEYWORD), CLASS (111, "CLASS", "class", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
EXTENDS (112, "EXTENDS", "extends", TokenType.DECLARATION, KeywordType.KEYWORD), EXTENDS (112, "EXTENDS", "extends", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
IMPLEMENTS (113, "IMPLEMENTS", "implements", TokenType.DECLARATION, KeywordType.KEYWORD), IMPLEMENTS (113, "IMPLEMENTS", "implements", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
INTERFACE (114, "INTERFACE", "interface", TokenType.DECLARATION, KeywordType.KEYWORD), INTERFACE (114, "INTERFACE", "interface", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
PACKAGE (115, "PACKAGE", "package", TokenType.DECLARATION, KeywordType.KEYWORD), PACKAGE (115, "PACKAGE", "package", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
ENUM (116, "ENUM", "enum", TokenType.DECLARATION, KeywordType.KEYWORD), ENUM (116, "ENUM", "enum", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
MANDATED (117, "MANDATED", "mandated", TokenType.DECLARATION, KeywordType.KEYWORD), MANDATED (117, "MANDATED", "mandated", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
/* THROWS (118, "THROWS", "throws", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
/*
* Modifier keywords * Modifier keywords
*/ */
PRIVATE (120, "PRIVATE", "private", TokenType.MODIFIER, KeywordType.KEYWORD), ANNOTATION_ACCESS (119, "ANNOTATION_ACCESS", "annotation", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
PUBLIC (121, "PUBLIC", "public", TokenType.MODIFIER, KeywordType.KEYWORD), PRIVATE (120, "PRIVATE", "private", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
PROTECTED (122, "PROTECTED", "protected", TokenType.MODIFIER, KeywordType.KEYWORD), PUBLIC (121, "PUBLIC", "public", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
CONST (123, "CONST", "const", TokenType.DECLARATION, KeywordType.KEYWORD), PROTECTED (122, "PROTECTED", "protected", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
STATIC (124, "STATIC", "static", TokenType.MODIFIER, KeywordType.KEYWORD), CONST (123, "CONST", "const", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME), KeywordType.KEYWORD),
TRANSIENT (125, "TRANSIENT", "transient", TokenType.MODIFIER, KeywordType.KEYWORD), STATIC (124, "STATIC", "static", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
SYNCHRONIZED (126, "SYNCHRONIZED", "synchronized", TokenType.MODIFIER, KeywordType.KEYWORD), TRANSIENT (125, "TRANSIENT", "transient", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
NATIVE (127, "NATIVE", "native", TokenType.MODIFIER, KeywordType.KEYWORD), SYNCHRONIZED (126, "SYNCHRONIZED", "synchronized", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
FINAL (128, "FINAL", "final", TokenType.MODIFIER, KeywordType.KEYWORD), NATIVE (127, "NATIVE", "native", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
VOLATILE (129, "VOLATILE", "volatile", TokenType.MODIFIER, KeywordType.KEYWORD), FINAL (128, "FINAL", "final", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
ABSTRACT (130, "ABSTRACT", "abstract", TokenType.MODIFIER, KeywordType.KEYWORD), VOLATILE (129, "VOLATILE", "volatile", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
ABSTRACT (130, "ABSTRACT", "abstract", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
TRANSITIVE (131, "TRANSITIVE", "transitive", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
OPEN (132, "OPEN", "open", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
/* /*
* Punctuation * Punctuation
*/ */
SEMICOLON (135, "SEMICOLON", ";", TokenType.PUNCTUATION, KeywordType.VALUE), AT_SIGN (133, "AT", ";", EnumSet.of(TokenType.PUNCTUATION), KeywordType.VALUE),
COLON (136, "COLON", ":", TokenType.PUNCTUATION, KeywordType.VALUE), SEMICOLON (134, "SEMICOLON", ";", EnumSet.of(TokenType.PUNCTUATION), KeywordType.VALUE),
QUESTIONMARK (137, "QUESTIONMARK", "?", TokenType.PUNCTUATION), COLON (135, "COLON", ":", EnumSet.of(TokenType.PUNCTUATION), KeywordType.VALUE),
LBRACE (138, "LBRACE", "{", TokenType.PUNCTUATION, KeywordType.VALUE), QUESTIONMARK (136, "QUESTIONMARK", "?", EnumSet.of(TokenType.PUNCTUATION)),
RBRACE (139, "RBRACE", "}", TokenType.PUNCTUATION, KeywordType.VALUE), LBRACE (137, "LBRACE", "{", EnumSet.of(TokenType.PUNCTUATION), KeywordType.VALUE),
LPAREN (140, "LPAREN", "(", TokenType.PUNCTUATION), RBRACE (138, "RBRACE", "}", EnumSet.of(TokenType.PUNCTUATION), KeywordType.VALUE),
RPAREN (141, "RPAREN", ")", TokenType.PUNCTUATION), LPAREN (139, "LPAREN", "(", EnumSet.of(TokenType.PUNCTUATION)),
LSQBRACKET (142, "LSQBRACKET", "[", TokenType.PUNCTUATION), RPAREN (140, "RPAREN", ")", EnumSet.of(TokenType.PUNCTUATION)),
RSQBRACKET (143, "RSQBRACKET", "]", TokenType.PUNCTUATION), LSQBRACKET (141, "LSQBRACKET", "[", EnumSet.of(TokenType.PUNCTUATION)),
THROWS (144, "THROWS", "throws", TokenType.DECLARATION, KeywordType.KEYWORD), RSQBRACKET (142, "RSQBRACKET", "]", EnumSet.of(TokenType.PUNCTUATION)),
ESCAPED_COLON (201, "ESCCOLON", "\\:", EnumSet.of(TokenType.PUNCTUATION, TokenType.MODULE_NAME)),
ESCAPED_ATSIGH (202, "ESCATSIGH", "\\@", EnumSet.of(TokenType.PUNCTUATION, TokenType.MODULE_NAME)),
ESCAPED_BACKSLASH (203, "ESCBACKSLASH", "\\\\", EnumSet.of(TokenType.PUNCTUATION, TokenType.MODULE_NAME)),
/* /*
* Special tokens * Special tokens
*/ */
ERROR (145, "ERROR", "error", TokenType.MODIFIER), ERROR (145, "ERROR", "error", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME)),
COMMENT (146, "COMMENT", "comment", TokenType.MODIFIER), COMMENT (146, "COMMENT", "comment", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME)),
TYPE (147, "TYPE", "type", TokenType.MODIFIER), TYPE (147, "TYPE", "type", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME)),
LENGTH (148, "LENGTH", "length", TokenType.DECLARATION), LENGTH (148, "LENGTH", "length", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME )),
INLINERETURN (149, "INLINERETURN", "inline-return", TokenType.MODIFIER), INLINERETURN (149, "INLINERETURN", "inline-return", EnumSet.of(TokenType.MODIFIER)),
INLINEMETHOD (150, "INLINEMETHOD", "inline-method", TokenType.MODIFIER), INLINEMETHOD (150, "INLINEMETHOD", "inline-method", EnumSet.of(TokenType.MODIFIER)),
INLINENEWINSTANCE (151, "INLINENEWINSTANCE", "inline-new", TokenType.MODIFIER), INLINENEWINSTANCE (151, "INLINENEWINSTANCE", "inline-new",EnumSet.of(TokenType.MODIFIER)),
/* /*
* Added for jasm * Added for jasm
*/ */
METHODREF (152, "METHODREF", "Method", TokenType.DECLARATION, KeywordType.KEYWORD, true), METHODREF (152, "METHODREF", "Method", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
FIELDREF (153, "FIELD", "Field", TokenType.DECLARATION, KeywordType.KEYWORD, true), FIELDREF (153, "FIELD", "Field", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
STACK (154, "STACK", "stack", TokenType.DECLARATION, KeywordType.KEYWORD, true), STACK (154, "STACK", "stack", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
LOCAL (155, "LOCAL", "locals", TokenType.DECLARATION, KeywordType.KEYWORD, true), LOCAL (155, "LOCAL", "locals", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
CPINDEX (156, "CPINDEX", "CPINDEX", TokenType.DECLARATION, true), CPINDEX (156, "CPINDEX", "CPINDEX", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
CPNAME (157, "CPNAME", "CPName", TokenType.DECLARATION, true), CPNAME (157, "CPNAME", "CPName", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
SIGN (158, "SIGN", "SIGN", TokenType.DECLARATION, true), SIGN (158, "SIGN", "SIGN", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
BITS (159, "BITS", "bits", TokenType.MISC, KeywordType.KEYWORD, true), BITS (159, "BITS", "bits", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
INF (160, "INF", "Inf", "Infinity", TokenType.MISC, KeywordType.KEYWORD), INF (160, "INF", "Inf", "Infinity", EnumSet.of(TokenType.MISC, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
NAN (161, "NAN", "NaN", TokenType.MISC, KeywordType.KEYWORD, true), NAN (161, "NAN", "NaN", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
INNERCLASS (162, "INNERCLASS", "InnerClass", TokenType.DECLARATION, KeywordType.KEYWORD, true), INNERCLASS (162, "INNERCLASS", "InnerClass", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
OF (163, "OF", "of", TokenType.DECLARATION, KeywordType.KEYWORD, true), OF (163, "OF", "of", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
SYNTHETIC (164, "SYNTHETIC", "synthetic", TokenType.MODIFIER, KeywordType.KEYWORD, true), SYNTHETIC (164, "SYNTHETIC", "synthetic", EnumSet.of(TokenType.MODIFIER, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
STRICT (165, "STRICT", "strict", TokenType.MODIFIER, KeywordType.KEYWORD, true), STRICT (165, "STRICT", "strict", EnumSet.of(TokenType.MODIFIER, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
DEPRECATED (166, "DEPRECATED", "deprecated", TokenType.MODIFIER, KeywordType.KEYWORD, true), DEPRECATED (166, "DEPRECATED", "deprecated", EnumSet.of(TokenType.MODIFIER, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
VERSION (167, "VERSION", "version", TokenType.DECLARATION, KeywordType.KEYWORD, true), VERSION (167, "VERSION", "version", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
MODULE (168, "MODULE", "module", TokenType.DECLARATION, KeywordType.KEYWORD), MODULE (168, "MODULE", "module", EnumSet.of(TokenType.DECLARATION, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
ANNOTATION (169, "ANNOTATION", "@", TokenType.MISC), ANNOTATION (169, "ANNOTATION", "@", EnumSet.of(TokenType.MISC, TokenType.MODULE_NAME )),
PARAM_NAME (173, "PARAM_NAME", "#", TokenType.MISC), PARAM_NAME (173, "PARAM_NAME", "#", EnumSet.of(TokenType.MISC, TokenType.MODULE_NAME )),
VARARGS (170, "VARARGS", "varargs", TokenType.MODIFIER, KeywordType.KEYWORD), VARARGS (170, "VARARGS", "varargs", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
BRIDGE (171, "BRIDGE", "bridge", TokenType.MODIFIER, KeywordType.KEYWORD), BRIDGE (171, "BRIDGE", "bridge", EnumSet.of(TokenType.MODIFIER, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
// Declaration keywords // Declaration keywords
BOOTSTRAPMETHOD (172, "BOOTSTRAPMETHOD", "BootstrapMethod", TokenType.DECLARATION, KeywordType.KEYWORD, true), BOOTSTRAPMETHOD (172, "BOOTSTRAPMETHOD", "BootstrapMethod", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
//Module statements //Module statements
REQUIRES (180, "REQUIRES", "requires", TokenType.DECLARATION, KeywordType.KEYWORD, true), REQUIRES (180, "REQUIRES", "requires", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
EXPORTS (182, "EXPORTS", "exports", TokenType.DECLARATION, KeywordType.KEYWORD, true), EXPORTS (182, "EXPORTS", "exports", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
TO (183, "TO", "to", TokenType.DECLARATION, KeywordType.KEYWORD, true), TO (183, "TO", "to", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
USES (184, "USES", "uses", TokenType.DECLARATION, KeywordType.KEYWORD, true), USES (184, "USES", "uses", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
PROVIDES (185, "PROVIDES", "provides", TokenType.DECLARATION, KeywordType.KEYWORD, true), PROVIDES (185, "PROVIDES", "provides", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
WITH (186, "WITH", "with", TokenType.DECLARATION, KeywordType.KEYWORD, true); WITH (186, "WITH", "with", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
OPENS (187, "OPENS", "opens", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD);
final static EnumSet<Token> ALL_TOKENS = EnumSet.allOf(Token.class);
// Misc Keywords // Misc Keywords
private Integer value; final private Integer value; // 160
private String printval; final private String printval; // INF
private String alias; final private String parsekey; // inf
private TokenType tok_type; final private String alias; // Infinity
private KeywordType key_type; final private EnumSet<TokenType> tokenType; // TokenType.MISC, TokenType.MODULE_NAME
private String parsekey; final private KeywordType key_type; // KeywordType.KEYWORD
private boolean possible_jasm_identifier;
public static Optional<Token> get(String parsekey, KeywordType ktype) {
return ALL_TOKENS.stream().filter(t->t.key_type == ktype).filter(t->t.parsekey.equals(parsekey)).findFirst();
}
// By default, if a KeywordType is not specified, it has the value 'TOKEN' // By default, if a KeywordType is not specified, it has the value 'TOKEN'
Token(Integer val, String print, String op, TokenType ttype) { Token(Integer val, String print, String op, EnumSet<TokenType> ttype) {
init(val, print, op, null, ttype, KeywordType.TOKEN, false); this(val, print, op, null, ttype, KeywordType.TOKEN);
} }
Token(Integer val, String print, String op, TokenType ttype, boolean ident) { Token(Integer val, String print, String op, String als, EnumSet<TokenType> ttype) {
init(val, print, op, null, ttype, KeywordType.TOKEN, ident); this(val, print, op, als, ttype, KeywordType.TOKEN);
} }
Token(Integer val, String print, String op, String als, TokenType ttype) { Token(Integer val, String print, String op, EnumSet<TokenType> ttype, KeywordType ktype) {
init(val, print, op, als, ttype, KeywordType.TOKEN, false); this(val, print, op, null, ttype, ktype);
} }
Token(Integer val, String print, String op, TokenType ttype, KeywordType ktype) { Token(Integer val, String print, String op, String als, EnumSet<TokenType> ttype, KeywordType ktype) {
init(val, print, op, null, ttype, ktype, false); this.value = val;
} this.printval = print;
this.parsekey = op;
Token(Integer val, String print, String op, TokenType ttype, KeywordType ktype, boolean ident) { this.tokenType = ttype;
init(val, print, op, null, ttype, ktype, ident); this.key_type = ktype;
} this.alias = als;
Token(Integer val, String print, String op, String als, TokenType ttype, KeywordType ktype) {
init(val, print, op, als, ttype, ktype, false);
}
private void init(Integer val, String print, String op, String als, TokenType ttype, KeywordType ktype, boolean ident) {
value = val;
printval = print;
parsekey = op;
tok_type = ttype;
key_type = ktype;
alias = als;
possible_jasm_identifier = ident;
} }
public String printval() { public String printval() {
@ -361,153 +366,18 @@ public class JasmTokens {
} }
public boolean possibleJasmIdentifier() { public boolean possibleJasmIdentifier() {
return possible_jasm_identifier; return tokenType.contains(TokenType.JASM_IDENT);
} }
public boolean possibleModuleName() { return tokenType.contains(TokenType.MODULE_NAME) && !tokenType.contains(TokenType.PUNCTUATION); }
@Override @Override
public String toString() { public String toString() {
return "<" + printval + "> [" + value + "]"; return "<" + printval + "> [" + value + "]";
} }
}
/**
* Initialized keyword and token Hash Maps (and Reverse Tables)
*/
static protected final int MaxTokens = 172;
private static HashMap<Integer, Token> TagToTokens = new HashMap<>(MaxTokens);
private static HashMap<String, Token> SymbolToTokens = new HashMap<>(MaxTokens);
private static HashMap<String, Token> ParsekeyToTokens = new HashMap<>(MaxTokens);
static protected final int MaxValTokens = 12;
private static HashMap<Integer, Token> TagToValTokens = new HashMap<>(MaxValTokens);
private static HashMap<String, Token> SymbolToValTokens = new HashMap<>(MaxValTokens);
private static HashMap<String, Token> ParsekeyToValTokens = new HashMap<>(MaxValTokens);
private static HashMap<Integer, Token> PossibleJasmIdentifiers = new HashMap<>(MaxValTokens);
static protected final int MaxKeywords = 40;
private static HashMap<Integer, Token> TagToKeywords = new HashMap<>(MaxKeywords);
private static HashMap<String, Token> SymbolToKeywords = new HashMap<>(MaxKeywords);
private static HashMap<String, Token> ParsekeyToKeywords = new HashMap<>(MaxKeywords);
static {
// register all of the tokens
for (Token tk : Token.values()) {
registerToken(tk);
}
}
private static void registerToken(Token tk) {
// Tag is a keyword
if (tk.key_type == KeywordType.KEYWORD) {
TagToKeywords.put(tk.value, tk);
if (tk.alias != null) {
ParsekeyToKeywords.put(tk.alias, tk);
}
SymbolToKeywords.put(tk.printval, tk);
if (tk.parsekey != null) {
ParsekeyToKeywords.put(tk.parsekey, tk);
}
}
// Values (and Keywords) go on the Val tokens list
if (tk.key_type == KeywordType.KEYWORD
|| tk.key_type == KeywordType.VALUE) {
TagToValTokens.put(tk.value, tk);
SymbolToValTokens.put(tk.printval, tk);
if (tk.alias != null) {
SymbolToValTokens.put(tk.alias, tk);
}
if (tk.parsekey != null) {
ParsekeyToValTokens.put(tk.parsekey, tk);
}
}
// make the list of 'possible jasm identifiers'
if (tk.possible_jasm_identifier) {
PossibleJasmIdentifiers.put(tk.value(), tk);
}
// Finally, register all tokens
TagToTokens.put(tk.value, tk);
SymbolToTokens.put(tk.printval, tk);
ParsekeyToTokens.put(tk.printval, tk);
}
/* Token accessors */
public static Token token(int tk) {
return TagToTokens.get(tk);
}
public static Token val_token(int tk) {
return TagToValTokens.get(tk);
}
public static Token keyword_token(int tk) {
return TagToKeywords.get(tk);
}
public static Token possibleJasmIdentifiers(int token) {
return PossibleJasmIdentifiers.get(token);
}
/* Reverse lookup accessors */
public static Token token(String parsekey) {
return ParsekeyToTokens.get(parsekey);
}
public static Token val_token(String parsekey) {
return ParsekeyToValTokens.get(parsekey);
}
public static Token keyword_token(String parsekey) {
return ParsekeyToKeywords.get(parsekey);
}
/* Reverse lookup by ID accessors */
public static Token token_ID(String ID) {
return ParsekeyToTokens.get(ID);
}
public static Token val_token_ID(String ID) {
return ParsekeyToValTokens.get(ID);
}
public static Token keyword_token_ID(String ID) {
return ParsekeyToKeywords.get(ID);
}
public static String keywordName(int token) {
String retval = null;
Token tk = keyword_token(token);
if (tk != null) {
retval = tk.parsekey;
}
return retval;
}
public static int val_token_int(String idValue) {
Token kwd = val_token(idValue);
int retval = Token.IDENT.value;
if (kwd != null) {
retval = kwd.value;
}
return retval;
} }
public static Token keyword_token_ident(String idValue) { public static Token keyword_token_ident(String idValue) {
Token kwd = keyword_token(idValue); return Token.get(idValue,KeywordType.KEYWORD).orElse(Token.IDENT);
if (kwd == null) {
kwd = Token.IDENT;
}
return kwd;
}
public static int keyword_token_int(String idValue) {
return keyword_token_ident(idValue).value();
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,8 +22,8 @@
*/ */
package org.openjdk.asmtools.jasm; package org.openjdk.asmtools.jasm;
import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MAJOR_VERSION; import static org.openjdk.asmtools.jasm.CFVersion.DEFAULT_MAJOR_VERSION;
import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MINOR_VERSION; import static org.openjdk.asmtools.jasm.CFVersion.DEFAULT_MINOR_VERSION;
import org.openjdk.asmtools.util.I18NResourceBundle; import org.openjdk.asmtools.util.I18NResourceBundle;
import org.openjdk.asmtools.util.ProductInfo; import org.openjdk.asmtools.util.ProductInfo;
import java.io.File; import java.io.File;
@ -42,6 +42,7 @@ public class Main {
* Name of the program. * Name of the program.
*/ */
String program; String program;
/** /**
* The stream where error message are printed. * The stream where error message are printed.
*/ */
@ -61,8 +62,7 @@ public class Main {
private boolean strict = false; private boolean strict = false;
private String props = null; private String props = null;
private int nwarnings = 0; private int nwarnings = 0;
private short major_version = DEFAULT_MAJOR_VERSION; private CFVersion cfv = new CFVersion();
private short minor_version = DEFAULT_MINOR_VERSION;
private int bytelimit = 0; private int bytelimit = 0;
private boolean debugScanner = false; private boolean debugScanner = false;
private boolean debugMembers = false; private boolean debugMembers = false;
@ -70,6 +70,7 @@ public class Main {
private boolean debugAnnot = false; private boolean debugAnnot = false;
private boolean debugInstr = false; private boolean debugInstr = false;
/** /**
* Constructor. * Constructor.
*/ */
@ -197,8 +198,7 @@ public class Main {
return false; return false;
} }
try { try {
major_version = Short.parseShort(versions[0]); cfv = new CFVersion(Short.parseShort(versions[0]), Short.parseShort(versions[1]) );
minor_version = Short.parseShort(versions[1]);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
error(i18n.getString("jasm.error.invalid_major_minor_param")); error(i18n.getString("jasm.error.invalid_major_minor_param"));
usage(); usage();
@ -237,8 +237,7 @@ public class Main {
strict = false; strict = false;
props = null; props = null;
nwarnings = 0; nwarnings = 0;
major_version = DEFAULT_MAJOR_VERSION; cfv = new CFVersion();
minor_version = DEFAULT_MINOR_VERSION;
bytelimit = 0; bytelimit = 0;
} }
@ -262,7 +261,7 @@ public class Main {
sf = new Environment(new File(inpname), out, nowarn); sf = new Environment(new File(inpname), out, nowarn);
sf.traceFlag = traceFlag; sf.traceFlag = traceFlag;
sf.debugInfoFlag = debugInfoFlag; sf.debugInfoFlag = debugInfoFlag;
p = new Parser(sf, major_version, minor_version); p = new Parser(sf, cfv);
p.setDebugFlags(debugScanner, debugMembers, debugCP, debugAnnot, debugInstr); p.setDebugFlags(debugScanner, debugMembers, debugCP, debugAnnot, debugInstr);
p.parseFile(); p.parseFile();
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,6 +22,8 @@
*/ */
package org.openjdk.asmtools.jasm; package org.openjdk.asmtools.jasm;
import java.util.stream.Collectors;
import static org.openjdk.asmtools.jasm.RuntimeConstants.*; import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
import static org.openjdk.asmtools.jasm.JasmTokens.*; import static org.openjdk.asmtools.jasm.JasmTokens.*;
import static org.openjdk.asmtools.jasm.Tables.CF_Context; import static org.openjdk.asmtools.jasm.Tables.CF_Context;
@ -38,36 +40,29 @@ public class Modifiers {
* Modifier masks * Modifier masks
*/ */
public static final int MM_ATTR = SYNTHETIC_ATTRIBUTE | DEPRECATED_ATTRIBUTE; public static final int MM_ATTR = SYNTHETIC_ATTRIBUTE | DEPRECATED_ATTRIBUTE;
public static final int MM_ACCESS = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED;
public static final int MM_INTRF = ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE | MM_ATTR ; // | ACC_MODULE ; public static final int MM_INTRF = MM_ACCESS | ACC_ABSTRACT | ACC_INTERFACE | MM_ATTR | ACC_ANNOTATION;
public static final int MM_CLASS = ACC_PUBLIC | ACC_FINAL| ACC_SUPER | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM | MM_ATTR | ACC_MODULE ; public static final int MM_CLASS = MM_ACCESS | ACC_FINAL | ACC_SUPER | ACC_ABSTRACT | ACC_ENUM | MM_ATTR | ACC_MODULE ;
public static final int MM_ACCESS = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED; // | ACC_MODULE;
public static final int MM_FIELD = MM_ACCESS | ACC_STATIC | ACC_FINAL | ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM | MM_ATTR ; // | ACC_MODULE ; public static final int MM_FIELD = MM_ACCESS | ACC_STATIC | ACC_FINAL | ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM | MM_ATTR ;
public static final int MM_I_METHOD = ACC_ABSTRACT | ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC | ACC_VARARGS | ACC_BRIDGE | ACC_SYNTHETIC ; // interface method public static final int MM_I_METHOD = ACC_ABSTRACT | ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC | ACC_VARARGS | ACC_BRIDGE | ACC_SYNTHETIC ; // interface method
public static final int MM_A_METHOD = MM_ACCESS | ACC_ABSTRACT | MM_ATTR; public static final int MM_A_METHOD = MM_ACCESS | ACC_ABSTRACT | MM_ATTR;
public static final int MM_N_METHOD = MM_ACCESS | ACC_STRICT | ACC_VARARGS | ACC_SYNTHETIC | MM_ATTR; // <init> public static final int MM_N_METHOD = MM_ACCESS | ACC_STRICT | ACC_VARARGS | ACC_SYNTHETIC | MM_ATTR; // <init>
public static final int MM_METHOD = MM_ACCESS | ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE | ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | MM_ATTR ; // | ACC_MODULE ; public static final int MM_METHOD = MM_ACCESS | ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE | ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | MM_ATTR ; // | ACC_MODULE ;
public static final int MM_INNERCLASS = MM_ACCESS | ACC_STATIC | ACC_FINAL | ACC_SUPER | ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM | MM_ATTR ; // | ACC_MODULE ; public static final int MM_INNERCLASS = MM_ACCESS | ACC_STATIC | ACC_FINAL | ACC_SUPER | ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM | MM_ATTR ; // | ACC_MODULE ;
public static final int MM_REQUIRES = ACC_REEXPORT | ACC_SYNTHETIC | ACC_MANDATED ; public static final int MM_REQUIRES = ACC_TRANSITIVE | ACC_STATIC_PHASE | ACC_SYNTHETIC | ACC_MANDATED ;
public static final int MM_EXPORTS = ACC_SYNTHETIC | ACC_MANDATED ;
private Modifiers() { private Modifiers() {
} }
public static Modifiers ModifiersObject() {
if (ref == null) {
ref = new Modifiers();
}
return ref;
}
public static boolean validRequires(int mod) { public static boolean validRequires(int mod) {
return (mod & ~MM_REQUIRES) == 0; return (mod & ~MM_REQUIRES) == 0;
} }
public static boolean validClass(int mod) { public static boolean validExports(int mod) { return (mod & ~MM_EXPORTS) == 0; }
return (mod & ~MM_CLASS) == 0;
}
public static boolean validInnerClass(int mod) { public static boolean validInnerClass(int mod) {
return (mod & ~MM_INNERCLASS) == 0; return (mod & ~MM_INNERCLASS) == 0;
@ -85,6 +80,18 @@ public class Modifiers {
return (mod & ~MM_INTRF) == 0; return (mod & ~MM_INTRF) == 0;
} }
public static int getInvalidModifiers4Interface(int mod) {
return mod & ~MM_INTRF;
}
public static boolean validClass(int mod) {
return (mod & ~MM_CLASS) == 0;
}
public static int getInvalidModifiers4Class(int mod) {
return (mod & ~MM_CLASS);
}
public static boolean validAbstractMethod(int mod) { public static boolean validAbstractMethod(int mod) {
return (mod & ~MM_A_METHOD) == 0; return (mod & ~MM_A_METHOD) == 0;
} }
@ -95,7 +102,7 @@ public class Modifiers {
public static boolean validInterfaceMethod(int mod, ClassData cd) { public static boolean validInterfaceMethod(int mod, ClassData cd) {
return ((mod & ~MM_I_METHOD) == 0) && return ((mod & ~MM_I_METHOD) == 0) &&
(cd.major_version >= 52 || isPublic(mod) && isAbstract(mod) && !isStatic(mod)); (cd.cfv.major_version() >= 52 || isPublic(mod) && isAbstract(mod) && !isStatic(mod));
} }
public static boolean validInterfaceField(int mod) { public static boolean validInterfaceField(int mod) {
@ -194,7 +201,10 @@ public class Modifiers {
return isSyntheticPseudoMod(mod) || isDeprecatedPseudoMod(mod); return isSyntheticPseudoMod(mod) || isDeprecatedPseudoMod(mod);
} }
public static boolean isReexport(int mod) { return (mod & ACC_REEXPORT) != 0; } public static boolean isTransitive(int mod) { return (mod & ACC_TRANSITIVE) != 0; }
public static boolean isStaticPhase(int mod) { return (mod & ACC_STATIC_PHASE) != 0; }
/* /*
* Checks that only one (or none) of the Access flags are set. * Checks that only one (or none) of the Access flags are set.
*/ */
@ -202,7 +212,6 @@ public class Modifiers {
boolean retval = true; boolean retval = true;
switch (mod & MM_ACCESS) { switch (mod & MM_ACCESS) {
case 0: case 0:
// case ACC_MODULE:
case ACC_PUBLIC: case ACC_PUBLIC:
case ACC_PRIVATE: case ACC_PRIVATE:
case ACC_PROTECTED: case ACC_PROTECTED:
@ -210,9 +219,7 @@ public class Modifiers {
default: default:
retval = false; retval = false;
} }
return retval; return retval;
} }
/* /*
@ -223,27 +230,41 @@ public class Modifiers {
return (mod & (flagA | flagB)) == (flagA | flagB); return (mod & (flagA | flagB)) == (flagA | flagB);
} }
private static String getNames(int bits) {
return RuntimeConstants.ACC_NAMES.entrySet().stream()
.filter(e -> (e.getKey() & bits) != 0 && !e.getValue().isEmpty())
.map(s->s.getValue())
.collect(Collectors.joining(", "));
}
/** /**
* Check the modifier flags for the class * Check the modifier flags for the class
* *
* @param env The error reporting environment. * @param env The error reporting environment.
* @param mod The modifier flags being checked * @param mod The modifier flags being checked
* @param pos the position of the parser in the file * @param scanner The file parser
*/ */
public static void checkClassModifiers(Environment env, int mod, int pos) { public static void checkClassModifiers(Environment env, int mod, Scanner scanner) {
if (isInterface(mod)) { if (isInterface(mod)) {
if (!validInterface(mod)) { if( isEnum(mod) ) {
env.error(pos, "warn.invalid.modifier.int"); env.error(scanner.pos, "warn.invalid.modifier.class.intenum");
} else if ( !validInterface(mod) ) {
String names = getNames(getInvalidModifiers4Interface(mod));
env.error(scanner.pos, "warn.invalid.modifier.int", (names.isEmpty() ? "." : " - " + names));
} }
if (!isAbstract(mod)) { if (!isAbstract(mod)) {
env.error(pos, "warn.invalid.modifier.int.abs"); env.error(scanner.pos, "warn.invalid.modifier.int.abs");
} }
} else { } else {
if (!validClass(mod)) { if ( scanner.token != Token.CLASS && !isEnum(mod) && scanner.token != Token.ANNOTATION) {
env.error(pos, "warn.invalid.modifier.class"); env.error(scanner.pos, "warn.missing.modifier.class");
}
if (! validClass(mod)) {
String names = getNames(getInvalidModifiers4Class(mod));
env.error(scanner.pos, "warn.invalid.modifier.class", (names.isEmpty() ? "." : " - " + names));
} }
if (isAbstract(mod) && Modifiers.isFinal(mod)) { if (isAbstract(mod) && Modifiers.isFinal(mod)) {
env.error(pos, "warn.invalid.modifier.class.finabs"); env.error(scanner.pos, "warn.invalid.modifier.class.finabs");
} }
} }
} }
@ -386,6 +407,9 @@ public class Modifiers {
sb.append(Token.FINAL.parsekey() + " "); sb.append(Token.FINAL.parsekey() + " ");
} }
if ((context == CF_Context.CTX_CLASS || context == CF_Context.CTX_INNERCLASS) && isInterface(mod)) { if ((context == CF_Context.CTX_CLASS || context == CF_Context.CTX_INNERCLASS) && isInterface(mod)) {
if (isAnnotation(mod)) {
sb.append(Token.ANNOTATION_ACCESS.parsekey() + " ");
}
sb.append(Token.INTERFACE.parsekey() + " "); sb.append(Token.INTERFACE.parsekey() + " ");
} }
if (isStrict(mod)) { if (isStrict(mod)) {
@ -403,9 +427,6 @@ public class Modifiers {
if (context == CF_Context.CTX_METHOD && isMandated(mod)) { if (context == CF_Context.CTX_METHOD && isMandated(mod)) {
sb.append(Token.MANDATED.parsekey() + " "); sb.append(Token.MANDATED.parsekey() + " ");
} }
// We don't have print identifiers for annotation flags
// if (isAnnotation(mod))
// sb.append(Tables.keywordName(Tables.ANNOTATION) + " ");
return sb; return sb;
} }
@ -423,9 +444,16 @@ public class Modifiers {
return sb.toString(); return sb.toString();
} }
public static String moduleFlags( int flags ) {
return "";
}
public static String accessString(int mod, CF_Context context) { public static String accessString(int mod, CF_Context context) {
StringBuffer sb = _accessString(mod, context); return (context == CF_Context.CTX_MODULE) ?
return sb.toString(); moduleFlags(mod) :
_accessString(mod, context).toString();
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,34 +22,63 @@
*/ */
package org.openjdk.asmtools.jasm; package org.openjdk.asmtools.jasm;
import org.openjdk.asmtools.common.Module;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import static org.openjdk.asmtools.jasm.RuntimeConstants.ACC_NONE; /**
import static org.openjdk.asmtools.jasm.RuntimeConstants.ACC_REEXPORT; * The module attribute
*/
public class ModuleAttr extends AttrData { class ModuleAttr extends AttrData {
// shared data // shared data
private final Module.Builder builder; private Module.Builder builder;
private final ClassData clsData; private final ClassData clsData;
private Module module; private final Function<String, ConstantPool.ConstCell> findCellAsciz;
private final Function<String, ConstantPool.ConstCell> findCellClassByName;
private final Function<String, ConstantPool.ConstCell> findCellModuleByName;
private final Function<String, ConstantPool.ConstCell> findCellPackageByName;
// entries to populate tables of the module attribute
BiConsumer<String, Integer> requires = (mn, f) -> this.builder.require(mn, f);
BiConsumer<String, Set<String>> exports = (pn, ms) -> this.builder.exports(new Module.Exported(pn), ms);
BiConsumer<String, Set<String>> opens = (pn, ms) -> this.builder.opens(new Module.Opened(pn), ms);
BiConsumer<String, Set<String>> provides = (tn, ts) -> this.builder.provides(new Module.Provided(tn), ts);
Consumer<Set<String>> uses = (ts) -> this.builder.uses(ts);
ModuleAttr(ClassData cdata) { ModuleAttr(ClassData cdata) {
super(cdata, Tables.AttrTag.ATT_Module.parsekey()); super(cdata, Tables.AttrTag.ATT_Module.parsekey());
builder = new Module.Builder(); builder = new Module.Builder();
clsData = cdata; clsData = cdata;
findCellAsciz = (name) -> clsData.pool.FindCellAsciz(name);
findCellClassByName = (name) -> clsData.pool.FindCellClassByName(name);
findCellModuleByName = (name) -> clsData.pool.FindCellModuleByName(name);
findCellPackageByName = (name) -> clsData.pool.FindCellPackageByName(name);
} }
public ModuleAttr build() { void openModule() {
Content.instance.requiresStruct = new RequiresStruct(); builder.setModuleFlags(Module.Modifier.ACC_OPEN);
Content.instance.exportsStruct = new ExportsStruct(); }
Content.instance.usesStruct = new UsesStruct(); void setModuleName(String value) { builder.setModuleName(value);}
Content.instance.providesStruct = new ProvidesStruct();
ModuleAttr build() {
Module module = builder.build();
Content.instance.header = new HeaderStruct(module.header, findCellModuleByName, findCellAsciz);
Content.instance.requiresStruct = new SetStruct<>(module.requires, findCellModuleByName, findCellAsciz);
Content.instance.exportsMapStruct = new MapStruct<>(module.exports, findCellPackageByName, findCellModuleByName );
Content.instance.opensMapStruct = new MapStruct<>(module.opens,findCellPackageByName, findCellModuleByName );
Content.instance.usesStruct = new SetStruct<>(module.uses, findCellClassByName, null);
Content.instance.providesMapStruct = new MapStruct<>(module.provides, findCellClassByName, findCellClassByName);
return this; return this;
} }
@Override @Override
public int attrLength() { return Content.instance.getLength(); } public int attrLength() {
return Content.instance.getLength();
}
@Override @Override
public void write(CheckedDataOutputStream out) throws IOException { public void write(CheckedDataOutputStream out) throws IOException {
@ -57,178 +86,205 @@ public class ModuleAttr extends AttrData {
Content.instance.write(out); Content.instance.write(out);
} }
/**
* Adds a module on which the current module has a dependence.
*/
protected void require(String d, boolean reexports) {
builder.require(d, reexports);
}
/**
* Adds a qualified/an unqualified module exports.
*/
protected void exports(String p, Set<String> ms) { builder.exports(p, ms); }
/**
* Adds a service dependence's of this module
*/
protected void use(String cn) {
builder.use(cn);
}
/**
* Adds a service that a module provides one implementation of.
*/
protected void provide(String s, String impl) {
builder.provide(s, impl);
}
/**
* Gets the module if it is absent builds one
*
* @return the Module
*/
private Module buildModuleIfAbsent() {
if (module == null) {
module = builder.build();
}
return module;
}
private enum Content implements Data { private enum Content implements Data {
instance { instance {
@Override @Override
public int getLength() { public int getLength() {
return requiresStruct.getLength() + exportsStruct.getLength() + return header.getLength() +
usesStruct.getLength() + providesStruct.getLength(); requiresStruct.getLength() +
exportsMapStruct.getLength() +
opensMapStruct.getLength() +
usesStruct.getLength() +
providesMapStruct.getLength();
} }
@Override @Override
public void write(CheckedDataOutputStream out) throws IOException { public void write(CheckedDataOutputStream out) throws IOException {
// keep order! // keep order!
header.write(out);
requiresStruct.write(out); requiresStruct.write(out);
exportsStruct.write(out); exportsMapStruct.write(out);
opensMapStruct.write(out);
usesStruct.write(out); usesStruct.write(out);
providesStruct.write(out); providesMapStruct.write(out);
} }
}; };
RequiresStruct requiresStruct;
ExportsStruct exportsStruct; HeaderStruct header ;
UsesStruct usesStruct; SetStruct<Module.Dependence> requiresStruct;
ProvidesStruct providesStruct; MapStruct<Module.Exported> exportsMapStruct;
MapStruct<Module.Opened> opensMapStruct;
SetStruct<Module.Uses> usesStruct;
MapStruct<Module.Provided> providesMapStruct;
} }
private final static class Module { /**
//* A service dependence's of this module * u2 {exports|opens}_count;
final Set<String> uses; * { u2 {exports|opens}_index;
//* A module on which the current module has a dependence. * u2 {exports|opens}_flags;
private final Set<Dependence> requires; * u2 {exports|opens}_to_count;
//* A module export, may be qualified or unqualified. * u2 {exports|opens}_to_index[{exports|opens}_to_count];
private final Map<String, Set<String>> exports; * } {exports|opens}[{exports|opens}_count];
//* A service that a module provides one or more implementations of. * or
private final Map<String, Set<String>> provides; * u2 provides_count;
* { u2 provides_index;
* u2 provides_with_count;
* u2 provides_with_index[provides_with_count];
* } provides[provides_count];
*/
private class MapStruct<T extends Module.TargetType> implements Data {
final List<Triplet<ConstantPool.ConstCell, Integer, List<ConstantPool.ConstCell>>> exportsOpensList = new ArrayList<>();
final List<Pair<ConstantPool.ConstCell, List<ConstantPool.ConstCell>>> providesList = new ArrayList<>();
private Module(Set<Dependence> requires, MapStruct(Map<T, Set<String>> source,
Map<String, Set<String>> exports, Function<String,ConstantPool.ConstCell> nameFinder,
Set<String> uses, Function<String,ConstantPool.ConstCell> targetFinder) {
Map<String, Set<String>> provides) { Objects.requireNonNull(source);
this.requires = Collections.unmodifiableSet(requires); source.entrySet().stream()
this.exports = Collections.unmodifiableMap(exports); .sorted(Map.Entry.comparingByKey())
this.uses = Collections.unmodifiableSet(uses); .forEach(e -> {
this.provides = Collections.unmodifiableMap(provides); ArrayList<ConstantPool.ConstCell> to = new ArrayList<>();
e.getValue().forEach(mn -> to.add(targetFinder.apply(mn)));
if (e.getKey().isFlagged()) {
exportsOpensList.add(new Triplet<>
( nameFinder.apply(e.getKey().getTypeName()),
((Module.FlaggedTargetType) e.getKey()).getFlags(),
to));
} else {
providesList.add(new Pair<>(nameFinder.apply(e.getKey().getTypeName()),
to));
}
}
);
} }
//* A module on which the current module has a dependence. @Override
private final static class Dependence implements Comparable<Dependence> { public void write(CheckedDataOutputStream out) throws IOException {
private final String mn; if (providesList.isEmpty()) {
private final boolean reexports; out.writeShort(exportsOpensList.size()); // u2 {exports|opens}_count;
for (Triplet<ConstantPool.ConstCell, Integer, List<ConstantPool.ConstCell>> triplet : exportsOpensList) {
public Dependence(String name, boolean reexports) { out.writeShort(triplet.first.arg); // { u2 {exports|opens}_index;
this.mn = name; out.writeShort(triplet.second); // u2 {exports|opens}_flags;
this.reexports = reexports; out.writeShort(triplet.third.size()); // u2 {exports|opens}_to_count;
} for (ConstantPool.ConstCell to : triplet.third)
out.writeShort(to.arg); // u2 {exports|opens}_to_index[{exports|opens}_to_count]; }
/** }
* Returns the module name. } else {
*/ out.writeShort(providesList.size()); // u2 provides_count;
public String name() { return mn; } for (Pair<ConstantPool.ConstCell, List<ConstantPool.ConstCell>> pair : providesList) {
out.writeShort(pair.first.arg); // { u2 provides_index;
/** out.writeShort(pair.second.size()); // u2 provides_with_count;
* Returns the public modifier of the requires. for (ConstantPool.ConstCell to : pair.second)
*/ out.writeShort(to.arg); // u2 provides_with_index[provides_with_count]; }
public boolean isReexports() { return reexports; }
@Override
public int hashCode() {
return mn.hashCode() * 11 + Boolean.hashCode(reexports);
}
@Override
public boolean equals(Object o) {
if (o instanceof Dependence) {
Dependence d = (Dependence) o;
return this.mn.equals(d.mn) && Boolean.compare(reexports, d.isReexports()) == 0;
} }
return false;
}
@Override
public int compareTo(Dependence o) {
int rc = this.mn.compareTo(o.mn);
return rc != 0 ? rc : Boolean.compare(reexports, o.isReexports());
} }
} }
/** @Override
* The module builder. public int getLength() {
*/ if (providesList.isEmpty()) {
private static final class Builder { // (u2:{exports|opens}_count) + (u2:{exports|opens}_index + u2:{exports|opens}_flags u2:{exports|opens}_to_count) * {exports|opens}_count +
public final Set<Dependence> requires = new HashSet<>(); return 2 + 6 * exportsOpensList.size() +
final Map<String, Set<String>> exports = new HashMap<>(); // (u2:{exports|opens}_to_index) * {exports|opens}_to_count
final Set<String> uses = new HashSet<>(); exportsOpensList.stream().mapToInt(p -> p.third.size()).filter(s -> s > 0).sum() * 2;
final Map<String, Set<String>> provides = new HashMap<>(); } else {
// (u2 : provides_count) + (u2:provides_index + u2:provides_with_count) * provides_count +
public Builder() { return 2 + 4 * providesList.size() +
} // (u2:provides_with_index) * provides_with_count
providesList.stream().mapToInt(p -> p.second.size()).filter(s -> s > 0).sum() * 2;
public Builder require(String d, boolean reexports) {
requires.add(new Dependence(d, reexports));
return this;
}
public Builder exports(String p, Set<String> ms) {
Objects.requireNonNull(p);
Objects.requireNonNull(ms);
if (!exports.containsKey(p))
exports.put(p, new HashSet<>());
exports.get(p).addAll(ms);
return this;
}
public Builder use(String cn) {
uses.add(cn);
return this;
}
public Builder provide(String s, String impl) {
provides.computeIfAbsent(s, _k -> new HashSet<>()).add(impl);
return this;
}
/**
* @return The new module
*/
public Module build() {
return new Module(requires, exports, uses, provides);
} }
} }
} }
// Helper class private class HeaderStruct implements Data {
final ConstantPool.ConstCell index;
final int flags;
final ConstantPool.ConstCell versionIndex;
HeaderStruct(Module.Header source,
Function<String,ConstantPool.ConstCell> nameFinder,
Function<String,ConstantPool.ConstCell> versionFinder) {
index = nameFinder.apply(source.getModuleName());
versionIndex = (source.getModuleVersion() == null ) ? null : versionFinder.apply(source.getModuleVersion());
flags = source.getModuleFlags();
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(index.arg); // u2 module_name_index;
out.writeShort(flags); // u2 module_flags;
out.writeShort(versionIndex == null ? 0 : versionIndex.arg); // u2 module_version_index;
}
@Override
public int getLength() {
// u2:module_name_index) + u2:module_flags +u2:module_version_index
return 6;
}
}
/**
* u2 uses_count;
* u2 uses_index[uses_count];
* or
* u2 requires_count;
* { u2 requires_index;
* u2 requires_flags;
* u2 requires_version_index;
* } requires[requires_count];
*/
private class SetStruct<T extends Module.TargetType> implements Data {
final List<ConstantPool.ConstCell> usesList = new ArrayList<>();
final List<Triplet<ConstantPool.ConstCell, Integer, ConstantPool.ConstCell>> requiresList = new ArrayList<>();
SetStruct(Set<T> source,
Function<String,ConstantPool.ConstCell> nameFinder,
Function<String,ConstantPool.ConstCell> versionFinder) {
Objects.requireNonNull(source);
source.forEach(e -> {
if (e.isFlagged()) {
requiresList.add(new Triplet<>(
nameFinder.apply(e.getTypeName()),
((Module.FlaggedTargetType) e).getFlags(),
(((Module.VersionedFlaggedTargetType) e).getVersion() == null) ?
null :
versionFinder.apply(((Module.VersionedFlaggedTargetType) e).getVersion())));
} else {
usesList.add(nameFinder.apply((e.getTypeName())));
}
});
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
if (usesList.isEmpty()) {
out.writeShort(requiresList.size()); // u2 requires_count;
for (Triplet<ConstantPool.ConstCell, Integer, ConstantPool.ConstCell> r : requiresList) {
out.writeShort(r.first.arg); // u2 requires_index;
out.writeShort(r.second); // u2 requires_flags;
out.writeShort(r.third == null ? 0 : r.third.arg); // u2 requires_version_index;
}
} else {
out.writeShort(usesList.size()); // u2 uses_count;
for (ConstantPool.ConstCell u : usesList)
out.writeShort(u.arg); // u2 uses_index[uses_count];
}
}
@Override
public int getLength() {
return usesList.isEmpty() ?
// (u2:requires_count) + (u2:requires_index + u2:requires_flags + u2:requires_version_index) * requires_count
2 + 6 * requiresList.size() :
// (u2:uses_count) + (u2:uses_index) * uses_count
2 + 2 * usesList.size();
}
}
// Helper classes
private class Pair<F, S> { private class Pair<F, S> {
public final F first; final F first;
public final S second; final S second;
Pair(F first, S second) { Pair(F first, S second) {
this.first = first; this.first = first;
@ -236,132 +292,12 @@ public class ModuleAttr extends AttrData {
} }
} }
/** public class Triplet<F, S, T> extends Pair<F,S> {
* u2 requires_count; private final T third;
* { u2 requires_index; Triplet(F first, S second, T third) {
* u2 requires_flags; super(first,second);
* } requires[requires_count]; this.third = third;
*/
class RequiresStruct implements Data {
List<Pair<ConstantPool.ConstCell, Integer>> list = new ArrayList<>();
public RequiresStruct() {
buildModuleIfAbsent().requires.forEach(
r -> list.add(
new Pair<>(clsData.pool.FindCellAsciz(r.name()),
r.isReexports() ? ACC_REEXPORT : ACC_NONE))
);
}
@Override
public int getLength() { return 2 + list.size() * 4; }
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(list.size()); // u2 requires_count;
for (Pair<ConstantPool.ConstCell, Integer> p : list) {
out.writeShort(p.first.arg); // u2 requires_index;
out.writeShort(p.second); // u2 requires_flags;
}
} }
} }
/**
* u2 exports_count;
* { u2 exports_index;
* u2 exports_to_count;
* u2 exports_to_index[exports_to_count];
* } exports[exports_count];
*/
private class ExportsStruct implements Data {
final List<Pair<ConstantPool.ConstCell, List<ConstantPool.ConstCell>>> exports = new ArrayList<>();
ExportsStruct() {
Objects.requireNonNull(module);
//(un)qualified module exports
buildModuleIfAbsent().exports.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(e -> {
ArrayList<ConstantPool.ConstCell> to = new ArrayList<>();
e.getValue().forEach(mn -> to.add(clsData.pool.FindCellAsciz(mn)));
exports.add(new Pair<>(clsData.pool.FindCellAsciz(e.getKey()), to));
}
);
}
@Override
public int getLength() {
return 2 + 4 * exports.size() + exports.stream().mapToInt(p->p.second.size()).filter(s->s>0).sum() * 2;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(exports.size()); // u2 exports_count;
for (Pair<ConstantPool.ConstCell, List<ConstantPool.ConstCell>> pair : exports) {
out.writeShort(pair.first.arg); // u2 exports_index;
out.writeShort(pair.second.size()); // u2 exports_to_count;
for( ConstantPool.ConstCell to : pair.second ) {
out.writeShort(to.arg); // u2 exports_to_index[exports_to_count];
}
}
}
}
/**
* u2 uses_count;
* u2 uses_index[uses_count];
*/
private class UsesStruct implements Data {
final List<ConstantPool.ConstCell> uses = new ArrayList<>();
UsesStruct() {
buildModuleIfAbsent().uses.stream().sorted().forEach(u -> uses.add(clsData.pool.FindCellAsciz(u)));
}
@Override
public int getLength() {
return 2 + 2 * uses.size();
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(uses.size());
for (ConstantPool.ConstCell u : uses)
out.writeShort(u.arg);
}
}
/**
* u2 provides_count;
* { u2 provides_index;
* u2 with_index;
* } provides[provides_count];
*/
private class ProvidesStruct implements Data {
List<Pair<ConstantPool.ConstCell, ConstantPool.ConstCell>> list = new ArrayList<>();
protected ProvidesStruct() {
buildModuleIfAbsent().provides.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(e -> e.getValue().stream()
.sorted()
.forEach(impl -> list.add(new Pair<>(
clsData.pool.FindCellAsciz(e.getKey()), clsData.pool.FindCellAsciz(impl))
)));
}
@Override
public int getLength() {
return 2 + list.size() * 4;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(list.size()); // u2 provides_count;
for (Pair<ConstantPool.ConstCell, ConstantPool.ConstCell> p : list) {
out.writeShort(p.first.arg); // u2 requires_index;
out.writeShort(p.second.arg); // u2 requires_flags;
}
}
}
} }

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -258,6 +258,8 @@ public class ParserAnnotation extends ParseBase {
annttns.add(parseAnnotation()); annttns.add(parseAnnotation());
} else if (isTypeAnnotationToken(scanner.stringValue)) { } else if (isTypeAnnotationToken(scanner.stringValue)) {
annttns.add(parseTypeAnnotation()); annttns.add(parseTypeAnnotation());
} else {
return null;
} }
} }
@ -369,7 +371,7 @@ public class ParserAnnotation extends ParseBase {
// First - validate that the parameter number (integer) // First - validate that the parameter number (integer)
// (eg >= 0, < numParams, and param num is not previously set) // (eg >= 0, < numParams, and param num is not previously set)
int paramNum = scanner.intValue; int paramNum = scanner.intValue;
Integer iParamNum = new Integer(paramNum); Integer iParamNum = Integer.valueOf(paramNum);
if (paramNum < 0 || paramNum >= totalParams) { if (paramNum < 0 || paramNum >= totalParams) {
//invalid Parameter number. Throw an error. //invalid Parameter number. Throw an error.
env.error(scanner.pos, "invalid.paramnum", paramNum); env.error(scanner.pos, "invalid.paramnum", paramNum);

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -450,12 +450,15 @@ d2l: {
ConstantPool.ConstCell NapeCell = parser.pool.FindCell(parseConstValue(ConstType.CONSTANT_NAMEANDTYPE)); ConstantPool.ConstCell NapeCell = parser.pool.FindCell(parseConstValue(ConstType.CONSTANT_NAMEANDTYPE));
ArrayList<ConstantPool.ConstCell> bsm_args = new ArrayList<>(256); ArrayList<ConstantPool.ConstCell> bsm_args = new ArrayList<>(256);
while (scanner.token != Token.SEMICOLON) {
if (scanner.token == Token.COMMA) { for (boolean sep = false; scanner.token != Token.SEMICOLON; sep = true) {
scanner.scan(); if (sep) scanner.expect(Token.COMMA);
} bsm_args.add(parseConstRef(null));
scanner.idValue = null; // Clear tag
bsm_args.add(parseConstRef(null)); bsm_args.add(parseConstRef(null));
} }
BootstrapMethodData bsmData = new BootstrapMethodData(MHCell, bsm_args); BootstrapMethodData bsmData = new BootstrapMethodData(MHCell, bsm_args);
parser.cd.addBootstrapMethod(bsmData); parser.cd.addBootstrapMethod(bsmData);
obj = new ConstantPool.ConstValue_IndyPair(bsmData, NapeCell); obj = new ConstantPool.ConstValue_IndyPair(bsmData, NapeCell);

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,77 +22,69 @@
*/ */
package org.openjdk.asmtools.jasm; package org.openjdk.asmtools.jasm;
import java.util.HashMap;
import java.util.Map;
/** /**
* *
*/ */
public interface RuntimeConstants { public interface RuntimeConstants {
/* Signature Characters */
public static final char SIGC_VOID = 'V';
public static final String SIG_VOID = "V";
public static final char SIGC_BOOLEAN = 'Z';
public static final String SIG_BOOLEAN = "Z";
public static final char SIGC_BYTE = 'B';
public static final String SIG_BYTE = "B";
public static final char SIGC_CHAR = 'C';
public static final String SIG_CHAR = "C";
public static final char SIGC_SHORT = 'S';
public static final String SIG_SHORT = "S";
public static final char SIGC_INT = 'I';
public static final String SIG_INT = "I";
public static final char SIGC_LONG = 'J';
public static final String SIG_LONG = "J";
public static final char SIGC_FLOAT = 'F';
public static final String SIG_FLOAT = "F";
public static final char SIGC_DOUBLE = 'D';
public static final String SIG_DOUBLE = "D";
public static final char SIGC_ARRAY = '[';
public static final String SIG_ARRAY = "[";
public static final char SIGC_CLASS = 'L';
public static final String SIG_CLASS = "L";
public static final char SIGC_METHOD = '(';
public static final String SIG_METHOD = "(";
public static final char SIGC_ENDCLASS = ';';
public static final String SIG_ENDCLASS = ";";
public static final char SIGC_ENDMETHOD = ')';
public static final String SIG_ENDMETHOD = ")";
public static final char SIGC_PACKAGE = '/';
public static final String SIG_PACKAGE = "/";
/* Class File Constants */
// public static final int JAVA_MAGIC = 0xcafebabe;
public static final int JAVA_VERSION = 45;
public static final int JAVA_MINOR_VERSION = 3;
/* Access Flags */ /* Access Flags */
public static final int ACC_NONE = 0x0000; // <<everywhere>> int ACC_NONE = 0x0000; // <<everywhere>>
public static final int ACC_PUBLIC = 0x0001; // class, inner, field, method int ACC_PUBLIC = 0x0001; // class, inner, field, method
public static final int ACC_PRIVATE = 0x0002; // inner, field, method int ACC_PRIVATE = 0x0002; // inner, field, method
public static final int ACC_PROTECTED = 0x0004; // inner, field, method int ACC_PROTECTED = 0x0004; // inner, field, method
public static final int ACC_STATIC = 0x0008; // inner, field, method int ACC_STATIC = 0x0008; // inner, field, method
public static final int ACC_FINAL = 0x0010; // class, inner, field, method int ACC_FINAL = 0x0010; // class, inner, field, method
public static final int ACC_SUPER = 0x0020; // class int ACC_TRANSITIVE = 0x0010; // requires(module)
public static final int ACC_REEXPORT = 0x0020; // requires (ACC_PUBLIC) int ACC_SUPER = 0x0020; // class
public static final int ACC_SYNCHRONIZED = 0x0020; // method int ACC_STATIC_PHASE = 0x0020; // requires(module)
public static final int ACC_VOLATILE = 0x0040; // field int ACC_SYNCHRONIZED = 0x0020; // method
public static final int ACC_BRIDGE = 0x0040; // method int ACC_OPEN = 0x0020; // module
public static final int ACC_TRANSIENT = 0x0080; // field int ACC_VOLATILE = 0x0040; // field
public static final int ACC_VARARGS = 0x0080; // method int ACC_BRIDGE = 0x0040; // method
public static final int ACC_NATIVE = 0x0100; // method int ACC_TRANSIENT = 0x0080; // field
public static final int ACC_INTERFACE = 0x0200; // class, inner int ACC_VARARGS = 0x0080; // method
public static final int ACC_ABSTRACT = 0x0400; // class, inner, method int ACC_NATIVE = 0x0100; // method
public static final int ACC_STRICT = 0x0800; // method int ACC_INTERFACE = 0x0200; // class, inner
public static final int ACC_SYNTHETIC = 0x1000; // class, inner, field, method requires int ACC_ABSTRACT = 0x0400; // class, inner, method
public static final int ACC_ANNOTATION = 0x2000; // class, inner int ACC_STRICT = 0x0800; // method
public static final int ACC_ENUM = 0x4000; // class, inner, field int ACC_SYNTHETIC = 0x1000; // class, inner, field, method, module requires(module) exports(module)
public static final int ACC_MODULE = 0x8000; // class int ACC_ANNOTATION = 0x2000; // class, inner
public static final int ACC_MANDATED = 0x8000; // method requires int ACC_ENUM = 0x4000; // class, inner, field
int ACC_MODULE = 0x8000; // class
int ACC_MANDATED = 0x8000; // method module requires(module) exports(module)
/* Attribute codes */ /* Attribute codes */
public static final int SYNTHETIC_ATTRIBUTE = 0x00010000; // actually, this is an attribute int SYNTHETIC_ATTRIBUTE = 0x00010000; // actually, this is an attribute
public static final int DEPRECATED_ATTRIBUTE = 0x00020000; // actually, this is an attribute int DEPRECATED_ATTRIBUTE = 0x00020000; // actually, this is an attribute
/* The version of a class file since which the compact format of stack map
* is necessary */ Map<Integer,String> ACC_NAMES = new HashMap() {{
public final int SPLIT_VERIFIER_CFV = 50; put(ACC_PUBLIC ,"public");
put(ACC_PRIVATE ,"private");
put(ACC_PROTECTED ,"protected");
put(ACC_STATIC ,"static");
put(ACC_FINAL ,"final");
put(ACC_SUPER ,"super");
put(ACC_SYNCHRONIZED ,"synchronized");
put(ACC_VOLATILE ,"volatile");
put(ACC_BRIDGE ,"bridge");
put(ACC_TRANSIENT ,"transient");
put(ACC_VARARGS ,"varargs");
put(ACC_NATIVE ,"native");
put(ACC_INTERFACE ,"interface");
put(ACC_ABSTRACT ,"abstract");
put(ACC_STRICT ,"strict");
put(ACC_SYNTHETIC ,"synthetic");
put(ACC_ANNOTATION ,"annotation");
put(ACC_ENUM ,"enum");
put(ACC_MODULE ,"module");
put(ACC_MANDATED ,"mandated");
put(SYNTHETIC_ATTRIBUTE ,"synthetic");
}};
/* The version of a class file since which the compact format of stack map is necessary */
int SPLIT_VERIFIER_CFV = 50;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,10 +23,10 @@
package org.openjdk.asmtools.jasm; package org.openjdk.asmtools.jasm;
import static org.openjdk.asmtools.jasm.JasmTokens.*; import static org.openjdk.asmtools.jasm.JasmTokens.*;
import static org.openjdk.asmtools.jasm.Tables.*;
import static org.openjdk.asmtools.jasm.Constants.EOF; import static org.openjdk.asmtools.jasm.Constants.EOF;
import static org.openjdk.asmtools.jasm.Constants.OFFSETBITS; import static org.openjdk.asmtools.jasm.Constants.OFFSETBITS;
import java.io.IOException; import java.io.IOException;
import java.util.function.Predicate;
/** /**
* A Scanner for Jasm tokens. Errors are reported to the environment object.<p> * A Scanner for Jasm tokens. Errors are reported to the environment object.<p>
@ -47,6 +47,9 @@ public class Scanner extends ParseBase {
* SyntaxError is the generic error thrown for parsing problems. * SyntaxError is the generic error thrown for parsing problems.
*/ */
protected static class SyntaxError extends Error { protected static class SyntaxError extends Error {
boolean fatalError = false;
SyntaxError Fatal() { fatalError = true; return this; }
boolean isFatal() {return fatalError;}
} }
/** /**
@ -62,7 +65,7 @@ public class Scanner extends ParseBase {
/** /**
* Current token * Current token
*/ */
// protected int token; // protected int token;
protected Token token; protected Token token;
/** /**
@ -88,7 +91,8 @@ public class Scanner extends ParseBase {
/* A growable character buffer. */ /* A growable character buffer. */
private int count; private int count;
private char buffer[] = new char[32]; private char buffer[] = new char[32];
//
private Predicate<Integer> escapingAllowed;
/** /**
* The position of the previous token * The position of the previous token
*/ */
@ -103,11 +107,21 @@ public class Scanner extends ParseBase {
*/ */
protected Scanner(Environment env) throws IOException { protected Scanner(Environment env) throws IOException {
super.init(this, null, env); super.init(this, null, env);
escapingAllowed = noFunc;
this.in = env; this.in = env;
ch = env.read(); ch = env.read();
xscan(); xscan();
} }
protected void scanModuleStatement() throws IOException {
try {
escapingAllowed = yesAndProcessFunc;
scan();
} finally {
escapingAllowed = noFunc;
}
}
/** /**
* scan * scan
* *
@ -181,7 +195,7 @@ prefix:
scan(); scan();
} }
private void putc(int ch) { private void putCh(int ch) {
if (count == buffer.length) { if (count == buffer.length) {
char newBuffer[] = new char[buffer.length * 2]; char newBuffer[] = new char[buffer.length * 2];
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length); System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
@ -207,33 +221,33 @@ prefix:
} }
switch (ch >> 8) { switch (ch >> 8) {
case 0x06: case 0x06:
return ((ch >= 0x0660) && (ch <= 0x0669)) || // Arabic-Indic return ((ch >= 0x0660) && (ch <= 0x0669)) || // Arabic-Indic
((ch >= 0x06f0) && (ch <= 0x06f9)); // Eastern Arabic-Indic ((ch >= 0x06f0) && (ch <= 0x06f9)); // Eastern Arabic-Indic
case 0x07: case 0x07:
case 0x08: case 0x08:
default: default:
return false; return false;
case 0x09: case 0x09:
return ((ch >= 0x0966) && (ch <= 0x096f)) || // Devanagari return ((ch >= 0x0966) && (ch <= 0x096f)) || // Devanagari
((ch >= 0x09e6) && (ch <= 0x09ef)); // Bengali ((ch >= 0x09e6) && (ch <= 0x09ef)); // Bengali
case 0x0a: case 0x0a:
return ((ch >= 0x0a66) && (ch <= 0x0a6f)) || // Gurmukhi return ((ch >= 0x0a66) && (ch <= 0x0a6f)) || // Gurmukhi
((ch >= 0x0ae6) && (ch <= 0x0aef)); // Gujarati ((ch >= 0x0ae6) && (ch <= 0x0aef)); // Gujarati
case 0x0b: case 0x0b:
return ((ch >= 0x0b66) && (ch <= 0x0b6f)) || // Oriya return ((ch >= 0x0b66) && (ch <= 0x0b6f)) || // Oriya
((ch >= 0x0be7) && (ch <= 0x0bef)); // Tamil ((ch >= 0x0be7) && (ch <= 0x0bef)); // Tamil
case 0x0c: case 0x0c:
return ((ch >= 0x0c66) && (ch <= 0x0c6f)) || // Telugu return ((ch >= 0x0c66) && (ch <= 0x0c6f)) || // Telugu
((ch >= 0x0ce6) && (ch <= 0x0cef)); // Kannada ((ch >= 0x0ce6) && (ch <= 0x0cef)); // Kannada
case 0x0d: case 0x0d:
return ((ch >= 0x0d66) && (ch <= 0x0d6f)); // Malayalam return ((ch >= 0x0d66) && (ch <= 0x0d6f)); // Malayalam
case 0x0e: case 0x0e:
return ((ch >= 0x0e50) && (ch <= 0x0e59)) || // Thai return ((ch >= 0x0e50) && (ch <= 0x0e59)) || // Thai
((ch >= 0x0ed0) && (ch <= 0x0ed9)); // Lao ((ch >= 0x0ed0) && (ch <= 0x0ed9)); // Lao
case 0x0f: case 0x0f:
return false; return false;
case 0x10: case 0x10:
return ((ch >= 0x1040) && (ch <= 0x1049)); // Tibetan return ((ch >= 0x1040) && (ch <= 0x1049)); // Tibetan
} }
} }
@ -333,14 +347,14 @@ prefix:
env.error(pos, "eof.in.comment"); env.error(pos, "eof.in.comment");
return bufferString(); return bufferString();
case '\n': case '\n':
putc('\n'); putCh('\n');
ch = in.read(); ch = in.read();
seenstar = false; seenstar = false;
c = count; c = count;
break; break;
case ' ': case ' ':
case '\t': case '\t':
putc(ch); putCh(ch);
ch = in.read(); ch = in.read();
break; break;
case '*': case '*':
@ -350,7 +364,7 @@ prefix:
count = c; count = c;
return bufferString(); return bufferString();
} }
putc('*'); putCh('*');
} else { } else {
seenstar = true; seenstar = true;
count = c; count = c;
@ -370,7 +384,7 @@ prefix:
if (!seenstar) { if (!seenstar) {
seenstar = true; seenstar = true;
} }
putc(ch); putCh(ch);
ch = in.read(); ch = in.read();
c = count; c = count;
break; break;
@ -396,7 +410,7 @@ prefix:
boolean overflow = false; boolean overflow = false;
long value = ch - '0'; long value = ch - '0';
count = 0; count = 0;
putc(ch); // save character in buffer putCh(ch); // save character in buffer
numberLoop: numberLoop:
for (;;) { for (;;) {
switch (ch = in.read()) { switch (ch = in.read()) {
@ -410,7 +424,7 @@ numberLoop:
case '7': case '7':
case '8': case '8':
case '9': case '9':
putc(ch); putCh(ch);
if (overflow) { if (overflow) {
break; break;
} }
@ -448,7 +462,7 @@ numberLoop:
radix = (ch == '0' ? 8 : 10); radix = (ch == '0' ? 8 : 10);
long value = ch - '0'; long value = ch - '0';
count = 0; count = 0;
putc(ch); // save character in buffer putCh(ch); // save character in buffer
numberLoop: numberLoop:
for (;;) { for (;;) {
switch (ch = in.read()) { switch (ch = in.read()) {
@ -472,7 +486,7 @@ numberLoop:
case '5': case '5':
case '6': case '6':
case '7': case '7':
putc(ch); putCh(ch);
if (radix == 10) { if (radix == 10) {
overflow = overflow || (value * 10) / 10 != value; overflow = overflow || (value * 10) / 10 != value;
value = (value * 10) + (ch - '0'); value = (value * 10) + (ch - '0');
@ -502,7 +516,7 @@ numberLoop:
case 'B': case 'B':
case 'c': case 'c':
case 'C': case 'C':
putc(ch); putCh(ch);
if (radix != 16) { if (radix != 16) {
break numberLoop; // an illegal character break numberLoop; // an illegal character
} }
@ -566,7 +580,7 @@ numberLoop:
boolean isSingleFloat = false; boolean isSingleFloat = false;
char lastChar; char lastChar;
if (ch == '.') { if (ch == '.') {
putc(ch); putCh(ch);
ch = in.read(); ch = in.read();
} }
@ -583,14 +597,14 @@ numberLoop:
case '7': case '7':
case '8': case '8':
case '9': case '9':
putc(ch); putCh(ch);
break; break;
case 'e': case 'e':
case 'E': case 'E':
if (seenExponent) { if (seenExponent) {
break numberLoop; // we'll get a format error break numberLoop; // we'll get a format error
} }
putc(ch); putCh(ch);
seenExponent = true; seenExponent = true;
break; break;
case '+': case '+':
@ -599,7 +613,7 @@ numberLoop:
if (lastChar != 'e' && lastChar != 'E') { if (lastChar != 'e' && lastChar != 'E') {
break numberLoop; // this isn't an error, though! break numberLoop; // this isn't an error, though!
} }
putc(ch); putCh(ch);
break; break;
case 'f': case 'f':
case 'F': case 'F':
@ -632,12 +646,12 @@ numberLoop:
|| lastChar == '+' || lastChar == '-') { || lastChar == '+' || lastChar == '-') {
env.error(in.pos - 1, "float.format"); env.error(in.pos - 1, "float.format");
} else if (isSingleFloat) { } else if (isSingleFloat) {
floatValue = Float.valueOf(bufferString()).floatValue(); floatValue = Float.valueOf(bufferString());
if (Float.isInfinite(floatValue)) { if (Float.isInfinite(floatValue)) {
env.error(pos, "overflow"); env.error(pos, "overflow");
} }
} else { } else {
doubleValue = Double.valueOf(bufferString()).doubleValue(); doubleValue = Double.valueOf(bufferString());
if (Double.isInfinite(doubleValue)) { if (Double.isInfinite(doubleValue)) {
env.error(pos, "overflow"); env.error(pos, "overflow");
env.error(pos, "overflow"); env.error(pos, "overflow");
@ -753,29 +767,54 @@ numberLoop:
case '\\': { case '\\': {
int c = scanEscapeChar(); int c = scanEscapeChar();
if (c >= 0) { if (c >= 0) {
putc((char) c); putCh((char) c);
} }
break; break;
} }
default: default:
putc(ch); putCh(ch);
ch = in.read(); ch = in.read();
break; break;
} }
} }
} }
/** /**
* Scan an Identifier. The current character should be the first character of the * Scan an Identifier. The current character should be the first character of the
* identifier. * identifier.
*/ */
private void scanIdentifier() throws IOException { private void scanIdentifier(char[] prefix) throws IOException {
int firstChar;
count = 0; count = 0;
int firstChar = ch; if(prefix != null) {
for(;;) {
for (int i = 0; i < prefix.length; i++)
putCh(prefix[i]);
ch = in.read();
if (ch == '\\') {
ch = in.read();
if (ch == 'u') {
ch = in.convertUnicode();
if (!isUCLetter(ch) && !isUCDigit(ch)) {
prefix = new char[]{(char)ch};
continue;
}
} else if (escapingAllowed.test(ch)) {
prefix = new char[]{(char)ch};
continue;
}
int p = in.pos;
env.error(p, "invalid.escape.char");
}
break;
}
}
firstChar = ch;
boolean firstIteration = true; boolean firstIteration = true;
scanloop: scanloop:
while (true) { while (true) {
putc(ch); putCh(ch);
ch = in.read(); ch = in.read();
// Check to see if the annotation marker is at // Check to see if the annotation marker is at
@ -783,7 +822,7 @@ scanloop:
if (firstIteration && firstChar == '@') { if (firstIteration && firstChar == '@') {
// May be a type annotation // May be a type annotation
if (ch == 'T') { // type annotation if (ch == 'T') { // type annotation
putc(ch); putCh(ch);
ch = in.read(); ch = in.read();
} }
@ -791,7 +830,7 @@ scanloop:
if (ch == '+' || ch == '-') { // regular annotation if (ch == '+' || ch == '-') { // regular annotation
// possible annotation - // possible annotation -
// need to eat up the '@+' or '@-' // need to eat up the '@+' or '@-'
putc(ch); putCh(ch);
ch = in.read(); ch = in.read();
} }
idValue = bufferString(); idValue = bufferString();
@ -882,15 +921,17 @@ scanloop:
break; // no, continue to parse identifier break; // no, continue to parse identifier
} }
case '\\': case '\\':
if ((ch = in.read()) == 'u') { ch = in.read();
if ( ch == 'u') {
ch = in.convertUnicode(); ch = in.convertUnicode();
if (isUCLetter(ch) || isUCDigit(ch)) { if (isUCLetter(ch) || isUCDigit(ch)) {
break; break;
} }
} else { } else if( escapingAllowed.test(ch)) {
int p = in.pos; break;
env.error(p, "invalid.escape.char");
} }
int p = in.pos;
env.error(p, "invalid.escape.char");
default: default:
// if ((!isUCDigit(ch)) && (!isUCLetter(ch))) { // if ((!isUCDigit(ch)) && (!isUCLetter(ch))) {
break scanloop; break scanloop;
@ -977,7 +1018,7 @@ loop:
case '8': case '8':
case '9': case '9':
count = 0; count = 0;
putc('.'); putCh('.');
scanReal(); scanReal();
break; break;
default: default:
@ -1073,7 +1114,7 @@ loop:
case ')': case ')':
case '<': case '<':
case '>': case '>':
scanIdentifier(); scanIdentifier(null);
break loop; break loop;
case '\u001a': case '\u001a':
// Our one concession to DOS. // Our one concession to DOS.
@ -1097,13 +1138,24 @@ loop:
scanCPRef(); scanCPRef();
break loop; break loop;
case '\\': case '\\':
if ((ch = in.read()) == 'u') { ch = in.read();
if ( ch == 'u') {
ch = in.convertUnicode(); ch = in.convertUnicode();
if (isUCLetter(ch)) { if (isUCLetter(ch)) {
scanIdentifier(); scanIdentifier(null);
break loop; break loop;
} }
} else if( escapingAllowed.test(ch)) {
scanIdentifier(new char[]{'\\', (char)ch});
break loop;
} }
// if ((ch = in.read()) == 'u') {
// ch = in.convertUnicode();
// if (isUCLetter(ch)) {
// scanIdentifier();
// break loop;
// }
// }
default: default:
env.out.println("funny.char:" + env.lineNumber(pos) + "/" + (pos & ((1 << OFFSETBITS) - 1))); env.out.println("funny.char:" + env.lineNumber(pos) + "/" + (pos & ((1 << OFFSETBITS) - 1)));
env.error(pos, "funny.char"); env.error(pos, "funny.char");
@ -1112,27 +1164,6 @@ loop:
} }
} }
/**
* Scan to a matching '}', ']' or ')'. The current token must be a '{', '[' or '(';
*/
protected void match(Token open, Token close) throws IOException {
int depth = 1;
while (true) {
xscan();
if (token == open) {
depth++;
} else if (token == close) {
if (--depth == 0) {
return;
}
} else if (token == Token.EOF) {
env.error(pos, "unbalanced.paren");
return;
}
}
}
@Override @Override
protected void debugScan(String dbstr) { protected void debugScan(String dbstr) {
if (token == null) { if (token == null) {
@ -1161,4 +1192,11 @@ loop:
} }
} }
private Predicate<Integer> noFunc = (ch)-> false;
private Predicate<Integer> yesAndProcessFunc = (ch) -> {
boolean res = ((ch == '\\') || (ch == ':') || (ch == '@'));
if (res)
putCh('\\');
return res;
};
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,6 +22,7 @@
*/ */
package org.openjdk.asmtools.jasm; package org.openjdk.asmtools.jasm;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.HashMap; import java.util.HashMap;
@ -126,10 +127,12 @@ public class Tables {
// Constant 14 reserved // Constant 14 reserved
CONSTANT_METHODHANDLE (15, "CONSTANT_METHODHANDLE", "MethodHandle"), CONSTANT_METHODHANDLE (15, "CONSTANT_METHODHANDLE", "MethodHandle"),
CONSTANT_METHODTYPE (16, "CONSTANT_METHODTYPE", "MethodType"), CONSTANT_METHODTYPE (16, "CONSTANT_METHODTYPE", "MethodType"),
CONSTANT_INVOKEDYNAMIC_TRANS (17, "CONSTANT_INVOKEDYNAMIC_TRANS", "InvokeDynamicTrans"), // Constant 17 reserved
CONSTANT_INVOKEDYNAMIC (18, "CONSTANT_INVOKEDYNAMIC", "InvokeDynamic"); CONSTANT_INVOKEDYNAMIC (18, "CONSTANT_INVOKEDYNAMIC", "InvokeDynamic"),
CONSTANT_MODULE (19, "CONSTANT_MODULE", "Module"),
CONSTANT_PACKAGE (20, "CONSTANT_PACKAGE", "Package");
static final public int maxTag = 18; static final public int maxTag = 20;
private final int value; private final int value;
private final String parseKey; private final String parseKey;
@ -209,7 +212,13 @@ public class Tables {
ATT_RuntimeVisibleTypeAnnotations (22, "ATT_RuntimeVisibleTypeAnnotations", "RuntimeVisibleTypeAnnotations"), ATT_RuntimeVisibleTypeAnnotations (22, "ATT_RuntimeVisibleTypeAnnotations", "RuntimeVisibleTypeAnnotations"),
ATT_RuntimeInvisibleTypeAnnotations (23, "ATT_RuntimeInvisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations"), ATT_RuntimeInvisibleTypeAnnotations (23, "ATT_RuntimeInvisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations"),
ATT_MethodParameters (24, "ATT_MethodParameters", "MethodParameters"), ATT_MethodParameters (24, "ATT_MethodParameters", "MethodParameters"),
ATT_Module (25, "ATT_Module", "Module"); ATT_Module (25, "ATT_Module", "Module"),
ATT_Version (26, "ATT_Version", "Version"),
ATT_TargetPlatform (27, "ATT_TargetPlatform", "TargetPlatform"),
ATT_MainClass (28, "ATT_MainClass", "MainClass"),
ATT_ModulePackages (29, "ATT_ModulePackages", "ModulePackages"),
ATT_ModuleMainClass (30, "ATT_ModuleMainClass", "ModuleMainClass"),
ATT_ModuleTarget (31, "ATT_ModuleTarget", "ModuleTarget");
private final Integer value; private final Integer value;
private final String printval; private final String printval;
@ -390,21 +399,22 @@ public class Tables {
*/ */
static public enum AnnotElemType { static public enum AnnotElemType {
AE_BYTE ('B', "byte"), AE_BYTE ('B', "byte"),
AE_CHAR ('C', "char"), AE_CHAR ('C', "char"),
AE_SHORT ('S', "short"), AE_SHORT ('S', "short"),
AE_INT ('I', "int"), AE_INT ('I', "int"),
AE_LONG ('J', "long"), AE_LONG ('J', "long"),
AE_FLOAT ('F', "float"), AE_FLOAT ('F', "float"),
AE_DOUBLE ('D', "double"), AE_DOUBLE ('D', "double"),
AE_BOOLEAN ('Z', "boolean"), AE_BOOLEAN ('Z', "boolean"),
AE_STRING ('s', "string"), AE_STRING ('s', "string"),
AE_ENUM ('e', "enum"), AE_ENUM ('e', "enum"),
AE_CLASS ('c', "class"), AE_CLASS ('c', "class"),
AE_ANNOTATION ('@', "annotation"), AE_ANNOTATION ('@', "annotation"),
AE_ARRAY ('[', "array"); AE_ARRAY ('[', "array"),
AE_UNKNOWN ((char)0, "unknown");
private final char value; private char value;
private final String printval; private final String printval;
AnnotElemType(char val, String print) { AnnotElemType(char val, String print) {
@ -431,7 +441,11 @@ public class Tables {
} }
public static AnnotElemType annotElemType(char subtag) { public static AnnotElemType annotElemType(char subtag) {
return AnnotElemTypes.get(subtag); AnnotElemType type = AnnotElemTypes.get(subtag);
if ( type == null ) {
type = AnnotElemType.AE_UNKNOWN;
}
return type;
} }
public static String annotElemTypeName(char subtag) { public static String annotElemTypeName(char subtag) {
@ -459,17 +473,18 @@ public class Tables {
*/ */
static public enum StackMapType { static public enum StackMapType {
/* Type codes for StackMap attribute */ /* Type codes for StackMap attribute */
ITEM_Bogus (0, "bogus", "B"), // an unknown or uninitialized value ITEM_Bogus (0, "bogus", "B"), // an unknown or uninitialized value
ITEM_Integer (1, "int", "I"), // a 32-bit integer ITEM_Integer (1, "int", "I"), // a 32-bit integer
ITEM_Float (2, "float", "F"), // not used ITEM_Float (2, "float", "F"), // not used
ITEM_Double (3, "double", "D"), // not used ITEM_Double (3, "double", "D"), // not used
ITEM_Long (4, "long", "L"), // a 64-bit integer ITEM_Long (4, "long", "L"), // a 64-bit integer
ITEM_Null (5, "null", "N"), // the type of null ITEM_Null (5, "null", "N"), // the type of null
ITEM_InitObject (6, "this", "IO"), // "this" in constructor ITEM_InitObject (6, "this", "IO"), // "this" in constructor
ITEM_Object (7, "CP", "O"), // followed by 2-byte index of class name ITEM_Object (7, "CP", "O"), // followed by 2-byte index of class name
ITEM_NewObject (8, "at", "NO"); // followed by 2-byte ref to "new" ITEM_NewObject (8, "at", "NO"), // followed by 2-byte ref to "new"
ITEM_UNKNOWN (null, "UNKNOWN", "UNKNOWN"); // placeholder for wrong types
private final Integer value; private Integer value;
private final String printval; private final String printval;
private final String parsekey; private final String parsekey;
@ -498,8 +513,15 @@ public class Tables {
StackMapTypes.put(typ.value, typ); StackMapTypes.put(typ.value, typ);
} }
public static StackMapType stackMapType(int subtag) { public static StackMapType stackMapType(int subtag, PrintWriter out) {
return StackMapTypes.get(subtag); StackMapType type = StackMapTypes.get(subtag);
if (type == null || type == StackMapType.ITEM_UNKNOWN) {
if (out != null)
out.println("// Unknown StackMap type " + subtag);
type = StackMapType.ITEM_UNKNOWN;
type.value = subtag;
}
return type;
} }
public static StackMapType stackMapType(String subtag) { public static StackMapType stackMapType(String subtag) {
@ -619,7 +641,8 @@ public class Tables {
CTX_CLASS (0, "class"), CTX_CLASS (0, "class"),
CTX_FIELD (1, "field"), CTX_FIELD (1, "field"),
CTX_METHOD (2, "method"), CTX_METHOD (2, "method"),
CTX_INNERCLASS (3, "inner-class"); CTX_INNERCLASS (3, "inner-class"),
CTX_MODULE (4, "module") ;
private final int value; private final int value;
private final String printval; private final String printval;
@ -640,7 +663,7 @@ public class Tables {
private static void registerAnnotElemType(CF_Context ctx) { private static void registerAnnotElemType(CF_Context ctx) {
// NameToAnnotElemType.put(typ.printval, typ); // NameToAnnotElemType.put(typ.printval, typ);
// AnnotElemTypes.put(typ.value, typ); // AnnotElemTypes.put(typ.value, typ);
} }
/* /*
public static CF_Context annotElemType(String idValue) { public static CF_Context annotElemType(String idValue) {
@ -649,6 +672,5 @@ public class Tables {
public static CF_Context annotElemType(int subtag) { public static CF_Context annotElemType(int subtag) {
return AnnotElemTypes.get(subtag); return AnnotElemTypes.get(subtag);
} }
* */ */
} }

@ -1,4 +1,4 @@
# Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -67,11 +67,10 @@ err.funny.char=Invalid character in input.
err.unbalanced.paren=Unbalanced parentheses. err.unbalanced.paren=Unbalanced parentheses.
# Parser: # Parser:
err.package.repeated=Package statement repeated. err.package.repeated=Package statement repeated.
#err.module.repeated=Module statement repeated.
warn.intf.repeated=Interface {0} repeated. warn.intf.repeated=Interface {0} repeated.
warn.exc.repeated=Exception repeated in throws clause. warn.exc.repeated=Exception repeated in throws clause.
err.multiple.inherit=Multiple inheritance is not supported. err.multiple.inherit=Multiple inheritance is not supported.
err.toplevel.expected=Class or interface declaration expected. err.toplevel.expected=Class, module or interface declaration expected.
err.const.def.expected=Constant declaration expected. err.const.def.expected=Constant declaration expected.
err.const.undecl=Constant #{0} not declared. err.const.undecl=Constant #{0} not declared.
err.const.redecl=Constant {0} redeclared. err.const.redecl=Constant {0} redeclared.
@ -84,6 +83,7 @@ err.identifier.expected=Identifier expected.
#err.missing.term=Missing term. #err.missing.term=Missing term.
#err.tag.expected=Tag expected. #err.tag.expected=Tag expected.
err.name.expected=Name expected, got {0}. err.name.expected=Name expected, got {0}.
err.module.name.expected=Module name expected, got {0}.
err.int.expected=Integer expected. err.int.expected=Integer expected.
err.neg.forbidden=Negative integer is not allowed here. err.neg.forbidden=Negative integer is not allowed here.
err.value.large=Value doesn't fit in {0}. err.value.large=Value doesn't fit in {0}.
@ -126,10 +126,12 @@ warn.invalid.modifier.intmth=interface method must be abstract public only \"{0
warn.invalid.modifier.abst=invalid modifier for abstract method. warn.invalid.modifier.abst=invalid modifier for abstract method.
warn.invalid.modifier.mth=invalid modifier for a method. warn.invalid.modifier.mth=invalid modifier for a method.
warn.invalid.modifier.acc=at most one of public, protected, and private modifiers can be used. warn.invalid.modifier.acc=at most one of public, protected, and private modifiers can be used.
warn.invalid.modifier.int=invalid modifier for an interface. warn.invalid.modifier.int=invalid modifier(s) for an interface{0}
warn.invalid.modifier.int.abs=interface class must have abstract modifier. warn.invalid.modifier.int.abs=interface class must have abstract modifier.
warn.invalid.modifier.class=invalid modifier for a class. warn.invalid.modifier.class=invalid modifier(s) for a class{0}
warn.missing.modifier.class=class or enum declaration missing.
warn.invalid.modifier.class.finabs=class cannot be both abstract and final. warn.invalid.modifier.class.finabs=class cannot be both abstract and final.
warn.invalid.modifier.class.intenum=cannot be both interface and enum.
warn.invalid.modifier.innerclass=invalid modifier for an inner class \"{0}\". warn.invalid.modifier.innerclass=invalid modifier for an inner class \"{0}\".
err.itemtype.expected=StackMap item type expected instead of {0}. err.itemtype.expected=StackMap item type expected instead of {0}.
err.localsmap.repeated=locals_map redeclared. err.localsmap.repeated=locals_map redeclared.
@ -159,7 +161,7 @@ err.paramname.token.unexpected=Incorrect ParamName, unrecognized token: \"{0}\".
# #
err.incorrect.annot.class=Incorrect Annotation (class), expected class name or CPX), got \"{0}\". err.incorrect.annot.class=Incorrect Annotation (class), expected class name or CPX), got \"{0}\".
err.incorrect.annot.enum=Incorrect Annotation (enum), expected type field IDENT, \"{0}\". err.incorrect.annot.enum=Incorrect Annotation (enum), expected type field IDENT, \"{0}\".
err.incorrect.annot.enum.cpx==Incorrect Annotation (enum), expexted type field CPX. err.incorrect.annot.enum.cpx==Incorrect Annotation (enum), expected type field CPX.
err.incorrect.annot.token=Incorrect Annotation, unrecognized token: \"{0}\". err.incorrect.annot.token=Incorrect Annotation, unrecognized token: \"{0}\".
err.incorrect.annot.bool=Incorrect Annotation (boolean), expected Integer), got \"{0}\". err.incorrect.annot.bool=Incorrect Annotation (boolean), expected Integer), got \"{0}\".
err.incorrect.annot.byte=Incorrect Annotation (byte), expected Integer), got \"{0}\". err.incorrect.annot.byte=Incorrect Annotation (byte), expected Integer), got \"{0}\".
@ -173,12 +175,9 @@ err.incorrect.typeannot.pathentry=Incorrect TypeAnnotation TargetPath PathEntry
err.incorrect.typeannot.pathentry.argindex=Incorrect TypeAnnotation TargetPath PathEntry ArgIndex (expected Integer), \"{0}\". err.incorrect.typeannot.pathentry.argindex=Incorrect TypeAnnotation TargetPath PathEntry ArgIndex (expected Integer), \"{0}\".
# #
# module Errors # module Errors
err.requires.expected=Module statement \"requires [public] ModuleName;\" expected. err.module.statement.expected= Module statement expected.
err.exports.expected=Module statement \"exports PackageName [to ModuleName (, ModuleName)];\" expected. err.requires.expected=Module statement \"requires [transitive] [static] ModuleName;\" expected.
err.uses.expected=Module statement \"uses TypeName ;\" expected. warn.dot.will.be.converted=Forward slash \"/\" expected instead of dot \".\". The dot is replaced by \"/\".
err.provides.expected=Module statement \"provides TypeName with TypeName ;\" expected.
err.module.statement.expected=One of a module statements - \"requires ...\", \"exports ...\", \"uses ...\" or \"provides ... with ...\" expected.
# #
# Compiler Errors # Compiler Errors
# #

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -250,7 +250,7 @@ public class Main {
out_println("class #" + in.readUnsignedShort() + "; // #" + i); out_println("class #" + in.readUnsignedShort() + "; // #" + i);
break; break;
case CONSTANT_PACKAGE: case CONSTANT_JAVACARD_PACKAGE:
out_begin("package { // #" + i); out_begin("package { // #" + i);
out_println(toHex(in.readUnsignedByte(), 1) + "; // flags"); out_println(toHex(in.readUnsignedByte(), 1) + "; // flags");
out_println("#" + in.readUnsignedShort() + "; // name"); out_println("#" + in.readUnsignedShort() + "; // name");

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -292,7 +292,6 @@ public class JcodTokens {
CONSTANT_FLOAT (4, "CONSTANT_FLOAT", "float"), CONSTANT_FLOAT (4, "CONSTANT_FLOAT", "float"),
CONSTANT_LONG (5, "CONSTANT_LONG", "long"), CONSTANT_LONG (5, "CONSTANT_LONG", "long"),
CONSTANT_DOUBLE (6, "CONSTANT_DOUBLE", "double"), CONSTANT_DOUBLE (6, "CONSTANT_DOUBLE", "double"),
// Class is removed for JavaCard (???) // Class is removed for JavaCard (???)
CONSTANT_CLASS (7, "CONSTANT_CLASS", "class"), CONSTANT_CLASS (7, "CONSTANT_CLASS", "class"),
CONSTANT_STRING (8, "CONSTANT_STRING", "String"), CONSTANT_STRING (8, "CONSTANT_STRING", "String"),
@ -300,16 +299,17 @@ public class JcodTokens {
CONSTANT_METHOD (10, "CONSTANT_METHOD", "Method"), CONSTANT_METHOD (10, "CONSTANT_METHOD", "Method"),
CONSTANT_INTERFACEMETHOD (11, "CONSTANT_INTERFACEMETHOD", "InterfaceMethod"), CONSTANT_INTERFACEMETHOD (11, "CONSTANT_INTERFACEMETHOD", "InterfaceMethod"),
CONSTANT_NAMEANDTYPE (12, "CONSTANT_NAMEANDTYPE", "NameAndType"), CONSTANT_NAMEANDTYPE (12, "CONSTANT_NAMEANDTYPE", "NameAndType"),
// added for JavaCard // added for JavaCard
CONSTANT_PACKAGE (13, "CONSTANT_PACKAGE", "package"), // in javacard export file CONSTANT_JAVACARD_PACKAGE (13, "CONSTANT_PACKAGE", "package"), // in javacard export file
// Constant 14 reserved // Constant 14 reserved
CONSTANT_METHODHANDLE (15, "CONSTANT_METHODHANDLE", "MethodHandle"), CONSTANT_METHODHANDLE (15, "CONSTANT_METHODHANDLE", "MethodHandle"),
CONSTANT_METHODTYPE (16, "CONSTANT_METHODTYPE", "MethodType"), CONSTANT_METHODTYPE (16, "CONSTANT_METHODTYPE", "MethodType"),
CONSTANT_INVOKEDYNAMIC_TRANS (17, "CONSTANT_INVOKEDYNAMIC_TRANS", "InvokeDynamicTrans"), // Constant 17 reserved
CONSTANT_INVOKEDYNAMIC (18, "CONSTANT_INVOKEDYNAMIC", "InvokeDynamic"); CONSTANT_INVOKEDYNAMIC (18, "CONSTANT_INVOKEDYNAMIC", "InvokeDynamic"),
CONSTANT_MODULE (19, "CONSTANT_MODULE", "Module"),
CONSTANT_MODULE_PACKAGE (20, "CONSTANT_PACKAGE", "Package");
public static final int maxTag = 18; public static final int maxTag = 20;
private final int value; private final int value;
private final String parseKey; private final String parseKey;
@ -368,7 +368,7 @@ public class JcodTokens {
ConstantTypes.put(tt.value, tt); ConstantTypes.put(tt.value, tt);
} }
static int constValue(String stringValue) { public static int constValue(String stringValue) {
ConstType Val = constType(stringValue); ConstType Val = constType(stringValue);
int val = -1; int val = -1;

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,15 +22,14 @@
*/ */
package org.openjdk.asmtools.jcoder; package org.openjdk.asmtools.jcoder;
import static org.openjdk.asmtools.jcoder.JcodTokens.*; import java.io.*;
import java.io.BufferedOutputStream; import java.util.ArrayList;
import java.io.DataOutputStream; import java.util.Arrays;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Stack; import java.util.Stack;
import java.util.ArrayList;
import static org.openjdk.asmtools.jcoder.JcodTokens.ConstType;
import static org.openjdk.asmtools.jcoder.JcodTokens.Token;
/** /**
* Compiles just 1 source file * Compiles just 1 source file
@ -39,13 +38,12 @@ class Jcoder {
/*-------------------------------------------------------- */ /*-------------------------------------------------------- */
/* Jcoder Fields */ /* Jcoder Fields */
ArrayList<ByteBuffer> Classes = new ArrayList<>(); private ArrayList<ByteBuffer> Classes = new ArrayList<>();
ByteBuffer buf; private ByteBuffer buf;
DataOutputStream bufstream; private DataOutputStream bufstream;
String pkg = null, pkgPrefix = ""; private int depth = 0;
int depth = 0; private String tabStr = "";
String tabStr = ""; private Context context = null;
Context context = null;
protected SourceFile env; protected SourceFile env;
protected Scanner scanner; protected Scanner scanner;
@ -55,46 +53,44 @@ class Jcoder {
/*-------------------------------------------------------- */ /*-------------------------------------------------------- */
/* ContextTag (marker) - describes the type of token */ /* ContextTag (marker) - describes the type of token */
/* this is rather cosmetic, no function currently. */ /* this is rather cosmetic, no function currently. */
static public enum ContextTag { private enum ContextTag {
NULL (0, ""), NULL ( ""),
CLASS (1, "Class"), CLASS ( "Class"),
CONSTANTPOOL (2, "Constant-Pool"), CONSTANTPOOL ( "Constant-Pool"),
INTERFACES (3, "Interfaces"), INTERFACES ( "Interfaces"),
INTERFACE (4, "Interface"), INTERFACE ( "Interface"),
METHODS (5, "Methods"), METHODS ( "Methods"),
METHOD (6, "Method"), METHOD ( "Method"),
FIELDS (7, "Fields"), FIELDS ( "Fields"),
FIELD (8, "Field"), FIELD ( "Field"),
ATTRIBUTE (9, "Attribute"); ATTRIBUTE ( "Attribute");
private final Integer value; private final String printValue;
private final String printval;
ContextTag(Integer val, String print) { ContextTag(String value) {
value = val; printValue = value;
printval = print;
} }
public String printval() { public String printval() {
return printval; return printValue;
} }
} }
/*-------------------------------------------------------- */ /*-------------------------------------------------------- */
/* ContextVal (marker) - Specific value on a context stack */ /* ContextVal (marker) - Specific value on a context stack */
public class ContextVal { private class ContextVal {
public ContextTag tag; public ContextTag tag;
public int compCount; int compCount;
public ContextVal owner; ContextVal owner;
public ContextVal(ContextTag tg) { ContextVal(ContextTag tg) {
tag = tg; tag = tg;
compCount = 0; compCount = 0;
owner = null; owner = null;
} }
public ContextVal(ContextTag tg, ContextVal ownr) { ContextVal(ContextTag tg, ContextVal ownr) {
tag = tg; tag = tg;
compCount = 0; compCount = 0;
owner = ownr; owner = ownr;
@ -118,11 +114,8 @@ class Jcoder {
init(); init();
} }
public boolean isConstantPool() { boolean isConstantPool() {
if (stack.empty()) { return !stack.empty() && (stack.peek().tag == ContextTag.CONSTANTPOOL);
return false;
}
return (stack.peek().tag == ContextTag.CONSTANTPOOL);
} }
public void init() { public void init() {
@ -133,7 +126,7 @@ class Jcoder {
hasFields = false; hasFields = false;
} }
public void update() { void update() {
if (stack.empty()) { if (stack.empty()) {
stack.push(new ContextVal(ContextTag.CLASS)); stack.push(new ContextVal(ContextTag.CLASS));
return; return;
@ -164,8 +157,6 @@ class Jcoder {
currentCtx.compCount += 1; currentCtx.compCount += 1;
stack.push(new ContextVal(ContextTag.INTERFACE, currentCtx)); stack.push(new ContextVal(ContextTag.INTERFACE, currentCtx));
break; break;
// case INTERFACE:
// break;
case FIELDS: case FIELDS:
currentCtx.compCount += 1; currentCtx.compCount += 1;
stack.push(new ContextVal(ContextTag.FIELD, currentCtx)); stack.push(new ContextVal(ContextTag.FIELD, currentCtx));
@ -185,7 +176,7 @@ class Jcoder {
} }
} }
public void exit() { void exit() {
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
stack.pop(); stack.pop();
} }
@ -217,7 +208,7 @@ class Jcoder {
/** /**
* Create a parser * Create a parser
*/ */
protected Jcoder(SourceFile sf, HashMap<String, String> macros) throws IOException { Jcoder(SourceFile sf, HashMap<String, String> macros) throws IOException {
scanner = new Scanner(sf, macros); scanner = new Scanner(sf, macros);
env = sf; env = sf;
context = new Context(); context = new Context();
@ -228,16 +219,14 @@ class Jcoder {
/** /**
* Expect a token, return its value, scan the next token or throw an exception. * Expect a token, return its value, scan the next token or throw an exception.
*/ */
protected final void expect(Token t) throws SyntaxError, IOException { private void expect(Token t) throws SyntaxError, IOException {
if (scanner.token != t) { if (scanner.token != t) {
env.traceln("expect:" + t + " instead of " + scanner.token); env.traceln("expect:" + t + " instead of " + scanner.token);
switch (t) { switch (t) {
case IDENT: case IDENT:
// env.error(prevPos, "identifier.expected");
env.error(scanner.pos, "identifier.expected"); env.error(scanner.pos, "identifier.expected");
break; break;
default: default:
// env.error(prevPos, "token.expected", keywordName(t)]);
env.error(scanner.pos, "token.expected", t.toString()); env.error(scanner.pos, "token.expected", t.toString());
break; break;
} }
@ -246,7 +235,7 @@ class Jcoder {
scanner.scan(); scanner.scan();
} }
protected void recoverField() throws SyntaxError, IOException { private void recoverField() throws SyntaxError, IOException {
while (true) { while (true) {
switch (scanner.token) { switch (scanner.token) {
case LBRACE: case LBRACE:
@ -269,7 +258,6 @@ class Jcoder {
case INTERFACE: case INTERFACE:
case CLASS: case CLASS:
// begin of something outside a class, panic more // begin of something outside a class, panic more
// endClass(pos);
throw new SyntaxError(); throw new SyntaxError();
default: default:
@ -283,7 +271,7 @@ class Jcoder {
/** /**
* Parse an array of struct. * Parse an array of struct.
*/ */
protected void parseArray() throws IOException { private void parseArray() throws IOException {
scanner.scan(); scanner.scan();
int length0 = buf.length, pos0 = scanner.pos; int length0 = buf.length, pos0 = scanner.pos;
int num_expected; int num_expected;
@ -316,6 +304,7 @@ class Jcoder {
if (numSize > 0) { if (numSize > 0) {
buf.append(num_expected, numSize); buf.append(num_expected, numSize);
} }
int num_present = parseStruct(); int num_present = parseStruct();
if (num_expected == -1) { if (num_expected == -1) {
env.trace(" buf.writeAt(" + length0 + ", " + num_present + ", " + numSize + "); "); env.trace(" buf.writeAt(" + length0 + ", " + num_present + ", " + numSize + "); ");
@ -323,15 +312,16 @@ class Jcoder {
if (numSize > 0) { if (numSize > 0) {
buf.writeAt(length0, num_present, numSize); buf.writeAt(length0, num_present, numSize);
} }
} else if (num_expected != num_present) { } else if ( num_expected != num_present) {
env.error(pos0, "warn.array.wronglength", new Integer(num_expected), new Integer(num_present)); if (context.isConstantPool() && num_expected == num_present +1) return;
env.error(pos0, "warn.array.wronglength", num_expected, num_present);
} }
} }
/** /**
* Parse a byte array. * Parse a byte array.
*/ */
protected void parseByteArray() throws IOException { private void parseByteArray() throws IOException {
scanner.scan(); scanner.scan();
expect(Token.LSQBRACKET); expect(Token.LSQBRACKET);
int length0 = buf.length, pos0 = scanner.pos; int length0 = buf.length, pos0 = scanner.pos;
@ -375,14 +365,14 @@ class Jcoder {
buf.writeAt(length0, len_present, lenSize); buf.writeAt(length0, len_present, lenSize);
} }
} else if (len_expected != len_present) { } else if (len_expected != len_present) {
env.error(pos0, "warn.array.wronglength", new Integer(len_expected), new Integer(len_present)); env.error(pos0, "warn.array.wronglength", len_expected, len_present);
} }
} }
/** /**
* Parse an Attribute. * Parse an Attribute.
*/ */
protected void parseAttr() throws IOException { private void parseAttr() throws IOException {
scanner.scan(); scanner.scan();
expect(Token.LPAREN); expect(Token.LPAREN);
int cpx; // index int const. pool int cpx; // index int const. pool
@ -418,14 +408,14 @@ class Jcoder {
if (len_expected == -1) { if (len_expected == -1) {
buf.writeAt(length0, len_present, 4); buf.writeAt(length0, len_present, 4);
} else if (len_expected != len_present) { } else if (len_expected != len_present) {
env.error(pos0, "warn.attr.wronglength", new Integer(len_expected), new Integer(len_present)); env.error(pos0, "warn.attr.wronglength", len_expected, len_present);
} }
} // end parseAttr } // end parseAttr
/** /**
* Parse a Component of JavaCard .cap file. * Parse a Component of JavaCard .cap file.
*/ */
protected void parseComp() throws IOException { private void parseComp() throws IOException {
scanner.scan(); scanner.scan();
expect(Token.LPAREN); expect(Token.LPAREN);
int tag = scanner.intValue; // index int const. pool int tag = scanner.intValue; // index int const. pool
@ -447,7 +437,7 @@ class Jcoder {
if (len_expected == -1) { if (len_expected == -1) {
buf.writeAt(length0, len_present, 2); buf.writeAt(length0, len_present, 2);
} else if (len_expected != len_present) { } else if (len_expected != len_present) {
env.error(pos0, "warn.attr.wronglength", new Integer(len_expected), new Integer(len_present)); env.error(pos0, "warn.attr.wronglength", len_expected, len_present);
} }
} // end parseComp } // end parseComp
@ -472,10 +462,10 @@ class Jcoder {
/** /**
* Parse a structure. * Parse a structure.
*/ */
protected int parseStruct() throws IOException { private int parseStruct() throws IOException {
adjustDepth(true); adjustDepth(true);
env.traceln(" "); env.traceln(" ");
env.traceln(tabStr + "Struct { <" + context + "> "); env.traceln(tabStr + "MapStruct { <" + context + "> ");
expect(Token.LBRACE); expect(Token.LBRACE);
int num = 0; int num = 0;
int addElem = 0; int addElem = 0;
@ -510,7 +500,7 @@ class Jcoder {
break; break;
case LONGSTRINGVAL: case LONGSTRINGVAL:
scanner.scan(); scanner.scan();
env.traceln("LongString [\"" + scanner.longStringValue.data + "\"] "); env.traceln("LongString [\"" + Arrays.toString(scanner.longStringValue.data) + "\"] ");
buf.write(scanner.longStringValue.data, 0, scanner.longStringValue.length); buf.write(scanner.longStringValue.data, 0, scanner.longStringValue.length);
addElem = 1; addElem = 1;
break; break;
@ -540,7 +530,7 @@ class Jcoder {
case RBRACE: case RBRACE:
scanner.scan(); scanner.scan();
env.traceln(" "); env.traceln(" ");
env.traceln(tabStr + "} // Struct <" + context + "> ["); env.traceln(tabStr + "} // MapStruct <" + context + "> [");
adjustDepth(false); adjustDepth(false);
return num + addElem; return num + addElem;
default: default:
@ -559,7 +549,7 @@ class Jcoder {
* Recover after a syntax error in the file. This involves discarding tokens until an * Recover after a syntax error in the file. This involves discarding tokens until an
* EOF or a possible legal continuation is encountered. * EOF or a possible legal continuation is encountered.
*/ */
protected void recoverFile() throws IOException { private void recoverFile() throws IOException {
while (true) { while (true) {
switch (scanner.token) { switch (scanner.token) {
case CLASS: case CLASS:
@ -593,20 +583,30 @@ class Jcoder {
} }
} }
/**
* Parse module declaration
*/
private void parseModule() throws IOException {
// skip module name as a redundant element
scanner.skipTill(Scanner.LBRACE);
buf = new ByteBuffer();
bufstream = new DataOutputStream(buf);
buf.myname = "module-info.class";
scanner.scan();
env.traceln("starting " + buf.myname);
// Parse the clause
parseClause();
env.traceln("ending " + buf.myname);
}
/** /**
* Parse a class or interface declaration. * Parse a class or interface declaration.
*/ */
protected void parseClass() throws IOException { private void parseClass(Token prev) throws IOException {
// Begin a new class
Token prev = scanner.token;
scanner.scan(); scanner.scan();
buf = new ByteBuffer(); buf = new ByteBuffer();
bufstream = new DataOutputStream(buf); bufstream = new DataOutputStream(buf);
String doc = scanner.docComment;
// Parse the class name // Parse the class name
int p = scanner.pos;
switch (scanner.token) { switch (scanner.token) {
case STRINGVAL: case STRINGVAL:
buf.myname = scanner.stringValue; buf.myname = scanner.stringValue;
@ -621,8 +621,6 @@ class Jcoder {
case IDENT: case IDENT:
if (prev == Token.FILE) { if (prev == Token.FILE) {
buf.myname = scanner.stringValue; buf.myname = scanner.stringValue;
} else if( prev == Token.MODULE) {
buf.myname = "module-info.class";
} else { } else {
buf.myname = scanner.stringValue + ".class"; buf.myname = scanner.stringValue + ".class";
} }
@ -632,12 +630,17 @@ class Jcoder {
throw new SyntaxError(); throw new SyntaxError();
} }
scanner.scan(); scanner.scan();
env.traceln("starting class " + buf.myname); env.traceln("starting class " + buf.myname);
// Parse the clause // Parse the clause
parseClause();
env.traceln("ending class " + buf.myname);
} // end parseClass
private void parseClause() throws IOException {
switch (scanner.token) { switch (scanner.token) {
case LBRACE: case LBRACE:
parseStruct(); // ?? parseStruct();
break; break;
case LSQBRACKET: case LSQBRACKET:
parseArray(); parseArray();
@ -654,18 +657,12 @@ class Jcoder {
default: default:
env.error(scanner.pos, "struct.expected"); env.error(scanner.pos, "struct.expected");
} }
}
env.traceln("ending class " + buf.myname);
// End the class
env.flushErrors();
Classes.add(buf);
} // end parseClass
/** /**
* Parse an Jcoder file. * Parse an Jcoder file.
*/ */
public ArrayList<ByteBuffer> parseFile() { ArrayList<ByteBuffer> parseFile() {
env.traceln("PARSER"); env.traceln("PARSER");
context.init(); context.init();
try { try {
@ -676,11 +673,16 @@ class Jcoder {
case MODULE: case MODULE:
case INTERFACE: case INTERFACE:
case FILE: case FILE:
// Start of a class Token t = scanner.token;
// scan(); if ( t == Token.MODULE) {
parseClass(); parseModule();
} else {
parseClass(t);
}
// End of the class,interface or module
env.flushErrors();
Classes.add(buf);
break; break;
case SEMICOLON: case SEMICOLON:
// Bogus semi colon // Bogus semi colon
scanner.scan(); scanner.scan();
@ -696,8 +698,11 @@ class Jcoder {
throw new SyntaxError(); throw new SyntaxError();
} }
} catch (SyntaxError e) { } catch (SyntaxError e) {
env.traceln("SyntaxError " + e.getMessage()); String msg = e.getMessage();
e.printStackTrace(); env.traceln("SyntaxError " + (msg == null ? "" : msg));
if( env.debugInfoFlag ) {
e.printStackTrace();
}
recoverFile(); recoverFile();
} }
} }
@ -709,7 +714,7 @@ class Jcoder {
} //end parseFile } //end parseFile
/*---------------------------------------------*/ /*---------------------------------------------*/
static char fileSeparator; //=System.getProperty("file.separator"); private static char fileSeparator; //=System.getProperty("file.separator");
/** /**
* write to the directory passed with -d option * write to the directory passed with -d option
@ -721,7 +726,7 @@ class Jcoder {
return; return;
} }
env.traceln("writing class " + myname); env.traceln("writing " + myname);
File outfile; File outfile;
if (destdir == null) { if (destdir == null) {
int startofname = myname.lastIndexOf('/'); int startofname = myname.lastIndexOf('/');
@ -749,8 +754,7 @@ class Jcoder {
out.write(cls.data, 0, cls.length); out.write(cls.data, 0, cls.length);
try { try {
out.close(); out.close();
} catch (IOException e) { } catch (IOException ignored) { }
}
} }
/** /**

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -75,10 +75,9 @@ public class Main {
public void usage() { public void usage() {
out.println(i18n.getString("jcoder.usage")); out.println(i18n.getString("jcoder.usage"));
out.println(i18n.getString("jcoder.opt.nowrite")); out.println(i18n.getString("jcoder.opt.nowrite"));
out.println(i18n.getString("jcoder.opt.ignore"));
out.println(i18n.getString("jcoder.opt.d")); out.println(i18n.getString("jcoder.opt.d"));
out.println(i18n.getString("jcoder.opt.version")); out.println(i18n.getString("jcoder.opt.version"));
// out.println(" -D<macroDef>=<string> macro declaration");
} }
/** /**
@ -91,7 +90,7 @@ public class Main {
long tm = System.currentTimeMillis(); long tm = System.currentTimeMillis();
ArrayList<String> v = new ArrayList<>(); ArrayList<String> v = new ArrayList<>();
boolean nowrite = false; boolean nowrite = false;
String props = null; boolean ignore = false;
int nwarnings = 0; int nwarnings = 0;
HashMap<String, String> macros = new HashMap<>(); HashMap<String, String> macros = new HashMap<>();
macros.put("VERSION", "3;45"); macros.put("VERSION", "3;45");
@ -130,10 +129,15 @@ public class Main {
macro = arg.substring(index, argLength); macro = arg.substring(index, argLength);
} }
macros.put(macroId, macro); macros.put(macroId, macro);
} else if (arg.equals("-vv")) {
debugInfoFlag = true;
traceFlag = true;
} else if (arg.equals("-v")) { } else if (arg.equals("-v")) {
traceFlag = true; traceFlag = true;
} else if (arg.equals("-nowrite")) { } else if (arg.equals("-nowrite")) {
nowrite = true; nowrite = true;
} else if (arg.equals("-ignore")) {
ignore = true;
} else if (arg.equals("-d")) { } else if (arg.equals("-d")) {
if ((i + 1) == argv.length) { if ((i + 1) == argv.length) {
error(i18n.getString("jcoder.error.d_requires_argument")); error(i18n.getString("jcoder.error.d_requires_argument"));
@ -176,7 +180,7 @@ public class Main {
} }
nerrors += env.nerrors; nerrors += env.nerrors;
nwarnings += env.nwarnings; nwarnings += env.nwarnings;
if (nowrite || (nerrors > 0)) { if (nowrite || (nerrors > 0 & !ignore)) {
continue; continue;
} }
try { try {

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -48,6 +48,7 @@ public class Scanner {
* End of input * End of input
*/ */
public static final int EOF = -1; public static final int EOF = -1;
public static final int LBRACE = 123; // "{"
private boolean debugCP = false; private boolean debugCP = false;
private int numCPentrs = 0; private int numCPentrs = 0;
@ -471,7 +472,12 @@ numberLoop:
} }
return n; return n;
} }
case '@':
readCh();
return '@';
case ':':
readCh();
return ':';
case 'r': case 'r':
readCh(); readCh();
return '\r'; return '\r';
@ -530,7 +536,11 @@ loop:
case '\\': { case '\\': {
int c = scanEscapeChar(); int c = scanEscapeChar();
if (c >= 0) { if (c >= 0) {
putc((char) c); char ch = (char)c;
if ( ch == '@' || ch == ':' || ch == '\\') {
putc('\\');
}
putc(ch);
} }
break; break;
} }
@ -639,6 +649,19 @@ loop:
} }
} // end scanIdentifier } // end scanIdentifier
// skip till symbol
protected void skipTill(int sym) throws IOException {
while (true) {
if( ch == EOF ) {
env.error(pos, "eof.in.comment");
return;
} else if (ch == sym) {
return;
}
readCh();
}
}
protected int xscan() throws IOException { protected int xscan() throws IOException {
int retPos = pos; int retPos = pos;
prevPos = in.pos; prevPos = in.pos;

@ -1,4 +1,4 @@
# Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -25,10 +25,12 @@ where possible options include:
jcoder.opt.nowrite=\ jcoder.opt.nowrite=\
\ -nowrite do not write resulting .class files \ -nowrite do not write resulting .class files
jcoder.opt.ignore=\
-ignore ingore non-fatal error(s) that suppress writing .class files
jcoder.opt.d=\ jcoder.opt.d=\
\ -d destdir directory to place resulting .class files \ -d destdir directory to place resulting .class files
jcoder.opt.version=\ jcoder.opt.version=\
\ -version prints the program version \ -version prints the program version
jcoder.error.D_needs_marco=-D needs macro declaration jcoder.error.D_needs_marco=-D needs macro declaration
jcoder.error.no_closing_quota=no closing quota in macro definition jcoder.error.no_closing_quota=no closing quota in macro definition
@ -55,8 +57,8 @@ err.identifier.expected=Identifier expected.
err.name.expected=Name expected. err.name.expected=Name expected.
err.io.exception=I/O error in {0}. err.io.exception=I/O error in {0}.
err.cannot.write=Cannot write to {0}. err.cannot.write=Cannot write to {0}.
warn.array.wronglength=expected array length {0} do not match real length {1}; expected length written warn.array.wronglength=expected array length %s do not match real length %s; expected length written
warn.attr.wronglength=expected attribute length {0} do not match real length {1}; expected length written warn.attr.wronglength=expected attribute length %s do not match real length %s; expected length written
#attrname.notfound=Cannot find "{0}" in constant pool #attrname.notfound=Cannot find "{0}" in constant pool
err.attrname.expected=Attribute's name or index expected. err.attrname.expected=Attribute's name or index expected.
err.element.expected=Primary data item expected. err.element.expected=Primary data item expected.

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -78,7 +78,6 @@ public class Main {
* Run the decoder * Run the decoder
*/ */
public synchronized boolean decode(String argv[]) { public synchronized boolean decode(String argv[]) {
// int flags = F_WARNINGS;
long tm = System.currentTimeMillis(); long tm = System.currentTimeMillis();
ArrayList<String> vargs = new ArrayList<>(); ArrayList<String> vargs = new ArrayList<>();
ArrayList<String> vj = new ArrayList<>(); ArrayList<String> vj = new ArrayList<>();
@ -88,10 +87,10 @@ public class Main {
// Parse arguments // Parse arguments
int i = 0; int i = 0;
for (String arg : argv) { for (String arg : argv) {
//
if (arg.equals("-g")) { if (arg.equals("-g")) {
printFlags = printFlags | 1; printFlags = printFlags | 1;
vargs.add(arg); vargs.add(arg);
//out.println("arg["+i+"]="+argv[i]+"/printFlags");
} else if (arg.equals("-v")) { } else if (arg.equals("-v")) {
DebugFlag = true; DebugFlag = true;
vargs.add(arg); vargs.add(arg);
@ -99,7 +98,6 @@ public class Main {
} else if (arg.equals("-version")) { } else if (arg.equals("-version")) {
out.println(ProductInfo.FULL_VERSION); out.println(ProductInfo.FULL_VERSION);
} else if (arg.startsWith("-")) { } else if (arg.startsWith("-")) {
//out.println("arg["+i+"]="+argv[i]+"/invalid flag");
error(i18n.getString("jdec.error.invalid_flag", arg)); error(i18n.getString("jdec.error.invalid_flag", arg));
usage(); usage();
return false; return false;
@ -117,24 +115,23 @@ public class Main {
String[] names = new String[0]; String[] names = new String[0];
names = vj.toArray(names); names = vj.toArray(names);
decode: for (String inpname : names) {
for (String inpname : names) { try {
try { ClassData cc = new ClassData(inpname, printFlags, out);
ClassData cc = new ClassData(inpname, printFlags, out); cc.DebugFlag = DebugFlag;
cc.DebugFlag = DebugFlag; cc.decodeClass();
cc.decodeClass(); continue;
continue decode; } catch (FileNotFoundException ee) {
} catch (FileNotFoundException ee) { error(i18n.getString("jdec.error.cannot_read", inpname));
error(i18n.getString("jdec.error.cannot_read", inpname)); } catch (Error ee) {
} catch (Error ee) { ee.printStackTrace();
ee.printStackTrace(); error(i18n.getString("jdec.error.fatal_error"));
error(i18n.getString("jdec.error.fatal_error")); } catch (Exception ee) {
} catch (Exception ee) { ee.printStackTrace();
ee.printStackTrace(); error(i18n.getString("jdec.error.fatal_exception"));
error(i18n.getString("jdec.error.fatal_exception"));
}
return false;
} }
return false;
}
return true; return true;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,10 +23,12 @@
package org.openjdk.asmtools.jdis; package org.openjdk.asmtools.jdis;
import org.openjdk.asmtools.asmutils.HexUtils; import org.openjdk.asmtools.asmutils.HexUtils;
import org.openjdk.asmtools.jasm.JasmTokens;
import org.openjdk.asmtools.jasm.Modifiers; import org.openjdk.asmtools.jasm.Modifiers;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import static org.openjdk.asmtools.jasm.RuntimeConstants.*; import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
import static org.openjdk.asmtools.jasm.Tables.*; import static org.openjdk.asmtools.jasm.Tables.*;
@ -37,15 +39,14 @@ import static org.openjdk.asmtools.jasm.Tables.*;
public class ClassData extends MemberData { public class ClassData extends MemberData {
/*-------------------------------------------------------- */ /*-------------------------------------------------------- */
/* ClassData Fields */ /* ClassData Fields */
// ----------------------------- // -----------------------------
// Header Info // Header Info
// ----------------------------- // -----------------------------
/** /**
* Version info * Version info
*/ */
protected int minor_version, protected int minor_version, major_version;
major_version;
/** /**
* Constant Pool index to this class * Constant Pool index to this class
@ -251,9 +252,6 @@ public class ClassData extends MemberData {
} }
minor_version = in.readShort(); minor_version = in.readShort();
major_version = in.readShort(); major_version = in.readShort();
// if (major_version != JAVA_VERSION) {
// throw new ClassFormatError("wrong version: " + major_version + ", expected " + JAVA_VERSION);
// }
// Read the constant pool // Read the constant pool
// ----------------------------------------------- // -----------------------------------------------
@ -304,93 +302,58 @@ public class ClassData extends MemberData {
return line; return line;
} }
private <T extends AnnotationData> void printAnnotations(List<T> annotations) {
if (annotations != null) {
for (T ad : annotations) {
ad.print(out, initialTab);
out.println();
}
}
}
public void print() throws IOException { public void print() throws IOException {
int k, l; int k, l;
String className = pool.getClassName(this_cpx); String className = "";
String moduleName = pool.getModuleName(this_cpx); if( isModuleUnit() ) {
boolean isModuleUnit = !moduleName.isEmpty();
pkgPrefixLen = className.lastIndexOf("/") + 1;
// Write the header
// package-info compilation unit
if (className.endsWith("package-info")) {
// Print the Annotations // Print the Annotations
if (visibleAnnotations != null) { printAnnotations(visibleAnnotations);
for (AnnotationData visad : visibleAnnotations) { printAnnotations(invisibleAnnotations);
visad.print(out, initialTab); } else {
out.println(); className = pool.getClassName(this_cpx);
pkgPrefixLen = className.lastIndexOf("/") + 1;
// Write the header
// package-info compilation unit
if (className.endsWith("package-info")) {
// Print the Annotations
printAnnotations(visibleAnnotations);
printAnnotations(invisibleAnnotations);
printAnnotations(visibleTypeAnnotations);
printAnnotations(invisibleTypeAnnotations);
if (pkgPrefixLen != 0) {
pkgPrefix = className.substring(0, pkgPrefixLen);
out.print("package " + pkgPrefix.substring(0, pkgPrefixLen - 1) + " ");
out.print("version " + major_version + ":" + minor_version + ";");
} }
}
if (invisibleAnnotations != null) {
for (AnnotationData invisad : invisibleAnnotations) {
invisad.print(out, initialTab);
out.println();
}
}
if (visibleTypeAnnotations != null) {
out.println(); out.println();
for (TypeAnnotationData visad : visibleTypeAnnotations) { return;
visad.print(out, initialTab);
out.println();
}
} }
if (invisibleTypeAnnotations != null) {
out.println();
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
invisad.print(out, initialTab);
out.println();
}
}
if (pkgPrefixLen != 0) {
pkgPrefix = className.substring(0, pkgPrefixLen);
out.print("package " + pkgPrefix.substring(0, pkgPrefixLen - 1) + " ");
out.print("version " + major_version + ":" + minor_version + ";");
}
out.println();
return;
}
if (!isModuleUnit) {
if (pkgPrefixLen != 0) { if (pkgPrefixLen != 0) {
pkgPrefix = className.substring(0, pkgPrefixLen); pkgPrefix = className.substring(0, pkgPrefixLen);
out.println("package " + pkgPrefix.substring(0, pkgPrefixLen - 1) + ";"); out.println("package " + pkgPrefix.substring(0, pkgPrefixLen - 1) + ";");
className = pool.getShortClassName(this_cpx, pkgPrefix); className = pool.getShortClassName(this_cpx, pkgPrefix);
} }
out.println(); out.println();
// Print the Annotations // Print the Annotations
if (visibleAnnotations != null) { printAnnotations(visibleAnnotations);
for (AnnotationData visad : visibleAnnotations) { printAnnotations(invisibleAnnotations);
visad.print(out, initialTab); printAnnotations(visibleTypeAnnotations);
out.println(); printAnnotations(invisibleTypeAnnotations);
}
}
if (invisibleAnnotations != null) {
for (AnnotationData invisad : invisibleAnnotations) {
invisad.print(out, initialTab);
out.println();
}
}
if (visibleTypeAnnotations != null) {
out.println();
for (TypeAnnotationData visad : visibleTypeAnnotations) {
visad.print(out, initialTab);
out.println();
}
}
if (invisibleTypeAnnotations != null) {
out.println();
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
invisad.print(out, initialTab);
out.println();
}
}
if ((access & ACC_SUPER) != 0) { if ((access & ACC_SUPER) != 0) {
out.print("super "); out.print("super ");
access = access & ~ACC_SUPER; access = access & ~ACC_SUPER;
} }
} }
// see if we are going to print: abstract interface class
// see if we are going to print: abstract interface class
// then replace it with just: interface // then replace it with just: interface
printHeader: printHeader:
{ {
@ -427,21 +390,25 @@ printSugar:
break printHeader; break printHeader;
} }
// not all conditions met, print header in ordinary way: if(isModuleUnit()) {
out.print(Modifiers.accessString(access, CF_Context.CTX_CLASS)); out.print(moduleData.getModuleHeader());
if (isSynthetic) { } else {
out.print("synthetic "); // not all conditions met, print header in ordinary way:
out.print(Modifiers.accessString(access, CF_Context.CTX_CLASS));
if (isSynthetic) {
out.print("synthetic ");
}
if (isDeprecated) {
out.print("deprecated ");
}
if (options.contains(Options.PR.CPX)) {
out.print("\t#" + this_cpx + "; //");
}
pool.PrintConstant(out, this_cpx);
} }
if (isDeprecated) {
out.print("deprecated ");
}
if (options.contains(Options.PR.CPX)) {
out.print("\t#" + this_cpx + "; //");
}
pool.PrintConstant(out, this_cpx);
} }
out.println(); out.println();
if(!isModuleUnit ) { if(!isModuleUnit()) {
if (!pool.getClassName(super_cpx).equals("java/lang/Object")) { if (!pool.getClassName(super_cpx).equals("java/lang/Object")) {
out.print("\textends "); out.print("\textends ");
pool.printlnClassId(out, super_cpx); pool.printlnClassId(out, super_cpx);
@ -470,11 +437,10 @@ printSugar:
out.println("\t// Compiled from " + source_name); out.println("\t// Compiled from " + source_name);
try { try {
source = new TextLines(source_name); source = new TextLines(source_name);
} catch (IOException e) { } catch (IOException ignored) {}
}
} }
// keep this new line for classes to pass huge test suite. // keep this new line for classes to pass huge test suite.
if(!isModuleUnit) if(!isModuleUnit())
out.println(); out.println();
// Print the constant pool // Print the constant pool
@ -482,52 +448,56 @@ printSugar:
pool.print(out); pool.print(out);
out.println(); out.println();
} }
// Don't print fields, methods, inner classes and bootstrap methods if it is module-info entity
if ( !isModuleUnit() ) {
// Print the fields // Print the fields
if (fields != null) { if (fields != null && !fields.isEmpty()) {
for (FieldData curf : fields) { for (FieldData curf : fields) {
curf.print(); curf.print();
}
} }
}
// Print the methods // Print the methods
if (methods != null) { if (methods != null && !methods.isEmpty()) {
for (MethodData curm : methods) { for (MethodData curm : methods) {
boolean skipBlankLine = false; boolean skipBlankLine = false;
curm.print(skipBlankLine); curm.print(skipBlankLine);
}
out.println();
} }
out.println();
}
// Print the inner classes // Print the inner classes
if (innerClasses != null) { if (innerClasses != null && !innerClasses.isEmpty()) {
for (InnerClassData icd : innerClasses) { for (InnerClassData icd : innerClasses) {
icd.print(); icd.print();
}
out.println();
} }
out.println(); // Print the BootstrapMethods
} //
// Only print these if printing extended constants
// Print the BootstrapMethods if ((options.contains(Options.PR.CPX)) && bootstrapMethods != null && !bootstrapMethods.isEmpty()) {
// for (BootstrapMethodData bsmdd : bootstrapMethods) {
// Only print these if printing extended constants bsmdd.print();
if ((options.contains(Options.PR.CPX)) && bootstrapMethods != null) { }
for (BootstrapMethodData bsmdd : bootstrapMethods) { out.println();
bsmdd.print();
} }
out.println();
}
// Print module attributes
if( isModuleUnit && moduleData != null) {
moduleData.print();
}
if( isModuleUnit ) {
out.println("} // end Module " + moduleName);
} else {
out.println("} // end Class " + className); out.println("} // end Class " + className);
} else {
// Print module attributes
moduleData.print();
out.print("} // end Module ");
out.print( moduleData.getModuleName());
if(moduleData.getModuleVersion() != null)
out.print(" @" + moduleData.getModuleVersion());
out.println();
} }
} // end ClassData.print() } // end ClassData.print()
// Gets the type of processed binary
private boolean isModuleUnit() {
return moduleData != null;
}
}// end class ClassData }// end class ClassData

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -65,8 +65,8 @@ public class CodeData {
name_cpx = in.readShort(); name_cpx = in.readShort();
sig_cpx = in.readShort(); sig_cpx = in.readShort();
slot = in.readShort(); slot = in.readShort();
//cls.traceln(" var #"+name_cpx+" start:"+start_pc // cls.traceln(" var #"+name_cpx+" start:"+start_pc
//+" length:"+length+"sig_cpx:"+sig_cpx+" sig_cpx:"+sig_cpx); // +" length:"+length+"sig_cpx:"+sig_cpx+" sig_cpx:"+sig_cpx);
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,7 +42,6 @@ public class ConstantPool {
private static final Hashtable<Byte, TAG> taghash = new Hashtable<>(); private static final Hashtable<Byte, TAG> taghash = new Hashtable<>();
private static final Hashtable<Byte, SUBTAG> subtaghash = new Hashtable<>(); private static final Hashtable<Byte, SUBTAG> subtaghash = new Hashtable<>();
/*-------------------------------------------------------- */ /*-------------------------------------------------------- */
/* ConstantPool Inner Classes */ /* ConstantPool Inner Classes */
/** /**
@ -66,8 +65,9 @@ public class ConstantPool {
CONSTANT_NAMEANDTYPE ((byte) 12, "NameAndType", "CONSTANT_NAMEANDTYPE"), CONSTANT_NAMEANDTYPE ((byte) 12, "NameAndType", "CONSTANT_NAMEANDTYPE"),
CONSTANT_METHODHANDLE ((byte) 15, "MethodHandle", "CONSTANT_METHODHANDLE"), CONSTANT_METHODHANDLE ((byte) 15, "MethodHandle", "CONSTANT_METHODHANDLE"),
CONSTANT_METHODTYPE ((byte) 16, "MethodType", "CONSTANT_METHODTYPE"), CONSTANT_METHODTYPE ((byte) 16, "MethodType", "CONSTANT_METHODTYPE"),
// CONSTANT_INVOKEDYNAMIC_TRANS ((byte) 17, "InvokeDynamicTrans", "method reciever"), CONSTANT_INVOKEDYNAMIC ((byte) 18, "InvokeDynamic", "CONSTANT_INVOKEDYNAMIC"),
CONSTANT_INVOKEDYNAMIC ((byte) 18, "InvokeDynamic", "CONSTANT_INVOKEDYNAMIC"); CONSTANT_MODULE ((byte) 19, "Module", "CONSTANT_MODULE"),
CONSTANT_PACKAGE ((byte) 20, "Package", "CONSTANT_PACKAGE");
private final Byte value; private final Byte value;
private final String tagname; private final String tagname;
@ -164,8 +164,9 @@ public class ConstantPool {
taghash.put(new Byte(TAG.CONSTANT_NAMEANDTYPE.value()), TAG.CONSTANT_NAMEANDTYPE); taghash.put(new Byte(TAG.CONSTANT_NAMEANDTYPE.value()), TAG.CONSTANT_NAMEANDTYPE);
taghash.put(new Byte(TAG.CONSTANT_METHODHANDLE.value()), TAG.CONSTANT_METHODHANDLE); taghash.put(new Byte(TAG.CONSTANT_METHODHANDLE.value()), TAG.CONSTANT_METHODHANDLE);
taghash.put(new Byte(TAG.CONSTANT_METHODTYPE.value()), TAG.CONSTANT_METHODTYPE); taghash.put(new Byte(TAG.CONSTANT_METHODTYPE.value()), TAG.CONSTANT_METHODTYPE);
// taghash.put(new Byte(TAG.CONSTANT_INVOKEDYNAMIC_TRANS.value()), TAG.CONSTANT_INVOKEDYNAMIC_TRANS);
taghash.put(new Byte(TAG.CONSTANT_INVOKEDYNAMIC.value()), TAG.CONSTANT_INVOKEDYNAMIC); taghash.put(new Byte(TAG.CONSTANT_INVOKEDYNAMIC.value()), TAG.CONSTANT_INVOKEDYNAMIC);
taghash.put(new Byte(TAG.CONSTANT_MODULE.value()), TAG.CONSTANT_MODULE);
taghash.put(new Byte(TAG.CONSTANT_PACKAGE.value()), TAG.CONSTANT_PACKAGE);
subtaghash.put(new Byte(SUBTAG.REF_GETFIELD.value()), SUBTAG.REF_GETFIELD); subtaghash.put(new Byte(SUBTAG.REF_GETFIELD.value()), SUBTAG.REF_GETFIELD);
subtaghash.put(new Byte(SUBTAG.REF_GETSTATIC.value()), SUBTAG.REF_GETSTATIC); subtaghash.put(new Byte(SUBTAG.REF_GETSTATIC.value()), SUBTAG.REF_GETSTATIC);
@ -431,7 +432,7 @@ public class ConstantPool {
* CPX * CPX
* *
* Constant entries that contain a single constant-pool index. Usually, this includes: * Constant entries that contain a single constant-pool index. Usually, this includes:
* CONSTANT_CLASS CONSTANT_METHODTYPE CONSTANT_STRING * CONSTANT_CLASS CONSTANT_METHODTYPE CONSTANT_STRING CONSTANT_MODULE CONSTANT_PACKAGE
* *
*/ */
class CPX extends Constant { class CPX extends Constant {
@ -445,12 +446,15 @@ public class ConstantPool {
@Override @Override
public String stringVal() { public String stringVal() {
String str = "UnknownTag"; String str = "UnknownTag";
switch (tag) { switch (tag) {
case CONSTANT_CLASS: case CONSTANT_CLASS:
str = getShortClassName(getClassName(this), cd.pkgPrefix); str = getShortClassName(getClassName(this), cd.pkgPrefix);
break; break;
case CONSTANT_PACKAGE:
case CONSTANT_MODULE:
str = getString(value);
break;
case CONSTANT_METHODTYPE: case CONSTANT_METHODTYPE:
case CONSTANT_STRING: case CONSTANT_STRING:
str = StringValue(value); str = StringValue(value);
@ -468,6 +472,8 @@ public class ConstantPool {
case CONSTANT_CLASS: case CONSTANT_CLASS:
case CONSTANT_STRING: case CONSTANT_STRING:
case CONSTANT_METHODTYPE: case CONSTANT_METHODTYPE:
case CONSTANT_PACKAGE:
case CONSTANT_MODULE:
out.println("#" + (value) + ";\t// " + stringVal()); out.println("#" + (value) + ";\t// " + stringVal());
break; break;
} }
@ -509,10 +515,6 @@ public class ConstantPool {
case CONSTANT_METHODHANDLE: case CONSTANT_METHODHANDLE:
str = subtagToString(value1) + ":" + StringValue(value2); str = subtagToString(value1) + ":" + StringValue(value2);
break; break;
// Removed INVOKEDYNAMIC_TRANS
// case: CONSTANT_INVOKEDYNAMIC_TRANS:
// str = StringValue(value1) + ":" + StringValue(value2);
// break;
case CONSTANT_INVOKEDYNAMIC: case CONSTANT_INVOKEDYNAMIC:
int bsm_attr_idx = value1; int bsm_attr_idx = value1;
int nape_idx = value2; int nape_idx = value2;
@ -562,7 +564,6 @@ public class ConstantPool {
out.println(value1 + ":#" + value2 + ";\t// " + stringVal()); out.println(value1 + ":#" + value2 + ";\t// " + stringVal());
break; break;
case CONSTANT_NAMEANDTYPE: case CONSTANT_NAMEANDTYPE:
// case CONSTANT_INVOKEDYNAMIC_TRANS:
out.println("#" + value1 + ":#" + value2 + ";\t// " + stringVal()); out.println("#" + value1 + ":#" + value2 + ";\t// " + stringVal());
break; break;
case CONSTANT_INVOKEDYNAMIC: case CONSTANT_INVOKEDYNAMIC:
@ -641,6 +642,8 @@ public class ConstantPool {
case CONSTANT_CLASS: case CONSTANT_CLASS:
case CONSTANT_STRING: case CONSTANT_STRING:
case CONSTANT_METHODTYPE: case CONSTANT_METHODTYPE:
case CONSTANT_PACKAGE:
case CONSTANT_MODULE:
pool.add(i, new CPX(tagobj, in.readUnsignedShort())); pool.add(i, new CPX(tagobj, in.readUnsignedShort()));
break; break;
case CONSTANT_FIELD: case CONSTANT_FIELD:
@ -648,7 +651,6 @@ public class ConstantPool {
case CONSTANT_INTERFACEMETHOD: case CONSTANT_INTERFACEMETHOD:
case CONSTANT_NAMEANDTYPE: case CONSTANT_NAMEANDTYPE:
case CONSTANT_INVOKEDYNAMIC: case CONSTANT_INVOKEDYNAMIC:
// case CONSTANT_INVOKEDYNAMIC_TRANS:
pool.add(i, new CPX2(tagobj, in.readUnsignedShort(), in.readUnsignedShort())); pool.add(i, new CPX2(tagobj, in.readUnsignedShort(), in.readUnsignedShort()));
break; break;
case CONSTANT_METHODHANDLE: case CONSTANT_METHODHANDLE:
@ -730,7 +732,49 @@ public class ConstantPool {
/** /**
* *
* getName * getModule
*
* Public string val - Safely gets the string-rep of a ConstantModule from the CP at a
* given index.
*
* Returns either null (if invalid), or the string value of the ConstantModule
*
*/
public String getModule(int cpx) {
String str = null;
if (inbounds(cpx)) {
Constant cns = pool.get(cpx);
if (cns != null && cns.tag == TAG.CONSTANT_MODULE) {
str = cns.stringVal();
}
}
return str;
}
/**
*
* getPackage
*
* Public string val - Safely gets the string-rep of a ConstantPackage from the CP at a
* given index.
*
* Returns either null (if invalid), or the string value of the ConstantPackage
*
*/
public String getPackage(int cpx) {
String str = null;
if (inbounds(cpx)) {
Constant cns = pool.get(cpx);
if (cns != null && cns.tag == TAG.CONSTANT_PACKAGE) {
str = cns.stringVal();
}
}
return str;
}
/**
*
* getTypeName
* *
* Safely gets a Java name from a ConstantUTF8 from the CP at a given index. * Safely gets a Java name from a ConstantUTF8 from the CP at a given index.
* *
@ -771,38 +815,6 @@ public class ConstantPool {
return getClassName((CPX) cns); return getClassName((CPX) cns);
} }
/**
*
* getModuleName
*
* Gets a Java module name from a ConstantClass from the CP at a given index
* where this_class is presented in the form: [Module's name in internal form (JVMS 4.2.1)]/module-info
* Traditionally, if this_class indicates P/Q/R, then the ClassFile occupies a file R.class in a directory representing
* the package P.Q. Similarly, if this_class indicates P/Q/module-info, then the ClassFile occupies a file module-info.class
* in a directory representing the module P.Q.
*
* Returns the Java module name, or an empty string in any other case.
*/
public String getModuleName(int cpx) {
String this_class = getClassName(cpx);
if(this_class.equals("#" + cpx)) {
return "";
}
return _getModuleName(this_class);
}
/**
* _getModuleName
*
* Helper for getting Module's name from the this_class string.
*
* Returns an empty string if this_class is not [Module's name in internal form (JVMS 4.2.1)]/module-info
*/
private String _getModuleName(String this_class) {
int i = this_class.lastIndexOf("/module-info");
return (i>0) ? this_class.substring(0,i).replace('/', '.') : "";
}
/** /**
* *
* getClassName * getClassName
@ -942,7 +954,6 @@ public class ConstantPool {
} }
/** /**
*
* ConstantStrValue * ConstantStrValue
* *
* Safely gets the string value of any Constant at any CP index. This string is either * Safely gets the string value of any Constant at any CP index. This string is either
@ -962,10 +973,8 @@ public class ConstantPool {
return "#" + cpx; return "#" + cpx;
} }
switch (cns.tag) { switch (cns.tag) {
case CONSTANT_METHODHANDLE: case CONSTANT_METHODHANDLE:
case CONSTANT_INVOKEDYNAMIC: case CONSTANT_INVOKEDYNAMIC:
// case CONSTANT_INVOKEDYNAMIC_TRANS:
case CONSTANT_METHOD: case CONSTANT_METHOD:
case CONSTANT_INTERFACEMETHOD: case CONSTANT_INTERFACEMETHOD:
case CONSTANT_FIELD: { case CONSTANT_FIELD: {
@ -975,21 +984,11 @@ public class ConstantPool {
} }
} }
} }
if(cns.tag == TAG.CONSTANT_CLASS) {
String moduleName = _getModuleName(StringValue(cpx));
if( !moduleName.isEmpty() ) {
return " " + moduleName;
}
}
return cns.tag.tagname + " " + StringValue(cpx); return cns.tag.tagname + " " + StringValue(cpx);
} }
/** /**
*
* print
*
* prints the entire constant pool. * prints the entire constant pool.
*
*/ */
public void print(PrintWriter out) throws IOException { public void print(PrintWriter out) throws IOException {
int cpx = 0; int cpx = 0;

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,7 +39,7 @@ public class Main {
/** /**
* Name of the program. * Name of the program.
*/ */
String program; public static String programName;
/** /**
* The stream where error message are printed. * The stream where error message are printed.
*/ */
@ -58,14 +58,14 @@ public class Main {
*/ */
public Main(PrintWriter out, String program) { public Main(PrintWriter out, String program) {
this.out = out; this.out = out;
this.program = program; Main.programName = program;
} }
/** /**
* Top level error message * Top level error message
*/ */
public void error(String msg) { public void error(String msg) {
System.err.println(program + ": " + msg); System.err.println(programName + ": " + msg);
} }
/** /**
@ -122,7 +122,6 @@ public class Main {
return false; return false;
} }
disasm:
for (String inpname : vj) { for (String inpname : vj) {
if (inpname == null) { if (inpname == null) {
continue; continue;
@ -131,14 +130,16 @@ disasm:
ClassData cc = new ClassData(out); ClassData cc = new ClassData(out);
cc.read(new DataInputStream(new FileInputStream(inpname))); cc.read(new DataInputStream(new FileInputStream(inpname)));
cc.print(); cc.print();
continue disasm; continue;
} catch (FileNotFoundException ee) { } catch (FileNotFoundException ee) {
error(i18n.getString("jdis.error.cannot_read", inpname)); error(i18n.getString("jdis.error.cannot_read", inpname));
} catch (Error ee) { } catch (Error ee) {
ee.printStackTrace(); if (options.contains(Options.PR.DEBUG))
ee.printStackTrace();
error(i18n.getString("jdis.error.fatal_error", inpname)); error(i18n.getString("jdis.error.fatal_error", inpname));
} catch (Exception ee) { } catch (Exception ee) {
ee.printStackTrace(); if (options.contains(Options.PR.DEBUG))
ee.printStackTrace();
error(i18n.getString("jdis.error.fatal_exception", inpname)); error(i18n.getString("jdis.error.fatal_exception", inpname));
} }
return false; return false;

@ -22,15 +22,15 @@
*/ */
package org.openjdk.asmtools.jdis; package org.openjdk.asmtools.jdis;
import org.openjdk.asmtools.jasm.Modifiers;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import static java.lang.String.format; import org.openjdk.asmtools.common.Module;
import org.openjdk.asmtools.jasm.JasmTokens;
import static org.openjdk.asmtools.jdis.Main.i18n;
/** /**
* The module attribute data. * The module attribute data.
@ -47,79 +47,145 @@ public class ModuleData {
this.out = clsData.out; this.out = clsData.out;
} }
public String getModuleName() {
return module == null ? "N/A" : module.getModuleName();
}
public String getModuleVersion() { return module.getModuleVersion(); }
public String getModuleHeader() {
if ( module == null ) {
return "N/A";
} else {
StringBuilder sb = new StringBuilder(module.getModuleFlags());
sb.append(JasmTokens.Token.MODULE.parsekey()).append(" ");
sb.append(module.getModuleName());
if (module.getModuleVersion() != null)
sb.append("// @").append(module.getModuleVersion());
return sb.toString();
}
}
/** /**
* Reads and resolve the method's attribute data called from ClassData. * Reads and resolve the method's attribute data called from ClassData.
*/ */
public void read(DataInputStream in) throws IOException { public void read(DataInputStream in) throws IOException {
Module.Builder builder = new Module.Builder(); int index, moduleFlags, versionIndex;
int requires_count = in.readUnsignedShort(); String moduleName, version;
for (int i = 0; i < requires_count; i++) { Module.Builder builder;
int index = in.readUnsignedShort(); try {
int flags = in.readUnsignedShort(); // u2 module_name_index;
String moduleName = pool.getString(index); index = in.readUnsignedShort();
moduleName = pool.getModule(index);
Set<Modifier> mods; // u2 module_flags;
if (flags == 0) { moduleFlags = in.readUnsignedShort();
mods = Collections.emptySet(); // u2 module_version_index;
} else { versionIndex = in.readUnsignedShort();
mods = new HashSet<>(); version = pool.getString(versionIndex);
if (Modifiers.isReexport(flags)) builder = new Module.Builder(moduleName, moduleFlags, version);
mods.add(Modifier.PUBLIC); } catch (IOException ioe) {
if (Modifiers.isSynthetic(flags)) System.err.println(Main.programName + ": " + i18n.getString("jdis.error.invalid_header"));
mods.add(Modifier.SYNTHETIC); throw ioe;
if (Modifiers.isMandated(flags))
mods.add(Modifier.MANDATED);
}
builder.require(moduleName, mods);
} }
int exports_count = in.readUnsignedShort(); try {
if (exports_count > 0) { int requires_count = in.readUnsignedShort();
for (int i = 0; i < exports_count; i++) { for (int i = 0; i < requires_count; i++) {
int index = in.readUnsignedShort(); index = in.readUnsignedShort();
String packageName = pool.getString(index).replace('/', '.'); int requiresFlags = in.readUnsignedShort();
int exports_to_count = in.readUnsignedShort(); versionIndex = in.readUnsignedShort();
if (exports_to_count > 0) {
Set<String> targets = new HashSet<>(exports_to_count); moduleName = pool.getModule(index);
for (int j = 0; j < exports_to_count; j++) { version = pool.getString(versionIndex);
int exports_to_index = in.readUnsignedShort(); builder.require(moduleName, requiresFlags, version);
targets.add(pool.getString(exports_to_index)); }
} catch (IOException ioe) {
System.err.println(Main.programName + ": " + i18n.getString("jdis.error.invalid_requires"));
throw ioe;
}
try {
int exports_count = in.readUnsignedShort();
if (exports_count > 0) {
for (int i = 0; i < exports_count; i++) {
index = in.readUnsignedShort();
String packageName = pool.getPackage(index);
int exportsFlags = in.readUnsignedShort();
int exports_to_count = in.readUnsignedShort();
if (exports_to_count > 0) {
Set<String> targets = new HashSet<>(exports_to_count);
for (int j = 0; j < exports_to_count; j++) {
int exports_to_index = in.readUnsignedShort();
targets.add(pool.getModule(exports_to_index));
}
builder.exports(packageName, exportsFlags, targets);
} else {
builder.exports(packageName, exportsFlags);
} }
builder.exports(packageName, targets);
} else {
builder.export(packageName);
} }
} }
} catch (IOException ioe) {
System.err.println(Main.programName + ": " + i18n.getString("jdis.error.invalid_exports"));
throw ioe;
} }
int uses_count = in.readUnsignedShort(); try {
if (uses_count > 0) { int opens_count = in.readUnsignedShort();
for (int i = 0; i < uses_count; i++) { if (opens_count > 0) {
int index = in.readUnsignedShort(); for (int i = 0; i < opens_count; i++) {
String serviceName = pool.getClassName(index).replace('/', '.'); index = in.readUnsignedShort();
builder.use(serviceName); String packageName = pool.getPackage(index);
} int opensFlags = in.readUnsignedShort();
} int opens_to_count = in.readUnsignedShort();
if (opens_to_count > 0) {
int provides_count = in.readUnsignedShort(); Set<String> targets = new HashSet<>(opens_to_count);
if (provides_count > 0) { for (int j = 0; j < opens_to_count; j++) {
Map<String, Set<String>> pm = new HashMap<>(); int opens_to_index = in.readUnsignedShort();
for (int i = 0; i < provides_count; i++) { targets.add(pool.getModule(opens_to_index));
int index = in.readUnsignedShort(); }
int with_index = in.readUnsignedShort(); builder.opens(packageName, opensFlags, targets);
String sn = pool.getClassName(index).replace('/', '.'); } else {
String cn = pool.getClassName(with_index).replace('/', '.'); builder.opens(packageName, opensFlags);
// computeIfAbsent }
Set<String> providers = pm.get(sn);
if (providers == null) {
providers = new HashSet<>();
pm.put(sn, providers);
} }
providers.add(cn);
} }
for (Map.Entry<String, Set<String>> e : pm.entrySet()) { } catch (IOException ioe) {
builder.provide(e.getKey(), e.getValue()); System.err.println(Main.programName + ": " + i18n.getString("jdis.error.invalid_opens"));
throw ioe;
}
try {
int uses_count = in.readUnsignedShort();
if (uses_count > 0) {
for (int i = 0; i < uses_count; i++) {
index = in.readUnsignedShort();
String serviceName = pool.getClassName(index);
builder.uses(serviceName);
}
} }
} catch (IOException ioe) {
System.err.println(Main.programName + ": " + i18n.getString("jdis.error.invalid_uses"));
throw ioe;
}
try {
int provides_count = in.readUnsignedShort();
if (provides_count > 0) {
for (int i = 0; i < provides_count; i++) {
index = in.readUnsignedShort();
String serviceName = pool.getClassName(index);
int provides_with_count = in.readUnsignedShort();
Set<String> implNames = new HashSet<>(provides_with_count);
for (int j = 0; j < provides_with_count; j++) {
int provides_with_index = in.readUnsignedShort();
implNames.add(pool.getClassName(provides_with_index));
}
builder.provides(serviceName, implNames);
}
}
} catch (IOException ioe) {
System.err.println(Main.programName + ": " + i18n.getString("jdis.error.invalid_provides"));
throw ioe;
} }
module = builder.build(); module = builder.build();
} }
@ -129,195 +195,4 @@ public class ModuleData {
if (module != null) if (module != null)
out.println(module.toString()); out.println(module.toString());
} }
private enum Modifier {
PUBLIC(0x0020), SYNTHETIC(0x1000), MANDATED(0x8000);
private final int value;
Modifier(int value) {
this.value = value;
}
}
private final static class Module {
//* A service dependence's of this module
final Set<String> uses;
//* A module on which the current module has a dependence.
private final Set<Dependence> requires;
//* A module export, may be qualified or unqualified.
private final Map<String, Set<String>> exports;
//* A service that a module provides one or more implementations of.
private final Map<String, Set<String>> provides;
private Module(Set<Dependence> requires,
Map<String, Set<String>> exports,
Set<String> uses,
Map<String, Set<String>> provides) {
this.requires = Collections.unmodifiableSet(requires);
this.exports = Collections.unmodifiableMap(exports);
this.uses = Collections.unmodifiableSet(uses);
this.provides = Collections.unmodifiableMap(provides);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
requires.stream()
.sorted()
.forEach(d -> sb.append(format(" %s%n", d.toString())));
//
exports.entrySet().stream()
.filter(e -> e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" exports %s;%n", e.getKey()))
.forEach(sb::append);
exports.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" exports %s to%n%s;%n", e.getKey(),
e.getValue().stream().sorted()
.map(mn -> format(" %s", mn))
.collect(Collectors.joining(",\n"))))
.forEach(sb::append);
//
uses.stream().sorted()
.map(s -> format(" uses %s;%n", s))
.forEach(sb::append);
//
provides.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.flatMap(e -> e.getValue().stream().sorted()
.map(impl -> format(" provides %s with %s;%n", e.getKey(), impl)))
.forEach(sb::append);
return sb.toString();
}
//* A module on which the current module has a dependence.
private final static class Dependence implements Comparable<Dependence> {
private final String name;
private final Set<Modifier> flags;
public Dependence(String name, Set<Modifier> flags) {
this.name = name;
this.flags = flags;
}
/**
* Returns the module name.
*
* @return The module name
*/
public String name() {
return name;
}
/**
* Returns the set of modifiers.
*
* @return A possibly-empty unmodifiable set of modifiers
*/
public Set<Modifier> modifiers() {
return flags;
}
@Override
public int hashCode() {
return name.hashCode() * 11 + flags.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof Dependence) {
Dependence d = (Dependence) o;
return this.name.equals(d.name) && flags.equals(d.flags);
}
return false;
}
@Override
public int compareTo(Dependence o) {
int rc = this.name.compareTo(o.name);
return rc != 0 ? rc : Integer.compare(this.flagsValue(), o.flagsValue());
}
@Override
public String toString() {
return format("requires %s%s;", flags.contains(Modifier.PUBLIC) ? "public " : "", name);
}
private int flagsValue() {
int value = 0;
for (Modifier m : flags) {
value |= m.value;
}
return value;
}
}
/**
* The module builder.
*/
public static final class Builder {
public final Set<Dependence> requires = new HashSet<>();
final Map<String, Set<String>> exports = new HashMap<>();
final Set<String> uses = new HashSet<>();
final Map<String, Set<String>> provides = new HashMap<>();
public Builder() {
}
/**
* Adds a module on which the current module has a dependence.
*/
public Builder require(String d, Set<Modifier> flags) {
requires.add(new Dependence(d, flags));
return this;
}
/**
* Adds a unqualified module export.
*/
public Builder export(String p) {
Objects.requireNonNull(p);
if (!exports.containsKey(p)) exports.put(p, new HashSet<>());
return this;
}
/**
* Adds a qualified module exports.
*/
public Builder exports(String p, Set<String> ms) {
Objects.requireNonNull(p);
Objects.requireNonNull(ms);
if (!exports.containsKey(p)) export(p);
exports.get(p).addAll(ms);
return this;
}
/**
* Adds a service dependence's of this module
*/
public Builder use(String cn) {
uses.add(cn);
return this;
}
/**
* Adds a service that a module provides one or more implementations of.
*/
public Builder provide(String s, Set<String> impl) {
provides.computeIfAbsent(s, _k -> new HashSet<>()).addAll(impl);
return this;
}
/**
* @return The new module
*/
public Module build() {
return new Module(requires, exports, uses, provides);
}
}
}
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -144,7 +144,7 @@ class StackMapData {
int[] map = new int[num]; int[] map = new int[num];
for (int k = 0; k < num; k++) { for (int k = 0; k < num; k++) {
int mt_val = in.readUnsignedByte(); int mt_val = in.readUnsignedByte();
StackMapType maptype = stackMapType(mt_val); StackMapType maptype = stackMapType(mt_val, null);
switch (maptype) { switch (maptype) {
case ITEM_Object: case ITEM_Object:
mt_val = mt_val | (in.readUnsignedShort() << 8); mt_val = mt_val | (in.readUnsignedShort() << 8);
@ -153,6 +153,7 @@ class StackMapData {
int pc = in.readUnsignedShort(); int pc = in.readUnsignedShort();
code.get_iAtt(pc).referred = true; code.get_iAtt(pc).referred = true;
mt_val = mt_val | (pc << 8); mt_val = mt_val | (pc << 8);
break;
} }
} }
map[k] = mt_val; map[k] = mt_val;

@ -1,4 +1,4 @@
# Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2014, 2017 Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -38,3 +38,10 @@ jdis.error.invalid_option=invalid option: {0}
jdis.error.cannot_read=cannot read {0} jdis.error.cannot_read=cannot read {0}
jdis.error.fatal_error=fatal error in file: {0} jdis.error.fatal_error=fatal error in file: {0}
jdis.error.fatal_exception=fatal exception in file: {0} jdis.error.fatal_exception=fatal exception in file: {0}
jdis.error.invalid_header=Invalid Module's attributes table
jdis.error.invalid_requires=Invalid requires table
jdis.error.invalid_exports=Invalid exports table
jdis.error.invalid_opens=Invalid opens table
jdis.error.invalid_uses=Invalid uses table
jdis.error.invalid_provides=Invalid provides table

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -168,13 +168,13 @@ class iAtt {
} }
} }
public void printMapList(int[] map) { public void printMapList(int[] map) throws IOException {
boolean pr_cpx = options.contains(Options.PR.CPX); boolean pr_cpx = options.contains(Options.PR.CPX);
for (int k = 0; k < map.length; k++) { for (int k = 0; k < map.length; k++) {
int fullmaptype = map[k]; int fullmaptype = map[k];
int mt_val = fullmaptype & 0xFF; int mt_val = fullmaptype & 0xFF;
StackMapType maptype = stackMapType(mt_val); StackMapType maptype = stackMapType(mt_val, out);
int argument = fullmaptype >> 8; int argument = fullmaptype >> 8;
switch (maptype) { switch (maptype) {
case ITEM_Object: case ITEM_Object: