CODETOOLS-7902618 CODETOOLS-7902643 CODETOOLS-7902644 CODETOOLS-7902648

This commit is contained in:
lkuskov 2020-04-02 16:02:32 -07:00
parent 79096622a1
commit 61d329f0fb
55 changed files with 2530 additions and 2246 deletions

View File

@ -1,9 +1,10 @@
re:data
re:data/.*
re:asmtools-6.0-build/.*
re:.*~$
re:.*\.log$
re:.*\.pyc$
re:.*\.swp$
re:.*\.DS_Store$
re:.*\iml$
syntax: regexp
data
data/.*
asmtools-7.0-build/.*
.*~$
.*\.log$
.*\.pyc$
.*\.swp$
.*\.DS_Store$
.*\.iml$

View File

@ -1,7 +1,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!--
Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@ -31,7 +31,7 @@
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
<title>README - AsmTools - Version 6.0</title>
<title>README - AsmTools - Version 7.0</title>
<style>
body, tr {
font-family: Arial, Helvetica, sans-serif;
@ -106,7 +106,7 @@ table.Screen { margin-top: 0.5em; margin-bottom: 0.5em;
<h1>Release Notes</h1>
<h2>AsmTools</h2>
</h2>
<h2>October 2017</h2>
<h2>April 2020</h2>
</center>
</td>
</tr>
@ -143,7 +143,7 @@ development process to test the compliance of a Virtual Machine (VM) to
its specification.</p>
<p>
These
release notes contain information about the ASM Tools version 6.0.
release notes contain information about the ASM Tools version 7.0.
See the (
<a href="https://wiki.openjdk.java.net/display/CodeTools/Main">CodeTools</a> project)
<a href="https://wiki.openjdk.java.net/display/CodeTools/AsmTools">AsmTools</a> OpenJDK project page for more information about AsmTools.
@ -163,8 +163,22 @@ See the (
<th class="sun-darkblue" scope="col"><b>Bug ID </b></th>
<th class="sun-darkblue" scope="col"><b>Description</b></th>
</tr>
<tr>
<td>
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902525">CODETOOLS-7902525</a>
</td>
<td>
Asmtools support: JEP 360 Sealed Types(Preview)
</td>
</tr>
<tr>
<td>
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902524">CODETOOLS-7902524</a>
</td>
<td>
Asmtools support: JEP 359 Records(Preview)
</td>
</tr>
</tbody>
</table>
<p>
@ -180,9 +194,39 @@ See the (
<th class="sun-darkblue" scope="col"><b>Bug ID </b></th>
<th class="sun-darkblue" scope="col"><b>Description</b></th>
</tr>
</tbody>
<tr>
<td>
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902618">CODETOOLS-7902618</a>
</td>
<td>
Asmtools does not support jasm output/input for TypeAnnotations.
</td>
</tr>
<tr>
<td>
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902643">CODETOOLS-7902643</a>
</td>
<td>
Asmtools(jasm) does not support signature attributes in field_info, component_info
</td>
</tr>
<tr>
<td>
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902644">CODETOOLS-7902644</a>
</td>
<td>
Asmtools (jcoder) fails if an jcod file contains CONSTANT_Utf8_info with non-normative char sequences
</td>
</tr>
<tr>
<td>
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902648">CODETOOLS-7902648</a>
</td>
<td>
jasm has no clues about how to interpret CONSTANT_MethodHandle_info:reference_kind in an invokedynamic instruction
</td>
</tr>
</tbody>
</table>
<p class="nav-link">[<a href="#_top">Top</a>]</p>
<p><a name="system_requirements"></a></p>
@ -195,7 +239,7 @@ version 1.8 or later, or a Java SE platform 8.0 runtime environment.
<p class="nav-link">[<a href="#_top">Top</a>]</p>
<a name="installation"></a>
<h2>Installation</h2>
To install the AsmTools, simply unzip the&nbsp; asmtools-6.0.zip
To install the AsmTools, simply unzip the&nbsp; asmtools-7.0.zip
distribution file in the directory of your choice. Optionally, you may
wish to define an environment variable (ASMTOOLSHOME) to point to this
location for your convenience.
@ -204,7 +248,7 @@ location for your convenience.
<h2>Release Contents</h2>
<p>
This section lists the components under the base subdirectory structure
(<code>asmtools-6.0/</code>)
(<code>asmtools-7.0/</code>)
that is created when you unzip the AsmTools distribution archive during
installation.
</p>
@ -285,7 +329,7 @@ The AsmTools open source project was created in order to develop a community tha
<p><a name="source" id="source"></a></p>
<h2>Obtaining the Sources</h2>
<p>
The sources for <a href="">ASM Tools</a> 6.0 and later is available via the community
The sources for <a href="">ASM Tools</a> 7.0 and later is available via the community
<a href="http://www.openjdk.org/">OpenJDK</a> project. The sources are stored
and accessed through a Mercurial repository, which the public may access in a
read-only fashion. Committing to changes to the sources is accomplished by
@ -340,7 +384,7 @@ The general steps to do a build from source from the command line:
<li>Make your current directory <code>&lt;topdir&gt;/build/</code>
<li>Invoke ant:<br><code>% ant</code>
<li>Output appears in a directory above (one above &lt;topdir&gt;),
such as: <code>../../asmtools-6.0-build/</code>
such as: <code>../../asmtools-7.0-build/</code>
</ol>
<p>
@ -368,7 +412,7 @@ specify in your IDE for building.
<hr>
<hr noshade="noshade">
<p><a href="legal/copyright.txt">Copyright</a> &copy; 2008, 2017, Oracle and/or its affiliates. All rights reserved.
<p><a href="legal/copyright.txt">Copyright</a> &copy; 2008, 2020, 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
HREF="http://openjdk.java.net/legal/gplv2+ce.html">GNU
General Public License Version 2 (GPLv2)</A></p>

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2020, 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.asmutils;
/**
* Utility class to share common tools/methods.
*/
public class StringUtils {
/**
* Converts CONSTANT_Utf8_info string to a printable string for jdis/jdes.
* @param utf8 UTF8 string taken from within ConstantPool of a class file
* @return output string for jcod/jasm
*/
public static String Utf8ToString(String utf8) {
StringBuilder sb = new StringBuilder("\"");
for (int k = 0; k < utf8.length(); k++) {
char c = utf8.charAt(k);
switch (c) {
case '\t':
sb.append('\\').append('t');
break;
case '\n':
sb.append('\\').append('n');
break;
case '\r':
sb.append('\\').append('r');
break;
case '\b':
sb.append('\\').append('b');
break;
case '\f':
sb.append('\\').append('f');
break;
case '\"':
sb.append('\\').append('\"');
break;
case '\'':
sb.append('\\').append('\'');
break;
case '\\':
sb.append('\\').append('\\');
break;
default:
sb.append(c);
}
}
return sb.append('\"').toString();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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
@ -22,6 +22,8 @@
*/
package org.openjdk.asmtools.common;
import org.openjdk.asmtools.jdis.Indenter;
import java.util.*;
import java.util.stream.Collectors;
@ -30,7 +32,7 @@ import static java.lang.String.format;
/**
* Internal presentation of a module
*/
public final class Module {
public final class Module extends Indenter {
//* A module name and module_flags
public final Header header;
@ -66,7 +68,7 @@ public final class Module {
int l = 0;
requires.stream()
.sorted()
.forEach(d -> sb.append(format(" requires %s;%s%n",
.forEach(d -> sb.append(getIndentString()).append(format("requires %s;%s%n",
d.toString(),
d.getModuleVersion() == null ? "" : " // @" + d.getModuleVersion())));
//
@ -74,14 +76,14 @@ public final class Module {
exports.entrySet().stream()
.filter(e -> e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" exports %s;%n", e.getKey().toString()))
.map(e -> format("%sexports %s;%n", getIndentString(), 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(),
.map(e -> format("%sexports %s to%n%s;%n", getIndentString(), e.getKey().toString(),
e.getValue().stream().sorted()
.map(mn -> format(" %s", mn))
.map(mn -> format("%s %s", getIndentString(), mn))
.collect(Collectors.joining(",\n"))))
.forEach(sb::append);
//
@ -89,29 +91,29 @@ public final class Module {
opens.entrySet().stream()
.filter(e -> e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> format(" opens %s;%n", e.getKey().toString()))
.map(e -> format("%sopens %s;%n", getIndentString(), 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(),
.map(e -> format("%sopens %s to%n%s;%n", getIndentString(), e.getKey().toString(),
e.getValue().stream().sorted()
.map(mn -> format(" %s", mn))
.map(mn -> format("%s %s", getIndentString(), mn))
.collect(Collectors.joining(",\n"))))
.forEach(sb::append);
//
l = newLine(sb,l);
uses.stream().sorted()
.map(s -> format(" uses %s;%n", s))
.map(s -> format("%suses %s;%n", getIndentString(), 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(),
.map(e -> format("%sprovides %s with%n%s;%n", getIndentString(), e.getKey().toString(),
e.getValue().stream().sorted()
.map(mn -> format(" %s", mn))
.map(mn -> format("%s %s", getIndentString(), mn))
.collect(Collectors.joining(",\n"))))
.forEach(sb::append);
//

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -26,7 +26,15 @@ import java.io.IOException;
import java.util.ArrayList;
/**
* See JVMS3, section 4.8.16.
* JVMS 4.7.16.
*
* annotation {
* u2 type_index;
* u2 num_element_value_pairs;
* { u2 element_name_index;
* element_value value;
* } element_value_pairs[num_element_value_pairs];
* }
*/
class AnnotationData implements Data {

View File

@ -193,6 +193,13 @@ class ClassData extends MemberData {
return this.recordData;
}
/**
* Rejects a record: removes the record attribute if there are no components
*/
public void rejectRecord() {
this.recordData = null;
}
// Field
public ConstantPool.ConstValue_Pair mkNape(ConstantPool.ConstCell name, ConstantPool.ConstCell sig) {
return new ConstantPool.ConstValue_Pair(ConstType.CONSTANT_NAMEANDTYPE, name, sig);
@ -325,14 +332,14 @@ class ClassData extends MemberData {
env.traceln("ascicell=" + ascicell);
ConstantPool.ConstValue_String me_str = (ConstantPool.ConstValue_String) ascicell.ref;
myClassName = me_str.value;
env.traceln("--------------------------------------------");
env.traceln("-------------------");
env.traceln("-- Constant Pool --");
env.traceln("-------------------");
pool.printPool();
env.traceln("--------------------------------------------");
env.traceln("-------------------");
env.traceln(" ");
env.traceln(" ");
env.traceln("--------------------------------------------");
env.traceln("-------------------");
env.traceln("-- Inner Classes --");
env.traceln("-------------------");
printInnerClasses();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -23,161 +23,37 @@
package org.openjdk.asmtools.jasm;
import org.openjdk.asmtools.jasm.OpcodeTables.Opcode;
import static org.openjdk.asmtools.jasm.RuntimeConstants.SPLIT_VERIFIER_CFV;
import org.openjdk.asmtools.jasm.Tables.AttrTag;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import static org.openjdk.asmtools.jasm.RuntimeConstants.SPLIT_VERIFIER_CFV;
class CodeAttr extends AttrData {
/*-------------------------------------------------------- */
/* CodeAttr inner classes */
static public class Local extends Argument {
String name;
boolean defd = false, refd = false;
public Local(String name) {
this.name = name;
}
}
/**
*
*/
static public class Label extends Local {
public Label(String name) {
super(name);
}
}
/**
*
*/
class LocVarData extends Local implements Data {
// arg means slot
short start_pc, length;
ConstantPool.ConstCell name_cpx, sig_cpx;
public LocVarData(String name) {
super(name);
}
@Override
public int getLength() {
return 10;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(start_pc);
out.writeShort(length);
out.writeShort(name_cpx.arg);
out.writeShort(sig_cpx.arg);
out.writeShort(arg);
}
}
/**
*
*/
class LineNumData implements Data {
int start_pc, line_number;
public LineNumData(int start_pc, int line_number) {
this.start_pc = start_pc;
this.line_number = line_number;
}
@Override
public int getLength() {
return 4;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(start_pc);
out.writeShort(line_number);
}
}
/**
*
*/
class Trap extends Local {
int start_pc = Argument.NotSet, end_pc = Argument.NotSet;
int pos;
Trap(int pos, String name) {
super(name);
this.pos = pos;
}
}
/**
*
*/
class TrapData implements Data {
int pos;
Trap trap;
int handler_pc;
Argument catchType;
public TrapData(int pos, Trap trap, int handler_pc, Argument catchType) {
this.pos = pos;
this.trap = trap;
this.handler_pc = handler_pc;
this.catchType = catchType;
}
@Override
public int getLength() {
return 8; // add the length of number of elements
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(trap.start_pc);
out.writeShort(trap.end_pc);
out.writeShort(handler_pc);
if (catchType.isSet()) {
out.writeShort(catchType.arg);
} else {
out.writeShort(0);
}
}
} // end TrapData
/*-------------------------------------------------------- */
/* CodeAttr Fields */
protected MethodData mtd;
protected ClassData cls;
protected MethodData mtd;
protected Environment env;
protected Argument max_stack, max_locals;
protected Instr zeroInstr, lastInstr;
protected int cur_pc = 0;
protected DataVector<TrapData> trap_table
= new DataVector<>(0); // TrapData
protected DataVector<TrapData> trap_table; // TrapData
protected DataVectorAttr<LineNumData> lin_num_tb; // LineNumData
protected int lastln = 0;
protected DataVectorAttr<LocVarData> loc_var_tb; // LocVarData
protected DataVector<DataVectorAttr<? extends Data>> attrs;
// protected iVector slots;
protected ArrayList<Integer> slots;
protected HashMap<String, LocVarData> locvarsHash;
protected HashMap<String, Label> labelsHash;
protected HashMap<String, Trap> trapsHash;
protected StackMapData curMapEntry = null;
protected DataVectorAttr<StackMapData> stackMap;
/*-------------------------------------------------------- */
// type annotations
protected DataVectorAttr<TypeAnnotationData> type_annotAttrVis = null;
protected DataVectorAttr<TypeAnnotationData> type_annotAttrInv = null;
public CodeAttr(MethodData mtd, int pos, int paramcnt, Argument max_stack, Argument max_locals) {
super(mtd.cls, AttrTag.ATT_Code.parsekey());
@ -193,10 +69,8 @@ class CodeAttr extends AttrData {
lin_num_tb = new DataVectorAttr<>(cls, AttrTag.ATT_LineNumberTable.parsekey());
attrs.add(lin_num_tb);
}
// slots = new iVector(paramcnt);
slots = new ArrayList<>(paramcnt);
for (int k = 0; k < paramcnt; k++) {
// slots.setElement(1, k);
slots.add(k, 1);
}
}
@ -205,6 +79,36 @@ class CodeAttr extends AttrData {
checkTraps();
checkLocVars();
checkLabels();
//
if (type_annotAttrVis != null) {
attrs.add(type_annotAttrVis);
}
if (type_annotAttrInv != null) {
attrs.add(type_annotAttrInv);
}
}
public void addAnnotations(ArrayList<AnnotationData> list) {
for (AnnotationData item : list) {
boolean invisible = item.invisible;
if (item instanceof TypeAnnotationData) {
// Type Annotations
TypeAnnotationData ta = (TypeAnnotationData) item;
if (invisible) {
if (type_annotAttrInv == null) {
type_annotAttrInv = new DataVectorAttr(cls,
AttrTag.ATT_RuntimeInvisibleTypeAnnotations.parsekey());
}
type_annotAttrInv.add(ta);
} else {
if (type_annotAttrVis == null) {
type_annotAttrVis = new DataVectorAttr(cls,
AttrTag.ATT_RuntimeVisibleTypeAnnotations.parsekey());
}
type_annotAttrVis.add(ta);
}
}
}
}
/* -------------------------------------- Traps */
@ -332,11 +236,8 @@ class CodeAttr extends AttrData {
}
public void LocVarDataDef(int slot) {
// slots.setElement(1, slot);
slots.set(slot, 1);
if ((max_locals != null) && (max_locals.arg < slots.size())) {
// if ((max_locals != null) && (max_locals.arg < slots.length)) {
env.error("warn.illslot", Integer.toString(slot));
}
}
@ -354,16 +255,6 @@ class CodeAttr extends AttrData {
int k;
findSlot:
{
/*
for (k = 0; k < slots.length; k++) {
if (slots.data[k] == 0) {
break findSlot;
}
}
k = slots.length;
*
*/
for (k = 0; k < slots.size(); k++) {
if (slots.get(k) == 0) {
break findSlot;
@ -391,7 +282,6 @@ class CodeAttr extends AttrData {
}
public void LocVarDataEnd(int slot) {
// slots.data[slot] = 0;
slots.set(slot, 0);
}
@ -405,10 +295,8 @@ class CodeAttr extends AttrData {
return;
}
locvar.length = (short) (cur_pc - locvar.start_pc);
// slots.data[locvar.arg] = 0;
slots.set(locvar.arg, 0);
// locvarsHash.put(name, null); unfortunately, prohibited
locvarsHash.put(name, new LocVarData(name));
}
@ -422,9 +310,7 @@ class CodeAttr extends AttrData {
} // this is false locvar
// set end of scope, if not set
if (slots.get(locvar.arg) == 1) {
// if (slots.data[locvar.arg] == 1) {
locvar.length = (short) (cur_pc - locvar.start_pc);
// slots.data[locvar.arg] = 0;
slots.set(locvar.arg, 0);
}
}
@ -497,14 +383,12 @@ class CodeAttr extends AttrData {
return 2 + 2 + 4 // for max_stack, max_locals, and cur_pc
+ cur_pc // + 2+trap_table.size()*8
+ trap_table.getLength() + attrs.getLength();
}
@Override
public void write(CheckedDataOutputStream out)
throws IOException, Parser.CompilerError {
int mxstck = (max_stack != null) ? max_stack.arg : 0;
// int mxloc = (max_locals != null) ? max_locals.arg : slots.length;
int mxloc = (max_locals != null) ? max_locals.arg : slots.size();
super.write(out); // attr name, attr len
out.writeShort(mxstck);
@ -518,5 +402,128 @@ class CodeAttr extends AttrData {
attrs.write(out);
}
/*-------------------------------------------------------- */
/* CodeAttr inner classes */
static public class Local extends Argument {
String name;
boolean defd = false, refd = false;
public Local(String name) {
this.name = name;
}
}
/**
*
*/
static public class Label extends Local {
public Label(String name) {
super(name);
}
}
/**
*
*/
class LocVarData extends Local implements Data {
// arg means slot
short start_pc, length;
ConstantPool.ConstCell name_cpx, sig_cpx;
public LocVarData(String name) {
super(name);
}
@Override
public int getLength() {
return 10;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(start_pc);
out.writeShort(length);
out.writeShort(name_cpx.arg);
out.writeShort(sig_cpx.arg);
out.writeShort(arg);
}
}
/**
*
*/
class LineNumData implements Data {
int start_pc, line_number;
public LineNumData(int start_pc, int line_number) {
this.start_pc = start_pc;
this.line_number = line_number;
}
@Override
public int getLength() {
return 4;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(start_pc);
out.writeShort(line_number);
}
}
/**
*
*/
class Trap extends Local {
int start_pc = Argument.NotSet, end_pc = Argument.NotSet;
int pos;
Trap(int pos, String name) {
super(name);
this.pos = pos;
}
}
/**
*
*/
class TrapData implements Data {
int pos;
Trap trap;
int handler_pc;
Argument catchType;
public TrapData(int pos, Trap trap, int handler_pc, Argument catchType) {
this.pos = pos;
this.trap = trap;
this.handler_pc = handler_pc;
this.catchType = catchType;
}
@Override
public int getLength() {
return 8; // add the length of number of elements
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(trap.start_pc);
out.writeShort(trap.end_pc);
out.writeShort(handler_pc);
if (catchType.isSet()) {
out.writeShort(catchType.arg);
} else {
out.writeShort(0);
}
}
} // end TrapData
} // end CodeAttr

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -25,11 +25,19 @@ package org.openjdk.asmtools.jasm;
import java.io.IOException;
/**
*
* Base contract for writeable structures
*/
interface Data {
public void write(CheckedDataOutputStream out) throws IOException;
void write(CheckedDataOutputStream out) throws IOException;
public int getLength();
int getLength();
default String tabString(int tabLevel) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < tabLevel; i++) {
sb.append('\t');
}
return sb.toString();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -320,15 +320,13 @@ public class Environment {
// Report the errors
for (ErrorMessage msg = errors; msg != null; msg = msg.next) {
int ln = lineNumber(msg.where);
int off = lineOffset(msg.where);
int i, j;
for (i = off; (i > 0) && (data[i - 1] != '\n') && (data[i - 1] != '\r'); i--);
for (j = off; (j < data.length) && (data[j] != '\n') && (data[j] != '\r'); j++);
String prefix = simpleInputFileName + ":" + ln + ":";
outputln(prefix + " " + msg.message);
outputln( String.format( "%s (%d:%d) %s", getSimpleInputFileName(), lineNumber(msg.where), off - i, msg.message));
outputln(new String(data, i, j - i));
char strdata[] = new char[(off - i) + 1];
@ -385,7 +383,7 @@ public class Environment {
msg = "Error: ";
}
msg = msg + errorString(err, arg1, arg2, arg3);
traceln("error(" + lineNumber(where) + ":" + lineOffset(where) + "):" + msg);
traceln(msg);
insertError(where, msg);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,11 +24,9 @@ package org.openjdk.asmtools.jasm;
import org.openjdk.asmtools.jasm.Tables.AttrTag;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* field_info
*/
class FieldData extends MemberData {
@ -55,7 +53,7 @@ class FieldData extends MemberData {
@Override
protected DataVector getAttrVector() {
return getDataVector(initValue, syntheticAttr, deprecatedAttr);
return getDataVector(initValue, syntheticAttr, deprecatedAttr, signatureAttr);
}
public void write(CheckedDataOutputStream out) throws IOException, Parser.CompilerError {

View File

@ -23,11 +23,8 @@
package org.openjdk.asmtools.jasm;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Optional;
import static org.openjdk.asmtools.jasm.JasmTokens.Token.ALL_TOKENS;
/**
*
* JasmTokens
@ -81,7 +78,9 @@ public class JasmTokens {
JASM (10, "Jasm"),
MISC (11, "Misc"),
JASM_IDENT (12, "Jasm identifier"),
MODULE_NAME (13, "Module Name");
MODULE_NAME (13, "Module Name"),
TYPE_PATH_KIND (14, "Type path kind") // Table 4.7.20.2-A Interpretation of type_path_kind values
;
private final Integer value;
private final String printval;
@ -95,11 +94,76 @@ public class JasmTokens {
}
}
/*-------------------------------------------------------- */
public enum AnnotationType {
Visible("@+"),
Invisible("@-"),
VisibleType("@T+"),
InvisibleType("@T-");
private final String jasmPrefix;
AnnotationType(String jasmPrefix) {
this.jasmPrefix = jasmPrefix;
}
/**
* isAnnotationToken
*
* examines the beginning of a string to see if it starts with an annotation
* characters ('@+' = visible annotation, '@-' = invisible).
*
* @param str String to be analyzed
* @return True if the string starts with an annotation char.
*/
static public boolean isAnnotationToken(String str) {
return (str.startsWith(AnnotationType.Invisible.jasmPrefix) ||
str.startsWith(AnnotationType.Visible.jasmPrefix));
}
/**
* isTypeAnnotationToken
*
* examines the beginning of a string to see if it starts with type annotation
* characters ('@T+' = visible type annotation, '@T-' = invisible).
*
* @param str String to be analyzed
* @return True if the string starts with an annotation char.
*/
static public boolean isTypeAnnotationToken(String str) {
return (str.startsWith(AnnotationType.InvisibleType.jasmPrefix) ||
str.startsWith(AnnotationType.VisibleType.jasmPrefix));
}
/**
* isAnnotation
*
* examines the beginning of a string to see if it starts with an annotation character
*
* @param str String to be analyzed
* @return True if the string starts with an annotation char.
*/
static public boolean isAnnotation(String str) {
return (str.startsWith("@"));
}
/**
* isInvisibleAnnotationToken
*
* examines the end of an annotation token to determine visibility ('+' = visible
* annotation, '-' = invisible).
*
* @param str String to be analyzed
* @return True if the token implies invisible annotation.
*/
static public boolean isInvisibleAnnotationToken(String str) {
return (str.endsWith("-"));
}
}
/**
* Scanner Tokens (Definitive List)
*/
static public enum Token {
public enum Token {
EOF (-1, "EOF", "EOF", EnumSet.of(TokenType.MISC)),
COMMA (0, "COMMA", ",", EnumSet.of(TokenType.OPERATOR)),
ASSIGN (1, "ASSIGN", "=", EnumSet.of(TokenType.OPERATOR)),
@ -290,9 +354,11 @@ public class JasmTokens {
CPINDEX (156, "CPINDEX", "CPINDEX", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
CPNAME (157, "CPNAME", "CPName", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
SIGN (158, "SIGN", "SIGN", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
BITS (159, "BITS", "bits", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
BITS (159, "BITS", "bits", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
INF (160, "INF", "Inf", "Infinity", EnumSet.of(TokenType.MISC, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
NAN (161, "NAN", "NaN", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
NAN (161, "NAN", "NaN", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
INNERCLASS (162, "INNERCLASS", "InnerClass", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
OF (163, "OF", "of", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
SYNTHETIC (164, "SYNTHETIC", "synthetic", EnumSet.of(TokenType.MODIFIER, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
@ -311,9 +377,10 @@ public class JasmTokens {
NESTHOST (173, "NESTHOST", "NestHost", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
NESTMEMBERS (174, "NESTMEMBERS", "NestMembers", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
//
RECORD (175, "RECORD", "Record", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
RECORD (175, "RECORD", "Record", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
COMPONENT (176, "COMPONENT", "Component", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
//
PERMITTEDSUBTYPES (176, "PERMITTEDSUBTYPES", "PermittedSubtypes", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
PERMITTEDSUBTYPES (177, "PERMITTEDSUBTYPES", "PermittedSubtypes", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
//Module statements
REQUIRES (180, "REQUIRES", "requires", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
@ -322,7 +389,17 @@ public class JasmTokens {
USES (184, "USES", "uses", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
PROVIDES (185, "PROVIDES", "provides", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
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);
OPENS (187, "OPENS", "opens", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
// Table 4.7.20.2-1 type_path_kind
ARRAY_TYPEPATH (188, TypeAnnotationTypes.EPathKind.ARRAY.parseKey(), TypeAnnotationTypes.EPathKind.ARRAY.parseKey(),
EnumSet.of(TokenType.TYPE_PATH_KIND, TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
INNER_TYPE_TYPEPATH (189, TypeAnnotationTypes.EPathKind.INNER_TYPE.parseKey(), TypeAnnotationTypes.EPathKind.INNER_TYPE.parseKey(),
EnumSet.of(TokenType.TYPE_PATH_KIND, TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
WILDCARD_TYPEPATH (190, TypeAnnotationTypes.EPathKind.WILDCARD.parseKey(), TypeAnnotationTypes.EPathKind.WILDCARD.parseKey(),
EnumSet.of(TokenType.TYPE_PATH_KIND, TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
TYPE_ARGUMENT_TYPEPATH (191, TypeAnnotationTypes.EPathKind.TYPE_ARGUMENT.parseKey(), TypeAnnotationTypes.EPathKind.TYPE_ARGUMENT.parseKey(),
EnumSet.of(TokenType.TYPE_PATH_KIND, TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD);
final static EnumSet<Token> ALL_TOKENS = EnumSet.allOf(Token.class);
// Misc Keywords
@ -334,36 +411,39 @@ public class JasmTokens {
final private KeywordType key_type; // KeywordType.KEYWORD
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();
return ALL_TOKENS.stream().
filter(t->t.key_type == ktype).
filter(t->t.parsekey.equals(parsekey) || ( t.alias != null && t.alias.equals(parsekey))).
findFirst();
}
// By default, if a KeywordType is not specified, it has the value 'TOKEN'
Token(Integer val, String print, String op, EnumSet<TokenType> ttype) {
this(val, print, op, null, ttype, KeywordType.TOKEN);
Token(Integer val, String print, String parsekey, EnumSet<TokenType> ttype) {
this(val, print, parsekey, null, ttype, KeywordType.TOKEN);
}
Token(Integer val, String print, String op, String als, EnumSet<TokenType> ttype) {
this(val, print, op, als, ttype, KeywordType.TOKEN);
Token(Integer val, String print, String parsekey, String als, EnumSet<TokenType> ttype) {
this(val, print, parsekey, als, ttype, KeywordType.TOKEN);
}
Token(Integer val, String print, String op, EnumSet<TokenType> ttype, KeywordType ktype) {
this(val, print, op, null, ttype, ktype);
Token(Integer val, String print, String parsekey, EnumSet<TokenType> ttype, KeywordType ktype) {
this(val, print, parsekey, null, ttype, ktype);
}
Token(Integer val, String print, String op, String als, EnumSet<TokenType> ttype, KeywordType ktype) {
Token(Integer val, String print, String parsekey, String als, EnumSet<TokenType> ttype, KeywordType ktype) {
this.value = val;
this.printval = print;
this.parsekey = op;
this.parsekey = parsekey;
this.tokenType = ttype;
this.key_type = ktype;
this.alias = als;
}
public String printval() {
public String printValue() {
return printval;
}
public String parsekey() {
public String parseKey() {
return parsekey;
}
@ -377,6 +457,13 @@ public class JasmTokens {
public boolean possibleModuleName() { return tokenType.contains(TokenType.MODULE_NAME) && !tokenType.contains(TokenType.PUNCTUATION); }
/**
* Checks a token belonging to the table: Table 4.7.20.2-A. Interpretation of type_path_kind values
*
* @return true if token is ARRAY, INNER_TYPE, WILDCARD or TYPE_ARGUMENT
*/
public boolean possibleTypePathKind() { return tokenType.contains(TokenType.TYPE_PATH_KIND); }
@Override
public String toString() {
return "<" + printval + "> [" + value + "]";

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -26,11 +26,9 @@ import static org.openjdk.asmtools.jasm.RuntimeConstants.DEPRECATED_ATTRIBUTE;
import static org.openjdk.asmtools.jasm.RuntimeConstants.SYNTHETIC_ATTRIBUTE;
import org.openjdk.asmtools.jasm.Tables.AttrTag;
import java.util.ArrayList;
import java.util.List;
/**
*
*
* The common base structure for field_info, method_info, and component_info
*/
abstract public class MemberData {
@ -41,6 +39,7 @@ abstract public class MemberData {
protected DataVectorAttr<TypeAnnotationData> type_annotAttrVis = null;
protected DataVectorAttr<TypeAnnotationData> type_annotAttrInv = null;
protected ClassData cls;
protected AttrData signatureAttr;
public MemberData(ClassData cls, int access) {
this.cls = cls;
@ -61,18 +60,19 @@ abstract public class MemberData {
// create the appropriate marker attributes,
// and clear the PseudoModifiers from the access flags.
if (Modifiers.isSyntheticPseudoMod(access)) {
syntheticAttr = new AttrData(cls,
AttrTag.ATT_Synthetic.parsekey());
syntheticAttr = new AttrData(cls, AttrTag.ATT_Synthetic.parsekey());
access &= ~SYNTHETIC_ATTRIBUTE;
}
if (Modifiers.isDeprecatedPseudoMod(access)) {
deprecatedAttr = new AttrData(cls,
AttrTag.ATT_Deprecated.parsekey());
deprecatedAttr = new AttrData(cls, AttrTag.ATT_Deprecated.parsekey());
access &= ~DEPRECATED_ATTRIBUTE;
}
}
public void setSignatureAttr(ConstantPool.ConstCell value_cpx) {
signatureAttr = new CPXAttr(cls, Tables.AttrTag.ATT_Signature.parsekey(), value_cpx);
}
protected abstract DataVector getAttrVector();
protected final DataVector getDataVector(Data... extraAttrs) {
@ -98,25 +98,24 @@ abstract public class MemberData {
return attrs;
}
public void addAnnotations(ArrayList<AnnotationData> annttns) {
for (AnnotationData annot : annttns) {
boolean invisible = annot.invisible;
if (annot instanceof TypeAnnotationData) {
public void addAnnotations(ArrayList<AnnotationData> list) {
for (AnnotationData item : list) {
boolean invisible = item.invisible;
if (item instanceof TypeAnnotationData) {
// Type Annotations
TypeAnnotationData tannot = (TypeAnnotationData) annot;
TypeAnnotationData ta = (TypeAnnotationData) item;
if (invisible) {
if (type_annotAttrInv == null) {
type_annotAttrInv = new DataVectorAttr(cls,
AttrTag.ATT_RuntimeInvisibleTypeAnnotations.parsekey());
}
type_annotAttrInv.add(tannot);
type_annotAttrInv.add(ta);
} else {
if (type_annotAttrVis == null) {
type_annotAttrVis = new DataVectorAttr(cls,
AttrTag.ATT_RuntimeVisibleTypeAnnotations.parsekey());
}
type_annotAttrVis.add(tannot);
type_annotAttrVis.add(ta);
}
} else {
// Regular Annotations
@ -124,16 +123,14 @@ abstract public class MemberData {
if (annotAttrInv == null) {
annotAttrInv = new DataVectorAttr(cls,
AttrTag.ATT_RuntimeInvisibleAnnotations.parsekey());
}
annotAttrInv.add(annot);
annotAttrInv.add(item);
} else {
if (annotAttrVis == null) {
annotAttrVis = new DataVectorAttr(cls,
AttrTag.ATT_RuntimeVisibleAnnotations.parsekey());
}
annotAttrVis.add(annot);
annotAttrVis.add(item);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,12 +22,6 @@
*/
package org.openjdk.asmtools.jasm;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static org.openjdk.asmtools.jasm.JasmTokens.Token;
import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
import static org.openjdk.asmtools.jasm.Tables.CF_Context;
@ -38,8 +32,6 @@ import static org.openjdk.asmtools.jasm.Tables.CF_Context;
*/
public class Modifiers {
private static Modifiers ref;
/*
* Modifier masks
*/
@ -377,71 +369,71 @@ public class Modifiers {
private static StringBuffer _accessString(int mod, CF_Context context) {
StringBuffer sb = new StringBuffer();
if (context == CF_Context.CTX_CLASS && isModule(mod)) {
sb.append(Token.MODULE.parsekey() + " ");
sb.append(Token.MODULE.parseKey() + " ");
}
if (isPublic(mod)) {
sb.append(Token.PUBLIC.parsekey() + " ");
sb.append(Token.PUBLIC.parseKey() + " ");
}
if (isPrivate(mod)) {
sb.append(Token.PRIVATE.parsekey() + " ");
sb.append(Token.PRIVATE.parseKey() + " ");
}
if (isProtected(mod)) {
sb.append(Token.PROTECTED.parsekey() + " ");
sb.append(Token.PROTECTED.parseKey() + " ");
}
if (isStatic(mod)) {
sb.append(Token.STATIC.parsekey() + " ");
sb.append(Token.STATIC.parseKey() + " ");
}
if (context == CF_Context.CTX_METHOD && isFinal(mod)) {
sb.append(Token.FINAL.parsekey() + " ");
sb.append(Token.FINAL.parseKey() + " ");
}
if (context == CF_Context.CTX_FIELD && isTransient(mod)) {
sb.append(Token.TRANSIENT.parsekey() + " ");
sb.append(Token.TRANSIENT.parseKey() + " ");
}
if (context == CF_Context.CTX_CLASS && isSuper(mod)) {
sb.append(Token.SUPER.parsekey() + " ");
sb.append(Token.SUPER.parseKey() + " ");
}
if (context == CF_Context.CTX_METHOD && isSynchronized(mod)) {
sb.append(Token.SYNCHRONIZED.parsekey() + " ");
sb.append(Token.SYNCHRONIZED.parseKey() + " ");
}
if (context == CF_Context.CTX_METHOD) {
if (isBridge(mod)) {
sb.append(Token.BRIDGE.parsekey() + " ");
sb.append(Token.BRIDGE.parseKey() + " ");
}
if (isVarArgs(mod)) {
sb.append(Token.VARARGS.parsekey() + " ");
sb.append(Token.VARARGS.parseKey() + " ");
}
if (isNative(mod)) {
sb.append(Token.NATIVE.parsekey() + " ");
sb.append(Token.NATIVE.parseKey() + " ");
}
}
if (isAbstract(mod)) {
if ((context != CF_Context.CTX_CLASS) || !isInterface(mod)) {
sb.append(Token.ABSTRACT.parsekey() + " ");
sb.append(Token.ABSTRACT.parseKey() + " ");
}
}
if ( context.isOneOf(CF_Context.CTX_CLASS, CF_Context.CTX_INNERCLASS, CF_Context.CTX_FIELD) && isFinal(mod)) {
sb.append(Token.FINAL.parsekey() + " ");
sb.append(Token.FINAL.parseKey() + " ");
}
if (context.isOneOf(CF_Context.CTX_CLASS, CF_Context.CTX_INNERCLASS) && isInterface(mod)) {
if (isAnnotation(mod)) {
sb.append(Token.ANNOTATION_ACCESS.parsekey() + " ");
sb.append(Token.ANNOTATION_ACCESS.parseKey() + " ");
}
sb.append(Token.INTERFACE.parsekey() + " ");
sb.append(Token.INTERFACE.parseKey() + " ");
}
if (isStrict(mod)) {
sb.append(Token.STRICT.parsekey() + " ");
sb.append(Token.STRICT.parseKey() + " ");
}
if (isSynthetic(mod)) {
sb.append(Token.SYNTHETIC.parsekey() + " ");
sb.append(Token.SYNTHETIC.parseKey() + " ");
}
if (context == CF_Context.CTX_FIELD && isVolatile(mod)) {
sb.append(Token.VOLATILE.parsekey() + " ");
sb.append(Token.VOLATILE.parseKey() + " ");
}
if (isEnum(mod)) {
sb.append(Token.ENUM.parsekey() + " ");
sb.append(Token.ENUM.parseKey() + " ");
}
if (context.isOneOf(CF_Context.CTX_METHOD, CF_Context.CTX_FIELD) && isMandated(mod)) {
sb.append(Token.MANDATED.parsekey() + " ");
sb.append(Token.MANDATED.parseKey() + " ");
}
return sb;

View File

@ -20,7 +20,6 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.asmtools.jasm;
import org.openjdk.asmtools.common.Module;
@ -34,6 +33,8 @@ import java.util.function.Consumer;
import static org.openjdk.asmtools.jasm.ConstantPool.*;
import static org.openjdk.asmtools.jasm.JasmTokens.Token;
import static org.openjdk.asmtools.jasm.JasmTokens.Token.COMMA;
import static org.openjdk.asmtools.jasm.JasmTokens.Token.SEMICOLON;
import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
import static org.openjdk.asmtools.jasm.Tables.*;
@ -73,7 +74,7 @@ class Parser extends ParseBase {
CodeAttr curCode;
private ArrayList clsDataList = new ArrayList<>();
private ArrayList<ClassData> clsDataList = new ArrayList<>();
private String pkg = null;
private String pkgPrefix = "";
private ArrayList<AnnotationData> pkgAnnttns = null;
@ -123,7 +124,7 @@ class Parser extends ParseBase {
*/
private void parseVersionPkg() throws IOException {
if (scanner.token == Token.SEMICOLON) {
if (scanner.token == SEMICOLON) {
return;
}
parse_ver:
@ -267,8 +268,8 @@ class Parser extends ParseBase {
tag = Tables.tag(sValue);
if (itemType != null) { // itemType OK
if ((tag != null) // ambiguity: "int," or "int 77,"?
&& (scanner.token != Token.SEMICOLON)
&& (scanner.token != Token.COMMA)) {
&& (scanner.token != SEMICOLON)
&& (scanner.token != COMMA)) {
itemType = StackMapType.ITEM_Object;
}
break resolve;
@ -279,7 +280,7 @@ class Parser extends ParseBase {
}
// resolution failed:
itemType = StackMapType.ITEM_Bogus;
env.error("itemtype.expected", "<" + ptoken.printval() + ">");
env.error("itemtype.expected", "<" + ptoken.printValue() + ">");
}
switch (itemType) {
case ITEM_Object: // followed by CP index
@ -316,6 +317,26 @@ class Parser extends ParseBase {
// In many cases, Identifiers can correctly have the same
// names as keywords. We need to allow these.
case OPEN:
case MODULE:
case VARARGS:
case REQUIRES:
case EXPORTS:
case TO:
case USES:
case PROVIDES:
case WITH:
case OPENS:
case ARRAY_TYPEPATH:
case INNER_TYPE_TYPEPATH:
case WILDCARD_TYPEPATH:
case TYPE_ARGUMENT_TYPEPATH:
case PERMITTEDSUBTYPES:
case INF:
case NAN:
case COMPONENT:
case SYNTHETIC:
case DEPRECATED:
case VERSION:
@ -323,7 +344,6 @@ class Parser extends ParseBase {
case STACK:
case LOCAL:
case OF:
case NAN:
case INNERCLASS:
case STRICT:
case FIELDREF:
@ -345,12 +365,21 @@ class Parser extends ParseBase {
ConstCell parseMethodHandle(SubTag subtag) throws Scanner.SyntaxError, IOException {
ConstCell refCell;
switch (subtag) {
// If the value of the reference_kind item is
// 1 (REF_getField), 2 (REF_getStatic), 3 (REF_putField) or 4 (REF_putStatic),
// then the constant_pool entry at that index must be a CONSTANT_Fieldref_info structure (§4.4.2)
// representing a field for which a method handle is to be created. jvms-4.4.8-200-C-A
case REF_GETFIELD:
case REF_GETSTATIC:
case REF_PUTFIELD:
case REF_PUTSTATIC:
refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_FIELD));
break;
// If the value of the reference_kind item is
// 5 (REF_invokeVirtual) or 8 (REF_newInvokeSpecial),
// then the constant_pool entry at that index must be a CONSTANT_Methodref_info structure (§4.4.2)
// representing a class's method or constructor (§2.9.1) for which a method handle is to be created.
// jvms-4.4.8-200-C-B
case REF_INVOKEVIRTUAL:
case REF_NEWINVOKESPECIAL:
refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_METHOD));
@ -368,11 +397,13 @@ class Parser extends ParseBase {
// if the class file version number is 52.0 or above, the constant_pool entry at that index must be
// either a CONSTANT_Methodref_info structure or a CONSTANT_InterfaceMethodref_info structure (§4.4.2)
// representing a class's or interface's method for which a method handle is to be created.
ConstType ctype = ConstType.CONSTANT_METHOD;
ConstType ctype01 = ConstType.CONSTANT_METHOD;
ConstType ctype02 = ConstType.CONSTANT_INTERFACEMETHOD;
if (this.cd.cfv.major_version() >= 52 && Modifiers.isInterface(this.cd.access)) {
ctype = ConstType.CONSTANT_INTERFACEMETHOD;
ctype01 = ConstType.CONSTANT_INTERFACEMETHOD;
ctype02 = ConstType.CONSTANT_METHOD;
}
refCell = pool.FindCell(cpParser.parseConstValue(ctype));
refCell = cpParser.parseConstRef(ctype01, ctype02);
break;
case REF_INVOKEINTERFACE:
refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_INTERFACEMETHOD));
@ -420,6 +451,26 @@ class Parser extends ParseBase {
return pool.FindCellAsciz(v);
// Some identifiers might coincide with token names.
// these should be OK to use as identifier names.
case OPEN:
case MODULE:
case VARARGS:
case REQUIRES:
case EXPORTS:
case TO:
case USES:
case PROVIDES:
case WITH:
case OPENS:
case ARRAY_TYPEPATH:
case INNER_TYPE_TYPEPATH:
case WILDCARD_TYPEPATH:
case TYPE_ARGUMENT_TYPEPATH:
case PERMITTEDSUBTYPES:
case INF:
case NAN:
case COMPONENT:
case SYNTHETIC:
case DEPRECATED:
case VERSION:
@ -427,7 +478,6 @@ class Parser extends ParseBase {
case STACK:
case LOCAL:
case OF:
case NAN:
case INNERCLASS:
case STRICT:
case FIELDREF:
@ -441,7 +491,7 @@ class Parser extends ParseBase {
default:
ConstType key = Tables.tag(scanner.token.value());
env.traceln("%%%%% Unrecognized token [" + scanner.token + "]: '" + (key == null ? "null" : key.parseKey()) + "'.");
env.error(scanner.prevPos, "name.expected", "\"" + scanner.token.parsekey() + "\"");
env.error(scanner.prevPos, "name.expected", "\"" + scanner.token.parseKey() + "\"");
throw new Scanner.SyntaxError();
}
}
@ -544,8 +594,8 @@ class Parser extends ParseBase {
env.error("const.def.expected");
throw new Scanner.SyntaxError();
}
if (scanner.token != Token.COMMA) {
scanner.expect(Token.SEMICOLON);
if (scanner.token != COMMA) {
scanner.expect(SEMICOLON);
return;
}
scanner.scan(); // COMMA
@ -666,6 +716,13 @@ class Parser extends ParseBase {
fld.addAnnotations(memberAnnttns);
}
// Parse the optional attribute: signature
if (scanner.token == Token.COLON) {
scanner.scan();
ConstCell signatureCell = parseName();
fld.setSignatureAttr(signatureCell);
}
// Parse the optional initializer
if (scanner.token == Token.ASSIGN) {
scanner.scan();
@ -675,8 +732,8 @@ class Parser extends ParseBase {
// If the next scanner.token is a comma, then there is more
debugScan(" [Parser.parseField]: Field: " + fld + " ");
if (scanner.token != Token.COMMA) {
scanner.expect(Token.SEMICOLON);
if (scanner.token != COMMA) {
scanner.expect(SEMICOLON);
return;
}
scanner.scan();
@ -799,7 +856,7 @@ class Parser extends ParseBase {
exc_table.add(exc);
env.traceln("THROWS:" + exc.arg);
}
if (scanner.token != Token.COMMA) {
if (scanner.token != COMMA) {
break;
}
scanner.scan();
@ -825,7 +882,7 @@ class Parser extends ParseBase {
annotParser.parseParamAnnots(paramcnt, curMethod);
}
if (scanner.token == Token.SEMICOLON) {
if (scanner.token == SEMICOLON) {
if ((max_stack != null) || (max_locals != null)) {
env.error("token.expected", "{");
}
@ -838,9 +895,13 @@ class Parser extends ParseBase {
if (scanner.token == Token.RBRACE) {
break;
}
scanner.expect(Token.SEMICOLON);
// code's type annotation(s)
if (scanner.token == Token.ANNOTATION) {
curCode.addAnnotations(annotParser.scanAnnotations());
break;
}
scanner.expect(SEMICOLON);
}
curCode.endCode();
scanner.expect(Token.RBRACE);
}
@ -869,7 +930,7 @@ class Parser extends ParseBase {
scanner.scan();
ArrayList<ConstCell> bsm_args = new ArrayList<>(256);
while (scanner.token != Token.SEMICOLON) {
while (scanner.token != SEMICOLON) {
if (scanner.token == Token.CPINDEX) {
bsm_args.add(pool.getCell(scanner.intValue));
@ -899,7 +960,7 @@ class Parser extends ParseBase {
String className = prependPackage(parseIdent(), true);
ConstCell hostClass = pool.FindCellClassByName(className);
debugScan(" [Parser.parseNestHost]: NestHost: class " + className);
scanner.expect(Token.SEMICOLON);
scanner.expect(SEMICOLON);
cd.addNestHost(hostClass);
}
@ -916,8 +977,8 @@ class Parser extends ParseBase {
String className = prependPackage(parseIdent(), true);
classes.add(pool.FindCellClassByName(className));
debugScan(" [Parser.parseClasses]: class " + className);
if (scanner.token != Token.COMMA) {
scanner.expect(Token.SEMICOLON);
if (scanner.token != COMMA) {
scanner.expect(SEMICOLON);
classesConsumer.accept(classes);
return;
}
@ -930,40 +991,67 @@ class Parser extends ParseBase {
*/
private void parseRecord() throws Scanner.SyntaxError, IOException {
// Parses in the form:
// RECORD COMPONENT (, COMPONENT)*;
// RECORD { (COMPONENT)+ }
// where
// COMPONENT NAME:DESCRIPTOR SIGNATURE? (ANNOTATION)*
// COMPONENT Component (ANNOTATION)* NAME:DESCRIPTOR(:SIGNATURE)? (,|;)
// NAME = (CPINDEX | IDENT)
// DESCRIPTOR = (CPINDEX | STRING)
// SIGNATURE = (CPINDEX | STRING)
debugScan("[Parser.parseRecord]: Begin ");
debugScan("[Parser.parseRecord]: Begin");
scanner.expect(Token.LBRACE);
ArrayList<AnnotationData> componentAnntts = null;
boolean grouped = false;
RecordData rd = cd.setRecord(scanner.pos);
Component:
while (true) {
if (scanner.token == Token.RBRACE) {
if (rd.isEmpty()) {
env.error(scanner.pos, "warn.no.components.in.record.attribute");
cd.rejectRecord();
} else if (grouped) {
env.error(scanner.pos, "grouped.component.expected");
}
scanner.scan();
break;
}
ConstCell nameCell, descCell, signatureCell = null;
if (scanner.token == Token.ANNOTATION) {
componentAnntts = annotParser.scanAnnotations();
}
scanner.expect(Token.COMPONENT);
nameCell = parseName();
scanner.expect(Token.COLON);
descCell = parseName();
rd.addComponent(nameCell, descCell);
while (true) {
switch (scanner.token) {
case COMMA:
scanner.scan();
continue Component; // next component
case SEMICOLON:
return; // EOR
case ANNOTATION:
rd.setAnnotations(annotParser.scanAnnotations());
break;
default:
if (signatureCell != null) {
env.error(scanner.pos, "warn.signature.repeated");
}
signatureCell = parseName();
rd.setComponentSignature(signatureCell);
}
// Parse the optional attribute: signature
if (scanner.token == Token.COLON) {
scanner.scan();
signatureCell = parseName();
}
rd.addComponent(nameCell, descCell, signatureCell, componentAnntts);
switch (scanner.token) {
case COMMA:
grouped = true;
break;
case SEMICOLON:
grouped = false;
componentAnntts = null;
break;
default:
env.error(scanner.pos, "one.of.two.token.expected",
"<" + SEMICOLON.printValue() + ">",
"<" + COMMA.printValue() + ">");
break;
}
// next component
scanner.scan();
} // end while
debugScan("[Parser.parseRecord]: End");
}
/**
@ -1046,7 +1134,7 @@ class Parser extends ParseBase {
}
// See if declaration is terminated
if (scanner.token == Token.SEMICOLON) {
if (scanner.token == SEMICOLON) {
// InnerClass is complete, no OUTERINFO;
outerClass = pool.getCell(0);
pic_tracecreate(mod, nameCell, innerClass, outerClass);
@ -1076,7 +1164,7 @@ class Parser extends ParseBase {
outerClass = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
}
if (scanner.token == Token.SEMICOLON) {
if (scanner.token == SEMICOLON) {
pic_tracecreate(mod, nameCell, innerClass, outerClass);
cd.addInnerClass(mod, nameCell, innerClass, outerClass);
} else {
@ -1250,7 +1338,7 @@ class Parser extends ParseBase {
mod |= ACC_ANNOTATION | ACC_INTERFACE;
scanner.scan();
} else {
env.error(scanner.prevPos, "token.expected", Token.ANNOTATION.parsekey() + Token.INTERFACE.parsekey());
env.error(scanner.prevPos, "token.expected", Token.ANNOTATION.parseKey() + Token.INTERFACE.parseKey());
throw new Scanner.SyntaxError();
}
}
@ -1275,9 +1363,9 @@ class Parser extends ParseBase {
scanner.scan();
cd.fileExtension = "." + fileExtension;
} else if (scanner.token == Token.MODULE) {
env.error(scanner.prevPos, "token.expected", Token.OPEN.parsekey());
env.error(scanner.prevPos, "token.expected", Token.OPEN.parseKey());
throw new Scanner.SyntaxError();
} else if (scanner.token == Token.SEMICOLON) {
} else if (scanner.token == SEMICOLON) {
// drop the semi-colon following a name
scanner.scan();
}
@ -1287,7 +1375,7 @@ class Parser extends ParseBase {
if (scanner.token == Token.EXTENDS) {
scanner.scan();
sup = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
while (scanner.token == Token.COMMA) {
while (scanner.token == COMMA) {
scanner.scan();
env.error(posa, "multiple.inherit");
cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
@ -1305,7 +1393,7 @@ class Parser extends ParseBase {
} else {
impl.add(intf);
}
} while (scanner.token == Token.COMMA);
} while (scanner.token == COMMA);
}
parseVersion();
scanner.expect(Token.LBRACE);
@ -1346,7 +1434,7 @@ class Parser extends ParseBase {
name = name + field + scanner.idValue;
scanner.scan();
} else {
env.error(scanner.pos, "name.expected", "\"" + scanner.token.parsekey() + "\"");
env.error(scanner.pos, "name.expected", "\"" + scanner.token.parseKey() + "\"");
throw new Scanner.SyntaxError();
}
if (scanner.token == Token.FIELD) {
@ -1370,7 +1458,7 @@ class Parser extends ParseBase {
name = name + field + scanner.idValue;
scanner.scanModuleStatement();
} else {
env.error(scanner.pos, "module.name.expected", "\"" + scanner.token.parsekey() + "\"");
env.error(scanner.pos, "module.name.expected", "\"" + scanner.token.parseKey() + "\"");
throw new Scanner.SyntaxError().Fatal();
}
if (scanner.token == Token.FIELD) {
@ -1407,7 +1495,7 @@ class Parser extends ParseBase {
scanner.scanModuleStatement();
// scanner.scan();
} else {
env.error(scanner.pos, "token.expected", Token.MODULE.parsekey());
env.error(scanner.pos, "token.expected", Token.MODULE.parseKey());
throw new Scanner.SyntaxError().Fatal();
}
// Parse the module name
@ -1476,7 +1564,7 @@ class Parser extends ParseBase {
int flags = 0;
String mn = "";
scanner.scanModuleStatement();
while (scanner.token != Token.SEMICOLON) {
while (scanner.token != SEMICOLON) {
switch (scanner.token) {
case STATIC:
if (((flags & (1 << Module.Modifier.ACC_STATIC_PHASE.asInt())) != 0) || !mn.isEmpty()) {
@ -1548,7 +1636,7 @@ class Parser extends ParseBase {
String typeName = "";
HashSet<String> names = new HashSet<>();
scanner.scan();
while (scanner.token != Token.SEMICOLON) {
while (scanner.token != SEMICOLON) {
if (scanner.token == Token.IDENT) {
if (typeName.isEmpty()) {
typeName = source.get();
@ -1589,7 +1677,7 @@ class Parser extends ParseBase {
HashSet<String> names = new HashSet<>();
boolean comma = false, first = true;
scanMethod.call();
while (scanner.token != Token.SEMICOLON) {
while (scanner.token != SEMICOLON) {
switch (scanner.token) {
case COMMA:
if (comma || first || onlyOneElement) {
@ -1788,7 +1876,7 @@ class Parser extends ParseBase {
int where = scanner.pos;
String id = parseIdent();
parseVersionPkg();
scanner.expect(Token.SEMICOLON);
scanner.expect(SEMICOLON);
if (pkg == null) {
pkg = id;
@ -1802,7 +1890,7 @@ class Parser extends ParseBase {
recoverFile();
}
// skip bogus semi colons
while (scanner.token == Token.SEMICOLON) {
while (scanner.token == SEMICOLON) {
scanner.scan();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,7 +22,10 @@
*/
package org.openjdk.asmtools.jasm;
import static org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
import org.openjdk.asmtools.jasm.TypeAnnotationTargetInfoData.*;
import static org.openjdk.asmtools.jasm.JasmTokens.AnnotationType.isInvisibleAnnotationToken;
import static org.openjdk.asmtools.jasm.TypeAnnotationTypes.*;
import static org.openjdk.asmtools.jasm.JasmTokens.*;
import static org.openjdk.asmtools.jasm.ConstantPool.*;
import static org.openjdk.asmtools.jasm.Tables.*;
@ -50,7 +53,7 @@ public class ParserAnnotation extends ParseBase {
*
* Used to store Annotation values
*/
class AnnotationElemValue implements Data {
static class AnnotationElemValue implements Data {
AnnotationData annotation;
@ -185,21 +188,11 @@ public class ParserAnnotation extends ParseBase {
}
}
/*-------------------------------------------------------- */
/* Annotation Parser Fields */
/**
* local handles on the scanner, main parser, and the error reporting env
*/
private static TTVis ttVisitor;
/*-------------------------------------------------------- */
/**
* main constructor
*
* @param scanner
* @param parser
* @param env
*/
protected ParserAnnotation(Scanner scanner, Parser parser, Environment env) {
super.init(scanner, parser, env);
ttVisitor = new TTVis();
@ -249,76 +242,23 @@ public class ParserAnnotation extends ParseBase {
* @throws IOException
*/
ArrayList<AnnotationData> scanAnnotations() throws IOException {
ArrayList<AnnotationData> annttns = new ArrayList<>();
ArrayList<AnnotationData> list = new ArrayList<>();
while (scanner.token == Token.ANNOTATION) {
if (isAnnotationToken(scanner.stringValue)) {
annttns.add(parseAnnotation());
} else if (isTypeAnnotationToken(scanner.stringValue)) {
annttns.add(parseTypeAnnotation());
if ( JasmTokens.AnnotationType.isAnnotationToken(scanner.stringValue)) {
list.add(parseAnnotation());
} else if (JasmTokens.AnnotationType.isTypeAnnotationToken(scanner.stringValue)) {
list.add(parseTypeAnnotation());
} else {
return null;
}
}
if (annttns.size() > 0) {
return annttns;
if (list.size() > 0) {
return list;
} else {
return null;
}
}
/**
* isAnnotation
*
* examines the beginning of a string to see if it starts with an annotation character
*
* @param str
* @return True if the string starts with an annotation char.
*/
protected boolean isAnnotation(String str) {
return (str.startsWith("@"));
}
/**
* isAnnotationToken
*
* examines the beginning of a string to see if it starts with an annotation
* characters ('@+' = visible annotation, '@-' = invisible).
*
* @param str
* @return True if the string starts with an annotation char.
*/
protected boolean isAnnotationToken(String str) {
return (str.startsWith("@+") || str.startsWith("@-"));
}
/**
* isTypeAnnotationToken
*
* examines the beginning of a string to see if it starts with type annotation
* characters ('@T+' = visible type annotation, '@T-' = invisible).
*
* @param str
* @return True if the string starts with an annotation char.
*/
protected boolean isTypeAnnotationToken(String str) {
return (str.startsWith("@T+") || str.startsWith("@T-"));
}
/**
* isInvisibleAnnotToken
*
* examines the end of an annotation token to determine visibility ('+' = visible
* annotation, '-' = invisible).
*
* @param str
* @return True if the token implies invisible annotation.
*/
protected boolean isInvisibleAnnotToken(String str) {
return (str.endsWith("-"));
}
/**
* parseDefaultAnnotation
*
@ -412,7 +352,7 @@ public class ParserAnnotation extends ParseBase {
* @throws IOException
*/
private AnnotationData parseTypeAnnotation() throws Scanner.SyntaxError, IOException {
boolean invisible = isInvisibleAnnotToken(scanner.stringValue);
boolean invisible = isInvisibleAnnotationToken(scanner.stringValue);
scanner.scan();
debugScan(" [ParserAnnotation.parseTypeAnnotation]: id = " + scanner.stringValue + " ");
String annoName = "L" + scanner.stringValue + ";";
@ -425,11 +365,13 @@ public class ParserAnnotation extends ParseBase {
// Scan the usual annotation data
_scanAnnotation(anno);
// scan the Target
// scan the Target (u1: target_type, union{...}: target_info)
_scanTypeTarget(anno);
// scan the Location
_scanTargetPath(anno);
if( scanner.token != Token.RBRACE ) {
// scan the Location (type_path: target_path)
_scanTargetPath(anno);
}
scanner.expect(Token.RBRACE);
return anno;
@ -445,7 +387,7 @@ public class ParserAnnotation extends ParseBase {
*/
private AnnotationData parseAnnotation() throws Scanner.SyntaxError, IOException {
debugScan(" - - - > [ParserAnnotation.parseAnnotation]: Begin ");
boolean invisible = isInvisibleAnnotToken(scanner.stringValue);
boolean invisible = isInvisibleAnnotationToken(scanner.stringValue);
scanner.scan();
String annoName = "L" + scanner.stringValue + ";";
@ -478,7 +420,7 @@ public class ParserAnnotation extends ParseBase {
throw new Scanner.SyntaxError();
}
String name = ((ConstValue_String) cellref)._toString();
debugScan(" - - - > [ParserAnnotation._scanAnnotation]: Annot - Field Name: " + name);
debugScan(" [ParserAnnotation._scanAnnotation]: Annot - Field Name: " + name);
Data data = scanAnnotationData(name);
annotData.add(new AnnotationData.ElemValuePair(nameCell, data));
@ -505,21 +447,21 @@ public class ParserAnnotation extends ParseBase {
//Scan the target_type and the target_info
scanner.expect(Token.IDENT);
debugScan(" [ParserAnnotation._scanTypeTarget]: TargetType: " + scanner.idValue);
TypeAnnotationUtils.TargetType tt = TypeAnnotationUtils.getTargetType(scanner.idValue);
if (tt == null) {
ETargetType targetType = ETargetType.getTargetType(scanner.idValue);
if (targetType == null) {
env.error(scanner.pos, "incorrect.typeannot.target", scanner.idValue);
throw new Scanner.SyntaxError();
}
debugScan(" [ParserAnnotation._scanTypeTarget]: Got TargetType: " + tt);
debugScan(" [ParserAnnotation._scanTypeTarget]: Got TargetType: " + targetType);
if (ttVisitor.scanner == null) {
ttVisitor.scanner = scanner;
}
ttVisitor.visitExcept(tt);
ttVisitor.visitExcept(targetType);
annotData.targetInfo = ttVisitor.getTargetInfo();
annotData.targetType = tt;
annotData.targetType = targetType;
debugScan(" [ParserAnnotation._scanTypeTarget]: Got TargetInfo: " + annotData.targetInfo);
scanner.expect(Token.RBRACE);
@ -531,9 +473,9 @@ public class ParserAnnotation extends ParseBase {
* Target Type visitor, used for constructing the target-info within a type
* annotation. visitExcept() is the entry point. ti is the constructed target info.
*/
private static class TTVis extends TypeAnnotationUtils.TypeAnnotationTargetVisitor {
private static class TTVis extends TypeAnnotationTypes.TypeAnnotationTargetVisitor {
private TypeAnnotationUtils.TargetInfo ti;
private TypeAnnotationTargetInfoData ti;
private IOException IOProb;
private Scanner.SyntaxError SyProb;
private Scanner scanner;
@ -560,7 +502,7 @@ public class ParserAnnotation extends ParseBase {
}
//This is the entry point for a visitor that tunnels exceptions
public void visitExcept(TypeAnnotationUtils.TargetType tt) throws IOException, Scanner.SyntaxError {
public void visitExcept(ETargetType tt) throws IOException, Scanner.SyntaxError {
IOProb = null;
SyProb = null;
ti = null;
@ -576,13 +518,13 @@ public class ParserAnnotation extends ParseBase {
}
}
public TypeAnnotationUtils.TargetInfo getTargetInfo() {
public TypeAnnotationTargetInfoData getTargetInfo() {
return ti;
}
// this fn gathers intvals, and tunnels any exceptions thrown by
// the scanner
private int scanIntVal(TypeAnnotationUtils.TargetType tt) {
private int scanIntVal(ETargetType tt) {
int ret = -1;
if (scanner.token == Token.INTVAL) {
ret = scanner.intValue;
@ -602,7 +544,7 @@ public class ParserAnnotation extends ParseBase {
// this fn gathers intvals, and tunnels any exceptions thrown by
// the scanner
private String scanStringVal(TypeAnnotationUtils.TargetType tt) {
private String scanStringVal(ETargetType tt) {
String ret = "";
if (scanner.token == Token.STRINGVAL) {
ret = scanner.stringValue;
@ -637,25 +579,25 @@ public class ParserAnnotation extends ParseBase {
}
@Override
public void visit_type_param_target(TypeAnnotationUtils.TargetType tt) {
public void visit_type_param_target(ETargetType tt) {
env.traceln("Type Param Target: ");
int byteval = scanIntVal(tt); // param index
if (!error()) {
ti = new TypeAnnotationUtils.typeparam_target(tt, byteval);
ti = new TypeAnnotationTargetInfoData.type_parameter_target(tt, byteval);
}
}
@Override
public void visit_supertype_target(TypeAnnotationUtils.TargetType tt) {
public void visit_supertype_target(ETargetType tt) {
env.traceln("SuperType Target: ");
int shortval = scanIntVal(tt); // type index
if (!error()) {
ti = new TypeAnnotationUtils.supertype_target(tt, shortval);
ti = new TypeAnnotationTargetInfoData.supertype_target(tt, shortval);
}
}
@Override
public void visit_typeparam_bound_target(TypeAnnotationUtils.TargetType tt) {
public void visit_typeparam_bound_target(ETargetType tt) {
env.traceln("TypeParam Bound Target: ");
int byteval1 = scanIntVal(tt); // param index
if (error()) {
@ -665,39 +607,39 @@ public class ParserAnnotation extends ParseBase {
if (error()) {
return;
}
ti = new TypeAnnotationUtils.typeparam_bound_target(tt, byteval1, byteval2);
ti = new TypeAnnotationTargetInfoData.type_parameter_bound_target(tt, byteval1, byteval2);
}
@Override
public void visit_empty_target(TypeAnnotationUtils.TargetType tt) {
public void visit_empty_target(ETargetType tt) {
env.traceln("Empty Target: ");
if (!error()) {
ti = new TypeAnnotationUtils.empty_target(tt);
ti = new TypeAnnotationTargetInfoData.empty_target(tt);
}
}
@Override
public void visit_methodformalparam_target(TypeAnnotationUtils.TargetType tt) {
public void visit_methodformalparam_target(ETargetType tt) {
env.traceln("MethodParam Target: ");
int byteval = scanIntVal(tt); // param index
if (!error()) {
ti = new TypeAnnotationUtils.methodformalparam_target(tt, byteval);
ti = new formal_parameter_target(tt, byteval);
}
}
@Override
public void visit_throws_target(TypeAnnotationUtils.TargetType tt) {
public void visit_throws_target(ETargetType tt) {
env.traceln("Throws Target: ");
int shortval = scanIntVal(tt); // exception index
if (!error()) {
ti = new TypeAnnotationUtils.throws_target(tt, shortval);
ti = new throws_target(tt, shortval);
}
}
@Override
public void visit_localvar_target(TypeAnnotationUtils.TargetType tt) {
public void visit_localvar_target(ETargetType tt) {
env.traceln("LocalVar Target: ");
TypeAnnotationUtils.localvar_target locvartab = new TypeAnnotationUtils.localvar_target(tt, 0);
localvar_target locvartab = new localvar_target(tt, 0);
ti = locvartab;
while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
@ -725,24 +667,24 @@ public class ParserAnnotation extends ParseBase {
}
@Override
public void visit_catch_target(TypeAnnotationUtils.TargetType tt) {
public void visit_catch_target(ETargetType tt) {
env.traceln("Catch Target: ");
int shortval = scanIntVal(tt); // catch index
ti = new TypeAnnotationUtils.catch_target(tt, shortval);
ti = new catch_target(tt, shortval);
}
@Override
public void visit_offset_target(TypeAnnotationUtils.TargetType tt) {
public void visit_offset_target(ETargetType tt) {
env.traceln("Offset Target: ");
int shortval = scanIntVal(tt); // offset index
if (!error()) {
ti = new TypeAnnotationUtils.offset_target(tt, shortval);
ti = new offset_target(tt, shortval);
}
}
@Override
public void visit_typearg_target(TypeAnnotationUtils.TargetType tt) {
public void visit_typearg_target(ETargetType tt) {
env.traceln("TypeArg Target: ");
int shortval = scanIntVal(tt); // offset
if (error()) {
@ -752,75 +694,77 @@ public class ParserAnnotation extends ParseBase {
if (error()) {
return;
}
ti = new TypeAnnotationUtils.typearg_target(tt, shortval, byteval);
ti = new type_argument_target(tt, shortval, byteval);
}
}
/**
* _scanTypeLocation
* _scanTargetPath
*
* parses an individual annotation-data.
* parses and fills the type_path structure (4.7.20.2)
*
* @return a parsed annotation.
* @throws IOException
* type_path {
* u1 path_length;
* { u1 type_path_kind;
* u1 type_argument_index;
* } path[path_length];
* }
*
* @throws Scanner.SyntaxError, IOException
*/
private void _scanTargetPath(TypeAnnotationData annotData) throws Scanner.SyntaxError, IOException {
ArrayList<TypePathEntry> targPath = new ArrayList<>();
// parse the location info
scanner.expect(Token.LBRACE);
while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
TypePathEntry tpe = _scanTypePathEntry();
scanner.scan();
annotData.addTypePathEntry(tpe);
// throw away comma
if (scanner.token == Token.COMMA) {
scanner.scan();
}
}
scanner.expect(Token.RBRACE);
annotData.targetPath = targPath;
}
/**
* _scanTypeLocation
*
* parses an individual annotation-data.
* parses a path entry of the type_path.
*
* @return a parsed annotation.
* @throws IOException
* { u1 type_path_kind;
* u1 type_argument_index;
* }
*
* @return a parsed type path.
* @throws Scanner.SyntaxError, IOException
*/
private TypePathEntry _scanTypePathEntry() throws Scanner.SyntaxError, IOException {
TypePathEntry tpe;
if ((scanner.token != Token.EOF) && (scanner.token == Token.STRINGVAL)) {
String pathEntryKey = scanner.stringValue;
PathKind pk = pathKind(pathEntryKey);
if (pk == null) {
// unexpected Type Path
env.error(scanner.pos, "incorrect.typeannot.pathentry", scanner.stringValue);
throw new Scanner.SyntaxError();
}
if (pk == PathKind.ITHARG_PARAMETERTYPE) {
//
if ( (scanner.token != Token.EOF) && scanner.token.possibleTypePathKind() ) {
EPathKind pathKind = EPathKind.getPathKind(scanner.stringValue);
if (pathKind == EPathKind.TYPE_ARGUMENT) {
scanner.scan();
// need to scan the index
// Take the form: INNER_TYPE(#)
scanner.expect(Token.LPAREN);
// Take the form: TYPE_ARGUMENT{#}
scanner.expect(Token.LBRACE);
int index = 0;
if ((scanner.token != Token.EOF) && (scanner.token == Token.INTVAL)) {
index = scanner.intValue;
scanner.scan();
} else {
// incorrect Arg index
env.error(scanner.pos, "incorrect.typeannot.pathentry.argindex", scanner.token);
throw new Scanner.SyntaxError();
}
scanner.expect(Token.RPAREN);
tpe = new TypePathEntry(pk.key(), (char) index);
tpe = new TypePathEntry(pathKind, index);
scanner.expect(Token.RBRACE);
} else {
tpe = new TypePathEntry(pk.key(), (char) 0);
tpe = new TypePathEntry(pathKind, 0);
scanner.scan();
}
} else {
// unexpected Type Path
@ -1136,7 +1080,6 @@ public class ParserAnnotation extends ParseBase {
env.error(scanner.pos, "incorrect.annot.keyword", ident);
throw new Scanner.SyntaxError();
}
return data;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -565,7 +565,7 @@ d2l: {
break;
default:
// problem - no constant value
System.err.println("NEAR: " + scanner.token.printval());
System.err.println("NEAR: " + scanner.token.printValue());
env.error(scanner.pos, "value.expected");
throw new Scanner.SyntaxError();
}

View File

@ -26,6 +26,7 @@ import static org.openjdk.asmtools.jasm.JasmTokens.*;
import static org.openjdk.asmtools.jasm.Tables.*;
import static org.openjdk.asmtools.jasm.OpcodeTables.*;
import java.io.IOException;
import java.lang.reflect.Modifier;
/**
* ParserInstr
@ -88,7 +89,7 @@ public class ParserInstr extends ParseBase {
Opcode opcode = OpcodeTables.opcode(mnemocode);
if (opcode == null) {
debugScan(" %%error%%error%%% $$$$$$$$$$$$$$$ mnemocode = '" + mnemocode + "'. ");
debugScan(" Error: mnemocode = '" + mnemocode + "'. ");
}
OpcodeType optype = opcode.type();
@ -267,7 +268,13 @@ public class ParserInstr extends ParseBase {
break;
case opc_invokestatic:
case opc_invokespecial:
arg = cpParser.parseConstRef(ConstType.CONSTANT_METHOD, ConstType.CONSTANT_INTERFACEMETHOD);
ConstType ctype01 = ConstType.CONSTANT_METHOD;
ConstType ctype02 = ConstType.CONSTANT_INTERFACEMETHOD;
if(Modifier.isInterface(this.parser.cd.access)) {
ctype01 = ConstType.CONSTANT_INTERFACEMETHOD;
ctype02 = ConstType.CONSTANT_METHOD;
}
arg = cpParser.parseConstRef(ctype01, ctype02);
break;
case opc_jsr:
case opc_goto:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
@ -33,26 +33,29 @@ import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
*/
public class RecordData extends AttrData {
private List<ComponentData> components = new ArrayList<>();
private ComponentData currentComp = null;
/* Record Data Fields */
public RecordData(ClassData cls) {
super(cls, Tables.AttrTag.ATT_Record.parsekey());
}
public void addComponent(ConstantPool.ConstCell nameCell, ConstantPool.ConstCell descCell) {
public void addComponent(ConstantPool.ConstCell nameCell,
ConstantPool.ConstCell descCell,
ConstantPool.ConstCell signature,
ArrayList<AnnotationData> annotations) {
// Define a field if absent
FieldData fd = getClassData().addFieldIfAbsent(ACC_MANDATED & ACC_PRIVATE & ACC_FINAL, nameCell, descCell);
currentComp = new ComponentData(fd);
components.add(currentComp);
ComponentData cd = new ComponentData(fd);
if( annotations != null ) {
cd.addAnnotations(annotations);
}
if( signature != null ) {
cd.setSignatureAttr(signature);
}
components.add(cd);
}
public void setComponentSignature(ConstantPool.ConstCell signature) {
currentComp.setSignature(signature);
}
public void setAnnotations(ArrayList<AnnotationData> annotations) {
currentComp.addAnnotations(annotations);
public boolean isEmpty() {
return components.isEmpty();
}
@Override
@ -72,20 +75,15 @@ public class RecordData extends AttrData {
class ComponentData extends MemberData {
private FieldData field;
private AttrData signature;
public ComponentData(FieldData field) {
super(getClassData());
this.field = field;
}
public void setSignature(ConstantPool.ConstCell value_cpx) {
signature = new CPXAttr(cls, Tables.AttrTag.ATT_Signature.parsekey(), value_cpx);
}
@Override
protected DataVector getAttrVector() {
return getDataVector(signature);
return getDataVector(signatureAttr);
}
public void write(CheckedDataOutputStream out) throws IOException, Parser.CompilerError {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,6 +22,7 @@
*/
package org.openjdk.asmtools.jasm;
import static java.lang.String.format;
import static org.openjdk.asmtools.jasm.JasmTokens.*;
import static org.openjdk.asmtools.jasm.Constants.EOF;
import static org.openjdk.asmtools.jasm.Constants.OFFSETBITS;
@ -188,7 +189,7 @@ prefix:
env.error(pos, "identifier.expected");
break;
default:
env.error(pos, "token.expected", "<" + t.printval() + ">");
env.error(pos, "token.expected", "<" + t.printValue() + ">");
break;
}
@ -948,7 +949,7 @@ scanloop:
idValue = bufferString();
stringValue = idValue;
token = keyword_token_ident(idValue);
debugStr("##### SCANNER (scanIdent) ######## token = " + token + " ##### ");
debugStr(format("##### SCANNER (scanIdent) ######## token = %s value = \"%s\"\n", token, idValue));
} // end scanIdentifier
//==============================
@ -1127,7 +1128,6 @@ loop:
// Our one concession to DOS.
if ((ch = in.read()) == EOF) {
token = Token.EOF;
// t0ken = Token.EOF;
break loop;
}
env.error(pos, "funny.char");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,40 +22,64 @@
*/
package org.openjdk.asmtools.jasm;
import org.openjdk.asmtools.jasm.TypeAnnotationTypes.ETargetType;
import org.openjdk.asmtools.jasm.TypeAnnotationTypes.TypePathEntry;
import java.io.IOException;
import java.util.ArrayList;
import org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
/**
*
* JVMS 4.7.20.
* type_annotation {
* u1 target_type;
* union {
* type_parameter_target;
* supertype_target;
* type_parameter_bound_target;
* empty_target;
* formal_parameter_target;
* throws_target;
* localvar_target;
* catch_target;
* offset_target;
* type_argument_target;
* } target_info;
* type_path target_path;
* u2 type_index;
* //
* //
* u2 num_element_value_pairs;
* { u2 element_name_index;
* element_value value;
* } element_value_pairs[num_element_value_pairs];
* }
*/
public class TypeAnnotationData extends AnnotationData {
protected TargetType targetType;
protected TargetInfo targetInfo;
protected ArrayList<TypePathEntry> targetPath;
protected ETargetType targetType;
protected TypeAnnotationTargetInfoData targetInfo;
protected TypeAnnotationTypePathData typePath;
/*-------------------------------------------------------- */
/*-------------------------------------------------------- */
/* TypeAnnotationData Methods */
public TypeAnnotationData(Argument typeCPX, boolean invisible) {
super(typeCPX, invisible);
typePath = new TypeAnnotationTypePathData();
}
@Override
public int getLength() {
return super.getLength() + 2 + targetInfo.getLength();
// lengthOf(annotations[]) + lengthOf(targetType) + lengthOf(targetInfo) + lengthOf(targetInfo)
return super.getLength() + 1 + targetInfo.getLength() + typePath.getLength();
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
super.write(out);
// KTL: (1/10/13) Spec changed: char -> byte
// out.writeShort(targetType.value);
out.writeByte(targetType.value);
targetInfo.write(out);
typePath.write(out);
super.write(out);
}
public void addTypePathEntry(TypePathEntry path) {
typePath.addTypePathEntry(path);
}
@Override
@ -64,40 +88,11 @@ public class TypeAnnotationData extends AnnotationData {
}
public String toString(int tabLevel) {
StringBuilder sb = new StringBuilder();
String tabStr = tabString(tabLevel);
sb.append(tabStr + "Target Type: ");
sb.append(targetType.toString());
sb.append('\n');
sb.append(tabStr + "Target Info: ");
sb.append(targetInfo.toString(tabLevel));
sb.append('\n');
sb.append(tabStr + "Target Path: [");
boolean first = true;
for (TypePathEntry tpe : targetPath) {
if (!first) {
sb.append(", ");
}
first = false;
sb.append(tpe);
}
sb.append("]");
sb.append('\n');
StringBuilder sb = new StringBuilder(tabString(tabLevel));
sb.append(targetType.toString()).
append(' ').
append(targetInfo.toString(tabLevel)).
append(typePath.toString(tabLevel));
return sb.toString();
}
protected static String tabString(int tabLevel) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < tabLevel; i++) {
sb.append('\t');
}
return sb.toString();
}
}

View File

@ -0,0 +1,546 @@
/*
* Copyright (c) 2020, 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;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
/**
* TargetInfo (4.7.20.1. The target_info union)
*
* BaseClass for any Type Annotation Target-Info.
*/
public abstract class TypeAnnotationTargetInfoData implements Data {
protected TypeAnnotationTypes.ETargetType targettype = null;
public TypeAnnotationTargetInfoData(TypeAnnotationTypes.ETargetType tt) {
targettype = tt;
}
public TypeAnnotationTypes.ETargetType getTargetType() {
return targettype;
}
public void print(PrintWriter out, String tab) {
// print the TargetType and TargetInfo
out.print(tab + " {");
targettype.print(out);
_print(out, tab);
out.print(tab + "} ");
}
public abstract void _print(PrintWriter out, String tab);
public abstract void write(CheckedDataOutputStream out) throws IOException;
@Override
public String toString() {
return toString(0);
}
protected abstract void _toString(StringBuilder sb, int tabLevel);
public String toString(int tabLevel) {
StringBuilder sb = new StringBuilder(tabString(tabLevel));
// first print the target info name (
sb.append(targettype.targetInfo().printValue()).append("_target ");
// get the sub-classes parts
_toString(sb, tabLevel);
return sb.toString();
}
/**
* type_parameter_target (4.7.20.1. The target_info union)
*
* The type_parameter_target item indicates that an annotation appears on the declaration of the i'th type parameter
* of a generic class, generic interface, generic method, or generic constructor.
*
* type_parameter_target {
* u1 type_parameter_index;
* }
*/
public static class type_parameter_target extends TypeAnnotationTargetInfoData {
int typeParamIndex;
public type_parameter_target(TypeAnnotationTypes.ETargetType tt, int index) {
super(tt);
typeParamIndex = index;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeByte(typeParamIndex);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(typeParamIndex);
}
@Override
public int getLength() {
return 1;
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append(String.format("{ type_parameter_index: %d; }",typeParamIndex));
}
}
/**
* supertype_target (4.7.20.1. The target_info union)
*
* The supertype_target item indicates that an annotation appears on a type in the extends or implements clause of
* a class or interface declaration.
*
* supertype_target {
* u2 supertype_index;
* }
*/
public static class supertype_target extends TypeAnnotationTargetInfoData {
int superTypeIndex;
public supertype_target(TypeAnnotationTypes.ETargetType tt, int index) {
super(tt);
superTypeIndex = index;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(superTypeIndex);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(superTypeIndex);
}
@Override
public int getLength() {
return 2;
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append(String.format("{ supertype_index: %d; }",superTypeIndex));
}
}
/**
* type_parameter_bound_target (4.7.20.1. The target_info union)
*
* The type_parameter_bound_target item indicates that an annotation appears on the i'th bound of the j'th type parameter
* declaration of a generic class, interface, method, or constructor.
*
* type_parameter_bound_target {
* u1 type_parameter_index;
* u1 bound_index;
* }
*/
public static class type_parameter_bound_target extends TypeAnnotationTargetInfoData {
int typeParamIndex;
int boundIndex;
public type_parameter_bound_target(TypeAnnotationTypes.ETargetType tt, int pindx, int bindx) {
super(tt);
typeParamIndex = pindx;
boundIndex = bindx;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeByte(typeParamIndex);
out.writeByte(boundIndex);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(typeParamIndex);
out.print(" ");
out.print(boundIndex);
}
@Override
public int getLength() {
return 2;
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append(String.format("{ type_parameter_index: %d; bound_index: %d; }",
typeParamIndex, boundIndex));
}
}
/**
* empty_target (4.7.20.1. The target_info union)
*
* The empty_target item indicates that an annotation appears on either the type in a field declaration,
* the return type of a method, the type of a newly constructed object, or the receiver type of a method or constructor.
*
* empty_target {
* }
*/
public static class empty_target extends TypeAnnotationTargetInfoData {
public empty_target(TypeAnnotationTypes.ETargetType tt) {
super(tt);
}
@Override
public void _print(PrintWriter out, String tab) {
// do nothing
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
// do nothing
}
@Override
public int getLength() { return 0; }
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append("{ }");
}
}
/**
* formal_parameter_target (4.7.20.1. The target_info union)
*
* The formal_parameter_target item indicates that an annotation appears on the type in a formal parameter
* declaration of a method, constructor, or lambda expression.
*
* formal_parameter_target {
* u1 formal_parameter_index;
* }
*/
public static class formal_parameter_target extends TypeAnnotationTargetInfoData {
int formalParamIndex;
public formal_parameter_target(TypeAnnotationTypes.ETargetType tt, int index) {
super(tt);
formalParamIndex = index;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeByte(formalParamIndex);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(formalParamIndex);
}
@Override
public int getLength() {
return 1;
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append(String.format("{ formal_parameter_index: %d; }",formalParamIndex));
}
}
/**
* throws_target (4.7.20.1. The target_info union)
*
* The throws_target item indicates that an annotation appears on the i'th type in the throws clause of a method or
* constructor declaration.
*
* throws_target {
* u2 throws_type_index;
* }
*/
public static class throws_target extends TypeAnnotationTargetInfoData {
int throwsTypeIndex;
public throws_target(TypeAnnotationTypes.ETargetType tt, int index) {
super(tt);
throwsTypeIndex = index;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(throwsTypeIndex);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(throwsTypeIndex);
}
@Override
public int getLength() {
return 2;
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append(String.format("{ throws_type_index: %d; }",throwsTypeIndex));
}
}
/**
* localvar_target (4.7.20.1. The target_info union)
*
* The localvar_target item indicates that an annotation appears on the type in a local variable declaration,
* including a variable declared as a resource in a try-with-resources statement.
*
* localvar_target {
* u2 table_length;
* { u2 start_pc;
* u2 length;
* u2 index;
* } table[table_length];
* }
*/
public static class localvar_target extends TypeAnnotationTargetInfoData {
public class LocalVar_Entry {
public int startPC;
public int length;
public int cpx;
public LocalVar_Entry(int st, int len, int index) {
startPC = st;
length = len;
cpx = index;
}
void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(startPC);
out.writeShort(length);
out.writeShort(cpx);
}
public void _print(PrintWriter out, String tab) {
out.print(tab + "{");
out.print(startPC);
out.print(" ");
out.print(length);
out.print(" ");
out.print(cpx);
out.print("}");
}
public String toString() {
return String.format("start_pc: %d, length: %d, index: %d", startPC, length, cpx);
}
}
ArrayList<LocalVar_Entry> table = null;
public localvar_target(TypeAnnotationTypes.ETargetType tt, int size) {
super(tt);
table = new ArrayList<>(size);
}
public void addEntry(int startPC, int length, int cpx) {
LocalVar_Entry entry = new LocalVar_Entry(startPC, length, cpx);
table.add(entry);
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(table.size());
for (LocalVar_Entry entry : table) {
entry.write(out);
}
}
@Override
public void _print(PrintWriter out, String tab) {
String innerTab = tab + " ";
for (LocalVar_Entry entry : table) {
entry._print(out, innerTab);
}
out.print(tab);
}
@Override
public int getLength() {
return 2 + // U2 for table size
(6 * table.size()); // (3 * U2) for each table entry
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
int i = 0;
sb.append(tabString(tabLevel)).append(String.format("{ %d {", table.size()));
for (LocalVar_Entry entry : table) {
sb.append(String.format(" [%d]: %s;", i++, entry.toString()));
}
sb.append(" } }");
}
}
/**
* catch_target (4.7.20.1. The target_info union)
*
* The catch_target item indicates that an annotation appears on the i'th type in an exception parameter declaration.
*
* catch_target {
* u2 exception_table_index;
* }
*/
public static class catch_target extends TypeAnnotationTargetInfoData {
int exceptionTableIndex;
public catch_target(TypeAnnotationTypes.ETargetType tt, int index) {
super(tt);
exceptionTableIndex = index;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(exceptionTableIndex);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(exceptionTableIndex);
}
@Override
public int getLength() {
return 2;
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append(String.format("{ exception_table_index: %d; }",exceptionTableIndex));
}
}
/**
* offset_target (4.7.20.1. The target_info union)
*
* The offset_target item indicates that an annotation appears on either the type in an instanceof expression or
* a new expression, or the type before the :: in a method reference expression.
*
* offset_target {
* u2 offset;
* }
*/
public static class offset_target extends TypeAnnotationTargetInfoData {
int offset;
public offset_target(TypeAnnotationTypes.ETargetType tt, int offset) {
super(tt);
this.offset = offset;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(offset);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(offset);
}
@Override
public int getLength() {
return 2;
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append(String.format("{ offset: %d; }", offset));
}
}
/**
* type_argument_target (4.7.20.1. The target_info union)
*
* The type_argument_target item indicates that an annotation appears either on the i'th type in a cast expression,
* or on the i'th type argument in the explicit type argument list for any of the following: a new expression,
* an explicit constructor invocation statement, a method invocation expression, or a method reference expression
*
* type_argument_target {
* u2 offset;
* u1 type_argument_index;
* }
*/
public static class type_argument_target extends TypeAnnotationTargetInfoData {
int offset;
int typeArgumentIndex;
public type_argument_target(TypeAnnotationTypes.ETargetType tt, int offset, int index) {
super(tt);
this.offset = offset;
typeArgumentIndex = index;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(offset);
out.writeByte(typeArgumentIndex);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(offset);
out.print(" ");
out.print(typeArgumentIndex);
}
@Override
public int getLength() {
return 3;
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
sb.append(tabString(tabLevel)).append(String.format("{ offset: %d; type_argument_index: %d; }",
offset, typeArgumentIndex));
}
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2020, 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;
import org.openjdk.asmtools.jasm.TypeAnnotationTypes.TypePathEntry;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
/**
* JVMS 4.7.20.2. The type_path structure
*
* type_path {
* u1 path_length;
* { u1 type_path_kind;
* u1 type_argument_index;
* } path[path_length];
* }
*/
public class TypeAnnotationTypePathData implements Data {
private ArrayList<TypePathEntry> typePathEntries = new ArrayList<>();
public void addTypePathEntry( TypePathEntry entry) {
typePathEntries.add(entry);
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeByte(typePathEntries.size());
for (TypePathEntry entry : typePathEntries) {
out.writeByte(entry.getTypePathKind());
out.writeByte(entry.getTypeArgumentIndex());
}
}
@Override
public int getLength() {
return 1 + typePathEntries.size() * 2;
}
public String toString(int tabLevel) {
String buffer = "";
if( typePathEntries.size() > 0 ) {
StringBuilder sb = new StringBuilder(tabString(tabLevel));
sb.append(" [ ");
boolean first = true;
for (TypePathEntry entry : typePathEntries) {
if (!first)
sb.append(", ");
first = false;
sb.append(entry.toString());
}
sb.append("]");
buffer = sb.toString();
}
return buffer;
}
/**
* jdis: print the type_path structure
*/
public void print(PrintWriter out, String tab) {
if( typePathEntries.size() > 0 ) {
out.print(tab + " {");
boolean first = true;
for (TypePathEntry entry : typePathEntries) {
if (!first) {
out.print(", ");
}
first = false;
out.print(entry.toString());
}
out.print(tab + "} ");
}
}
}

View File

@ -0,0 +1,312 @@
/*
* Copyright (c) 1996, 2020, 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;
import java.io.PrintWriter;
/**
* Type annotation types: target_type, target_info && target_path
*/
public class TypeAnnotationTypes {
/**
* Interpretation of type_path_kind values (Table 4.7.20.2-A)
*/
public enum EPathKind {
ARRAY(0),
INNER_TYPE(1),
WILDCARD(2),
TYPE_ARGUMENT(3);
private final int tag;
public static final int maxLen = 3;
EPathKind(int tag) {
this.tag = tag;
}
public int tag() {
return tag;
}
public String parseKey() {
return this.toString();
}
static EPathKind getPathKind(String token) {
for (EPathKind pk : values()) {
if( pk.parseKey().equals(token)) {
return pk;
}
}
return null;
}
}
// will throw ArrayIndexOutOfBounds if i < 0 or i > 3
static public EPathKind getPathKind(int i) {
return EPathKind.values()[i];
}
static public class TypePathEntry {
private final EPathKind kind;
private final int typeArgumentIndex;
public TypePathEntry(int kind, int typeArgumentIndex) {
this.kind = getPathKind(kind);
this.typeArgumentIndex = typeArgumentIndex;
}
public TypePathEntry(EPathKind kind, int typeArgumentIndex) {
this.kind = kind;
this.typeArgumentIndex = typeArgumentIndex;
}
public int getTypePathKind() {
return kind.tag();
}
public int getTypeArgumentIndex() {
return typeArgumentIndex;
}
@Override
public String toString() {
// Chapter 4.7.20.2 The type_path structure
// if the value of the type_path_kind is 0,1, or 2, thebn the value of the
// type_argument_index item is 0.
return kind.parseKey() + ( kind.tag == 3 ?
JasmTokens.Token.LBRACE.parseKey() + typeArgumentIndex + JasmTokens.Token.RBRACE.parseKey() :
"");
}
}
/**
* union {
* type_parameter_target;
* supertype_target;
* type_parameter_bound_target;
* empty_target;
* method_formal_parameter_target;
* throws_target;
* localvar_target;
* catch_target;
* offset_target;
* type_argument_target;
* } target_info;
*/
public enum ETargetInfo {
TYPEPARAM ("TYPEPARAM", "type_parameter"),
SUPERTYPE ("SUPERTYPE", "supertype"),
TYPEPARAM_BOUND ("TYPEPARAM_BOUND", "type_parameter_bound"),
EMPTY ("EMPTY", "empty"),
METHODPARAM ("METHODPARAM", "formal_parameter"),
EXCEPTION ("EXCEPTION", "throws"),
LOCALVAR ("LOCALVAR", "localvar"),
CATCH ("CATCH", "catch"),
OFFSET ("OFFSET", "offset"),
TYPEARG ("TYPEARG", "type_argument");
private final String parseKey;
private final String printValue;
ETargetInfo(String parse, String printValue) {
parseKey = parse;
this.printValue = printValue;
}
public String parseKey() {
return this.parseKey;
}
public String printValue() {
return this.printValue;
}
}
/**
* Interpretation of target_type values (Table 4.7.20-A./B.)
*/
static public enum ETargetType {
class_type_param (0x00, "CLASS_TYPE_PARAMETER", ETargetInfo.TYPEPARAM, "class/interface type parameter"),
meth_type_param (0x01, "METHOD_TYPE_PARAMETER", ETargetInfo.TYPEPARAM, "method/constructor type parameter"),
class_exts_impls (0x10, "CLASS_EXTENDS", ETargetInfo.SUPERTYPE, "class extends/implements"),
class_type_param_bnds (0x11, "CLASS_TYPE_PARAMETER_BOUND", ETargetInfo.TYPEPARAM_BOUND, "class/interface type parameter bounds"),
meth_type_param_bnds (0x12, "METHOD_TYPE_PARAMETER_BOUND", ETargetInfo.TYPEPARAM_BOUND, "method/constructor type parameter bounds"),
field (0x13, "FIELD", ETargetInfo.EMPTY, "field"),
meth_ret_type (0x14, "METHOD_RETURN", ETargetInfo.EMPTY, "method return type"),
meth_receiver (0x15, "METHOD_RECEIVER", ETargetInfo.EMPTY, "method receiver"),
meth_formal_param (0x16, "METHOD_FORMAL_PARAMETER", ETargetInfo.METHODPARAM, "method formal parameter type"),
throws_type (0x17, "THROWS", ETargetInfo.EXCEPTION, "exception type in throws"),
local_var (0x40, "LOCAL_VARIABLE", ETargetInfo.LOCALVAR, "local variable"),
resource_var (0x41, "RESOURCE_VARIABLE", ETargetInfo.LOCALVAR, "resource variable"),
exception_param (0x42, "EXCEPTION_PARAM", ETargetInfo.CATCH, "exception parameter"),
type_test (0x43, "INSTANCEOF", ETargetInfo.OFFSET, "type test (instanceof)"),
obj_creat (0x44, "NEW", ETargetInfo.OFFSET, "object creation (new)"),
constr_ref_receiver (0x45, "CONSTRUCTOR_REFERENCE_RECEIVER", ETargetInfo.OFFSET, "constructor reference receiver"),
meth_ref_receiver (0x46, "METHOD_REFERENCE_RECEIVER", ETargetInfo.OFFSET, "method reference receiver"),
cast (0x47, "CAST", ETargetInfo.TYPEARG, "cast"),
constr_invoc_typearg (0x48, "CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in constructor call"),
meth_invoc_typearg (0x49, "METHOD_INVOCATION_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in method call"),
constr_ref_typearg (0x4A, "CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in constructor reference"),
meth_ref_typearg (0x4B, "METHOD_REFERENCE_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in method reference");
public static final int maxTag = 0x9A;
public static final int maxLen = 36;
public final int value;
private final String parseKey;
private final ETargetInfo targetInfo;
private final String printVal;
ETargetType(int val, String parse, ETargetInfo targetInfo, String printVal) {
value = val;
parseKey = parse;
this.targetInfo = targetInfo;
this.printVal = printVal;
}
public String parseKey() {
return parseKey;
}
public String infoKey() {
return targetInfo.parseKey();
}
public ETargetInfo targetInfo() {
return targetInfo;
}
public void print(PrintWriter out) {
out.print(parseKey);
}
@Override
public String toString() {
return String.format("%s[%#x]", parseKey, value);
}
public static ETargetType getTargetType(int typeCode) {
for( ETargetType type: ETargetType.values() ) {
if (type.value == typeCode) {
return type;
}
}
return null;
}
static public ETargetType getTargetType(String typeName) {
for( ETargetType type: ETargetType.values() ) {
if (type.parseKey.equals(typeName)) {
return type;
}
}
return null;
}
};
/* TypeAnnotationVisitor Methods */
public static class TypeAnnotationTargetVisitor {
public final void visit(ETargetType tt) {
switch (tt) {
case class_type_param:
case meth_type_param:
visit_type_param_target(tt);
break;
case class_exts_impls:
visit_supertype_target(tt);
break;
case class_type_param_bnds:
case meth_type_param_bnds:
visit_typeparam_bound_target(tt);
break;
case field:
case meth_ret_type:
case meth_receiver:
visit_empty_target(tt);
break;
case meth_formal_param:
visit_methodformalparam_target(tt);
break;
case throws_type:
visit_throws_target(tt);
break;
case local_var:
case resource_var:
visit_localvar_target(tt);
break;
case exception_param:
visit_catch_target(tt);
break;
case type_test:
case obj_creat:
case constr_ref_receiver:
case meth_ref_receiver:
visit_offset_target(tt);
break;
case cast:
case constr_invoc_typearg:
case meth_invoc_typearg:
case constr_ref_typearg:
case meth_ref_typearg:
visit_typearg_target(tt);
break;
}
}
public void visit_type_param_target(ETargetType tt) {
}
public void visit_supertype_target(ETargetType tt) {
}
public void visit_typeparam_bound_target(ETargetType tt) {
}
public void visit_empty_target(ETargetType tt) {
}
public void visit_methodformalparam_target(ETargetType tt) {
}
public void visit_throws_target(ETargetType tt) {
}
public void visit_localvar_target(ETargetType tt) {
}
public void visit_catch_target(ETargetType tt) {
}
public void visit_offset_target(ETargetType tt) {
}
public void visit_typearg_target(ETargetType tt) {
}
}
}

View File

@ -1,891 +0,0 @@
/*
* Copyright (c) 1996, 2014, 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;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
/**
*
*/
public class TypeAnnotationUtils {
/*-------------------------------------------------------- */
/* TypeAnnotationData Inner Classes */
static public enum PathKind {
DEEPER_ARRAY (0, "DEEPER_ARRAY", "ARRAY"),
DEEPER_NESTEDTYPE (1, "DEEPER_NESTEDTYPE", "INNER_TYPE"),
BOUND_WILDCARDTYPE (2, "BOUND_WILDCARDTYPE", "WILDCARD"),
ITHARG_PARAMETERTYPE (3, "ITHARG_PARAMETERTYPE", "TYPE_ARGUMENT");
private final int key;
private final String type;
private final String parseKey;
public static final int maxLen = 3;
PathKind(int key, String type, String parseval) {
this.key = key;
this.type = type;
this.parseKey = parseval;
}
public int key() {
return key;
}
public String parsekey() {
return parseKey;
}
}
static private HashMap<String, PathKind> PathTypeHash = new HashMap<>(PathKind.maxLen);
private static void initPathTypes(PathKind pk) {
PathTypeHash.put(pk.parseKey, pk);
}
static {
for (PathKind pk : PathKind.values()) {
initPathTypes(pk);
}
}
public static PathKind pathKind(String parseKey) {
return PathTypeHash.get(parseKey);
}
// will throw ArrayIndexOutOfBounds if i < 0 or i > 3
static public PathKind getPathKind(int i) {
return PathKind.values()[i];
}
/*-------------------------------------------------------- */
/* TypeAnnotationData Inner Classes */
static public class TypePathEntry {
private final PathKind kind;
private final char index;
public TypePathEntry(int kind, char index) {
this.kind = getPathKind(kind);
this.index = index;
}
public PathKind kind() {
return kind;
}
public char index() {
return index;
}
public String toString() {
return kind.parsekey() + "(" + index + ")";
}
}
/*-------------------------------------------------------- */
/* TypeAnnotationData Inner Classes */
static public enum InfoType {
TYPEPARAM ("TYPEPARAM", "TYPEPARAM"),
SUPERTYPE ("SUPERTYPE", "SUPERTYPE"),
TYPEPARAM_BOUND ("TYPEPARAM_BOUND", "TYPEPARAM_BOUND"),
EMPTY ("EMPTY", "EMPTY"),
METHODPARAM ("METHODPARAM", "METHODPARAM"),
EXCEPTION ("EXCEPTION", "EXCEPTION"),
LOCALVAR ("LOCALVAR", "LOCALVAR"),
CATCH ("CATCH", "CATCH"),
OFFSET ("OFFSET", "OFFSET"),
TYPEARG ("TYPEARG", "TYPEARG");
private final String parseKey;
private final String printval;
InfoType(String parse, String print) {
parseKey = parse;
printval = print;
}
public String parseKey() {
return parseKey;
}
}
/**
* TargetType
*
* A (typed) tag (constant) representing the type of Annotation Target.
*/
static public enum TargetType {
class_type_param (0x00, "CLASS_TYPE_PARAMETER", InfoType.TYPEPARAM, "class type parameter"),
meth_type_param (0x01, "METHOD_TYPE_PARAMETER", InfoType.TYPEPARAM, "method type parameter"),
class_exts_impls (0x10, "CLASS_EXTENDS", InfoType.SUPERTYPE, "class extends/implements"),
class_type_param_bnds (0x11, "CLASS_TYPE_PARAMETER_BOUND", InfoType.TYPEPARAM_BOUND, "class type parameter bounds"),
meth_type_param_bnds (0x12, "METHOD_TYPE_PARAMETER_BOUND", InfoType.TYPEPARAM_BOUND, "method type parameter bounds"),
field (0x13, "FIELD", InfoType.EMPTY, "field"),
meth_ret_type (0x14, "METHOD_RETURN", InfoType.EMPTY, "method return type"),
meth_receiver (0x15, "METHOD_RECEIVER", InfoType.EMPTY, "method receiver"),
meth_formal_param (0x16, "METHOD_FORMAL_PARAMETER", InfoType.METHODPARAM, "method formal parameter type"),
throws_type (0x17, "THROWS", InfoType.EXCEPTION, "exception type in throws"),
local_var (0x40, "LOCAL_VARIABLE", InfoType.LOCALVAR, "local variable"),
resource_var (0x41, "RESOURCE_VARIABLE", InfoType.LOCALVAR, "resource variable"), // TODO
exception_param (0x42, "EXCEPTION_PARAM", InfoType.CATCH, "exception parameter"), // TODO
type_test (0x43, "INSTANCEOF", InfoType.OFFSET, "type test (instanceof)"),
obj_creat (0x44, "NEW", InfoType.OFFSET, "object creation (new)"),
constr_ref_receiver (0x45, "CONSTRUCTOR_REFERENCE_RECEIVER", InfoType.OFFSET, "constructor reference receiver"),
meth_ref_receiver (0x46, "METHOD_REFERENCE_RECEIVER", InfoType.OFFSET, "method reference receiver"),
cast (0x47, "CAST", InfoType.TYPEARG, "cast"),
constr_invoc_typearg (0x48, "CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT", InfoType.TYPEARG, "type argument in constructor call"),
meth_invoc_typearg (0x49, "METHOD_INVOCATION_TYPE_ARGUMENT", InfoType.TYPEARG, "type argument in method call"),
constr_ref_typearg (0x4A, "CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT", InfoType.TYPEARG, "type argument in constructor reference"),
meth_ref_typearg (0x4B, "METHOD_REFERENCE_TYPE_ARGUMENT", InfoType.TYPEARG, "type argument in method reference");
public static final int maxTag = 0x9A;
public static final int maxLen = 36;
public final int value;
private final String parseKey;
private final InfoType infoKey;
private final String printval;
TargetType(int val, String parse, InfoType info, String print) {
value = val;
parseKey = parse;
infoKey = info;
printval = print;
}
public String parseKey() {
return parseKey;
}
public String infoKey() {
return infoKey.parseKey();
}
public InfoType infoType() {
return infoKey;
}
public void print(PrintWriter out) {
out.print(parseKey);
}
@Override
public String toString() {
return parseKey + " (" + infoKey() + ") <" + printval + "> [" + Integer.toHexString(value) + "]";
}
};
static private HashMap<String, TargetType> TargetTypeHash = new HashMap<>(TargetType.maxLen);
static private HashMap<Integer, TargetType> TargetTypeList = new HashMap<>(TargetType.maxLen);
private static void initTargetTypes(TypeAnnotationUtils.TargetType tt) {
TargetTypeList.put(tt.value, tt);
TargetTypeHash.put(tt.parseKey, tt);
}
static {
for (TargetType type : TargetType.values()) {
initTargetTypes(type);
}
}
public static TargetType targetType(String parseKey) {
return TargetTypeHash.get(parseKey);
}
public static TargetType targetTypeEnum(Integer typeCode) {
return TargetTypeList.get(typeCode);
}
/**
* TargetInfo
*
* BaseClass for any Type Annotation Target-Info.
*/
public static class TargetInfo {
protected TargetType targettype = null;
public TargetInfo(TargetType tt) {
targettype = tt;
}
public TargetType getTargetType() {
return targettype;
}
public void print(PrintWriter out, String tab) {
// print the TargetType and TargetInfo
out.print(tab + " {");
targettype.print(out);
_print(out, tab);
out.print(tab + "}");
}
public void _print(PrintWriter out, String tab) {
// sub-classes override
}
public void write(CheckedDataOutputStream out) throws IOException {
// placeholder
}
public int getLength() {
return 0;
}
@Override
public String toString() {
return toString(0);
}
protected void _toString(StringBuilder sb, int tabLevel) {
// sub-classes override
}
public String toString(int tabLevel) {
StringBuilder sb = new StringBuilder();
String tabStr = tabString(tabLevel);
// first print the name/target-type
sb.append(tabStr);
sb.append(targettype.infoKey() + " \n");
sb.append(tabStr);
sb.append(targettype + " \n");
// get the sub-classes parts
_toString(sb, tabLevel);
return sb.toString();
}
protected static String tabString(int tabLevel) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < tabLevel; i++) {
sb.append('\t');
}
return sb.toString();
}
}
/**
* TypeParams_Target (3.3.1 Type parameters)
*
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
* array, or nested type.
*
* These need location information to identify the annotated element.
*/
public static class typeparam_target extends TargetInfo {
int pindex;
public typeparam_target(TargetType tt, int indx) {
super(tt);
pindex = indx;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeByte(pindex);
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(pindex);
}
@Override
public int getLength() {
return 1 + super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr = tabString(tabLevel);
sb.append(tabStr);
sb.append("param_index: ");
sb.append(pindex);
sb.append('\n');
}
}
/**
* supertype_target (3.3.2 Class extends and implements)
*
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
* array, or nested type.
*
* These need location information to identify the annotated element.
*/
public static class supertype_target extends TargetInfo {
int type_index;
public supertype_target(TargetType tt, int tindex) {
super(tt);
type_index = tindex;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(type_index);
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(type_index);
}
@Override
public int getLength() {
return 2 + super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr = tabString(tabLevel);
sb.append(tabStr);
sb.append("type_index: ");
sb.append(type_index);
sb.append('\n');
}
}
/**
* typeparam_bound_target (3.3.3 Type parameter bounds)
*
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
* array, or nested type.
*
* These need location information to identify the annotated element.
*/
public static class typeparam_bound_target extends TargetInfo {
int pindex;
int bindex;
public typeparam_bound_target(TargetType tt, int pindx, int bindx) {
super(tt);
pindex = pindx;
bindex = bindx;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeByte(pindex);
out.writeByte(bindex);
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(pindex);
out.print(" ");
out.print(bindex);
}
@Override
public int getLength() {
return 2 + super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr = tabString(tabLevel);
sb.append(tabStr);
sb.append("param_index: ");
sb.append(pindex);
sb.append('\n');
sb.append(tabStr);
sb.append("bound_index: ");
sb.append(bindex);
sb.append('\n');
}
}
/**
* empty_target (3.3.4 )
*
* Types without arguments.
*
* Basic types without arguments, like field, method return, or method receiver.
*/
public static class empty_target extends TargetInfo {
public empty_target(TargetType tt) {
super(tt);
}
}
/**
* methodformalparam_target (3.3.5 Method parameters)
*
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
* array, or nested type.
*
* These need location information to identify the annotated element.
*/
public static class methodformalparam_target extends TargetInfo {
int index;
public methodformalparam_target(TargetType tt, int indx) {
super(tt);
index = indx;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeByte(index);
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(index);
}
@Override
public int getLength() {
return 1 + super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr = tabString(tabLevel);
sb.append(tabStr);
sb.append("index: ");
sb.append(index);
sb.append('\n');
}
}
/**
* throws_target (3.3.6 throws clauses)
*
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
* array, or nested type.
*
* These need location information to identify the annotated element.
*/
public static class throws_target extends TargetInfo {
int type_index;
public throws_target(TargetType tt, int tindex) {
super(tt);
type_index = tindex;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(type_index);
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(type_index);
}
@Override
public int getLength() {
return 2 + super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr = tabString(tabLevel);
sb.append(tabStr);
sb.append("type_index: ");
sb.append(type_index);
sb.append('\n');
}
}
/**
* localvar_target (3.3.7 Local variables)
*
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
* array, or nested type.
*
* These need location information to identify the annotated element.
*/
public static class localvar_target extends TargetInfo {
public static class LocalVar_Entry {
public int startPC;
public int length;
public int cpx;
public LocalVar_Entry(int st, int len, int index) {
startPC = st;
length = len;
cpx = index;
}
void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(startPC);
out.writeShort(length);
out.writeShort(cpx);
}
public void _print(PrintWriter out, String tab) {
out.print(tab + "{");
out.print(startPC);
out.print(" ");
out.print(length);
out.print(" ");
out.print(cpx);
out.println("}");
}
public String toString() {
return new String("startPC: " + startPC
+ " length: " + length
+ " cpx: " + cpx);
}
}
ArrayList<LocalVar_Entry> table = null;
public localvar_target(TargetType tt, int size) {
super(tt);
table = new ArrayList<>(size);
}
public void addEntry(int startPC, int length, int cpx) {
LocalVar_Entry entry = new LocalVar_Entry(startPC, length, cpx);
table.add(entry);
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(table.size());
for (LocalVar_Entry entry : table) {
entry.write(out);
}
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
String innerTab = tab + " ";
out.println();
for (LocalVar_Entry entry : table) {
entry._print(out, innerTab);
}
out.print(innerTab);
}
@Override
public int getLength() {
return 2 + // U2 for table size
(6 * table.size()) + // (3 * U2) for each table entry
super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr1 = tabString(tabLevel + 1);
int i = 1;
for (LocalVar_Entry entry : table) {
sb.append(tabStr1);
sb.append("[" + i + "]: ");
sb.append(entry.toString());
sb.append('\n');
i += 1;
}
}
}
/**
* catch_target (3.3.8 Exception parameters (catch clauses))
*
* Index to the exception type (the type that shows up in a catch clause).
*
* These need location information to identify the annotated element.
*/
public static class catch_target extends TargetInfo {
int exception_table_index;
public catch_target(TargetType tt, int indx) {
super(tt);
exception_table_index = indx;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(exception_table_index);
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(exception_table_index);
}
@Override
public int getLength() {
return 2 + super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr = tabString(tabLevel);
sb.append(tabStr);
sb.append("exception_table_index: ");
sb.append(exception_table_index);
sb.append('\n');
}
}
/**
* offset_target (3.3.9 Typecasts, type tests, and object creation)
*
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
* array, or nested type.
*
* These need location information to identify the annotated element.
*/
public static class offset_target extends TargetInfo {
int offset;
public offset_target(TargetType tt, int ofst) {
super(tt);
offset = ofst;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(offset);
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(offset);
}
@Override
public int getLength() {
return 2 + super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr = tabString(tabLevel);
sb.append(tabStr);
sb.append("offset: ");
sb.append(offset);
sb.append('\n');
}
}
/**
* typearg_target (3.3.10 Constructor and method call type arguments)
*
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
* array, or nested type.
*
* These need location information to identify the annotated element.
*/
public static class typearg_target extends TargetInfo {
int offset;
int typeIndex;
public typearg_target(TargetType tt, int ofst, int tindx) {
super(tt);
offset = ofst;
typeIndex = tindx;
}
@Override
public void write(CheckedDataOutputStream out) throws IOException {
out.writeShort(offset);
out.writeByte(typeIndex);
super.write(out);
}
@Override
public void _print(PrintWriter out, String tab) {
out.print(" ");
out.print(offset);
out.print(" ");
out.print(typeIndex);
}
@Override
public int getLength() {
return 3 + super.getLength();
}
@Override
protected void _toString(StringBuilder sb, int tabLevel) {
String tabStr = tabString(tabLevel);
sb.append(tabStr);
sb.append("offset: ");
sb.append(offset);
sb.append('\n');
sb.append(tabStr);
sb.append("type_index: ");
sb.append(typeIndex);
sb.append('\n');
}
}
/*-------------------------------------------------------- */
/* TypeAnnotationVisitor Methods */
public static class TypeAnnotationTargetVisitor {
public final void visit(TargetType tt) {
switch (tt) {
case class_type_param:
case meth_type_param:
visit_type_param_target(tt);
break;
case class_exts_impls:
visit_supertype_target(tt);
break;
case class_type_param_bnds:
case meth_type_param_bnds:
visit_typeparam_bound_target(tt);
break;
case field:
case meth_ret_type:
case meth_receiver:
visit_empty_target(tt);
break;
case meth_formal_param:
visit_methodformalparam_target(tt);
break;
case throws_type:
visit_throws_target(tt);
break;
case local_var:
case resource_var:
visit_localvar_target(tt);
break;
case exception_param:
visit_catch_target(tt);
break;
case type_test:
case obj_creat:
case constr_ref_receiver:
case meth_ref_receiver:
visit_offset_target(tt);
break;
case cast:
case constr_invoc_typearg:
case meth_invoc_typearg:
case constr_ref_typearg:
case meth_ref_typearg:
visit_typearg_target(tt);
break;
}
}
public void visit_type_param_target(TargetType tt) {
}
public void visit_supertype_target(TargetType tt) {
}
public void visit_typeparam_bound_target(TargetType tt) {
}
public void visit_empty_target(TargetType tt) {
}
public void visit_methodformalparam_target(TargetType tt) {
}
public void visit_throws_target(TargetType tt) {
}
public void visit_localvar_target(TargetType tt) {
}
public void visit_catch_target(TargetType tt) {
}
public void visit_offset_target(TargetType tt) {
}
public void visit_typearg_target(TargetType tt) {
}
}
/*-------------------------------------------------------- */
/*-------------------------------------------------------- */
/* TypeAnnotationData Methods */
public TypeAnnotationUtils() {
}
public static TargetType getTargetType(int tt_index) {
if (tt_index < 0 || tt_index > TargetType.maxTag) {
return null;
}
return TargetTypeList.get(tt_index);
}
static public TargetType getTargetType(String tt) {
TargetType retval = TargetTypeHash.get(tt);
if (retval.name().equals("UNUSED")) {
retval = null;
}
return retval;
}
}

View File

@ -52,7 +52,6 @@ jasm.error.fatal_error=fatal error
jasm.error.fatal_exception=fatal exception
#err.not.implemented=Sorry, {0} not implemented.
# Scanner:
err.invalid.escape.char=Invalid escape character.
err.eof.in.comment=Comment not terminated at end of input.
@ -62,14 +61,12 @@ err.overflow=Numeric overflow.
err.float.format=Invalid floating point format.
err.eof.in.string=String not terminated at end of input.
err.newline.in.string=String not terminated at end of line.
#err.invalid.char.constant=Invalid character constant.
err.funny.char=Invalid character in input.
err.unbalanced.paren=Unbalanced parentheses.
# Parser:
err.package.repeated=Package statement repeated.
warn.intf.repeated=Interface {0} repeated.
warn.exc.repeated=Exception repeated in throws clause.
warn.signature.repeated=Signature attribute repeated in the record's component.
warn.record.repeated=Record attribute repeated.
err.multiple.inherit=Multiple inheritance is not supported.
err.toplevel.expected=Class, module or interface declaration expected.
@ -77,17 +74,22 @@ err.const.def.expected=Constant declaration expected.
err.const.undecl=Constant #{0} not declared.
err.const.redecl=Constant {0} redeclared.
warn.const0.redecl=Re-declaration of Constant #0 cannot be written to the class file.
err.field.expected=Field, method, NestMembers, NestHost or Record declaration expected.
err.field.expected=Field, Method, NestMembers, NestHost or Record declaration expected.
err.token.expected={0} expected.
err.identifier.expected=Identifier expected.
err.extra.nesthost.attribute=There may be at most one NestHost attribute.
err.extra.nestmembers.attribute=There may be at most one NestMembers attribute.
err.extra.permittedsubtypes.attribute=There may be at most one PermittedSubtypes attribute.
err.extra.record.attribute=There may be at most one Record attribute.
err.grouped.component.expected=Either an annotation or a record component expected.
warn.no.components.in.record.attribute=Record should have at least one component.
err.one.of.two.token.expected=Either #{0} or #{1} token expected.
err.both.nesthost.nestmembers.found=The attributes table of a ClassFile structure must not contain both a NestMembers attribute and a NestHost attribute.
err.name.expected=Name expected, got {0}.
err.module.name.expected=Module name expected, got {0}.
err.int.expected=Integer expected.
err.neg.forbidden=Negative integer is not allowed here.
err.value.large=Value doesn't fit in {0}.
err.value.expected=Value expected.
err.wrong.mnemocode=Invalid mnemocode ({0}).

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2020, 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
@ -662,7 +662,7 @@ class Jcoder {
/**
* Parse an Jcoder file.
*/
ArrayList<ByteBuffer> parseFile() {
void parseFile() {
env.traceln("PARSER");
context.init();
try {
@ -690,7 +690,7 @@ class Jcoder {
case EOF:
// The end
return Classes;
return;
default:
env.traceln("unexpected token=" + scanner.token.toString());
@ -708,9 +708,7 @@ class Jcoder {
}
} catch (IOException e) {
env.error(scanner.pos, "io.exception", env.getInputFileName());
return Classes;
}
return Classes;
} //end parseFile
/*---------------------------------------------*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -41,9 +41,7 @@ public class Main extends Tool {
public Main(PrintWriter out, String programName) {
super(out, programName);
printCannotReadMsg = (fname) -> {
error(i18n.getString("jcoder.error.cannot_read", fname));
};
printCannotReadMsg = (fname) -> error(i18n.getString("jcoder.error.cannot_read", fname));
}
public Main(PrintStream out, String program) {
@ -192,7 +190,7 @@ public class Main extends Tool {
/**
* main program
*/
public static void main(String argv[]) {
public static void main(String[] argv) {
Main compiler = new Main(new PrintWriter(System.out), "jcoder");
System.exit(compiler.compile(argv) ? 0 : 1);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -100,7 +100,7 @@ public class Scanner {
* A growable character buffer.
*/
private int count;
private char buffer[] = new char[32];
private char[] buffer = new char[32];
/*-------------------------------------------------------- */
/**
@ -170,7 +170,7 @@ public class Scanner {
private void putc(int ch) {
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);
buffer = newBuffer;
}
@ -178,7 +178,7 @@ public class Scanner {
}
private String bufferString() {
char buf[] = new char[count];
char[] buf = new char[count];
System.arraycopy(buffer, 0, buf, 0, count);
return new String(buf);
}
@ -472,16 +472,6 @@ numberLoop:
}
return n;
}
// Utf8 "\%pattern\%NonNegativePoint\%(II)";
case '%':
readCh();
return '%';
case '@':
readCh();
return '@';
case ':':
readCh();
return ':';
case 'r':
readCh();
return '\r';
@ -540,11 +530,7 @@ loop:
case '\\': {
int c = scanEscapeChar();
if (c >= 0) {
char ch = (char)c;
if ( ch == '@' || ch == ':' || ch == '\\') {
putc('\\');
}
putc(ch);
putc((char)c);
}
break;
}
@ -618,16 +604,12 @@ loop:
for (;;) {
putc(ch);
readCh();
//env.traceln(" read:"+(char)ch);
if ((ch == '/') || (ch == '.') || (ch == '-')) {
//env.traceln(" =>compound");
compound = true;
continue;
} else if (!Character.isJavaIdentifierPart((char) ch)) {
break;
}
}
//env.traceln(" end:"+(char)ch);
stringValue = bufferString();
if (compound) {
token = Token.IDENT;
@ -646,8 +628,6 @@ loop:
token = Token.INTVAL;
intSize = 1;
longValue = intValue;
} else {
//env.traceln(" ^^^^^^^^ Massive Weirdness here: Can't locate IDENT '" + stringValue + "'. ^^^^^^^^^^");
}
}
}

View File

@ -23,6 +23,7 @@
package org.openjdk.asmtools.jdec;
import org.openjdk.asmtools.common.Module;
import org.openjdk.asmtools.asmutils.StringUtils;
import org.openjdk.asmtools.jasm.Modifiers;
import org.openjdk.asmtools.jcoder.JcodTokens;
import org.openjdk.asmtools.util.I18NResourceBundle;
@ -36,7 +37,7 @@ import java.io.PrintWriter;
import static java.lang.String.format;
import static org.openjdk.asmtools.jasm.Tables.*;
import static org.openjdk.asmtools.jasm.Tables.AnnotElemType.AE_UNKNOWN;
import static org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
import static org.openjdk.asmtools.jasm.TypeAnnotationTypes.*;
/**
* Class data of the Java Decoder
@ -285,30 +286,7 @@ class ClassData {
switch (tg) {
case CONSTANT_UTF8: {
tagstr = "Utf8";
StringBuilder sb = new StringBuilder();
String s = (String) cpool[i];
sb.append('\"');
for (int k = 0; k < s.length(); k++) {
char c = s.charAt(k);
switch (c) {
case '\t':
sb.append('\\').append('t');
break;
case '\n':
sb.append('\\').append('n');
break;
case '\r':
sb.append('\\').append('r');
break;
case '\"':
sb.append('\\').append('\"');
break;
default:
sb.append(c);
}
}
valstr = sb.append('\"').toString();
valstr = StringUtils.Utf8ToString((String) cpool[i]);
}
break;
case CONSTANT_FLOAT:
@ -438,11 +416,13 @@ class ClassData {
*/
private void decodeTargetTypeAndRefInfo(DataInputStream in) throws IOException {
int tt = in.readUnsignedByte(); // [4.7.20] annotations[], type_annotation { u1 target_type; ...}
TargetType target_type = targetTypeEnum(tt);
InfoType info_type = target_type.infoType();
out_println(toHex(tt, 1) + "; // target_type: " + target_type.parseKey());
switch (info_type) {
ETargetType targetType = ETargetType.getTargetType(tt);
if( targetType == null ) {
throw new Error("Type annotation: invalid target_type(u1) " + tt);
}
ETargetInfo targetInfo = targetType.targetInfo();
out_println(toHex(tt, 1) + "; // target_type: " + targetType.parseKey());
switch (targetInfo) {
case TYPEPARAM: //[3.3.1] meth_type_param, class_type_param:
out_println(toHex(in.readUnsignedByte(), 1) + "; // param_index");
break;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,21 +27,22 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import static java.lang.String.format;
/**
*
*/
public class AnnotationData {
public class AnnotationData {
/*-------------------------------------------------------- */
/* AnnotData Fields */
private boolean invisible = false;
private int type_cpx = 0; //an index into the constant pool indicating the annotation type for this annotation.
private ArrayList<AnnotElem> array = new ArrayList<>();
private ClassData cls;
protected String visAnnotToken = "@+";
protected String invAnnotToken = "@-";
protected String dataName = "AnnotationData";
private boolean invisible = false;
private int type_cpx = 0; //an index into the constant pool indicating the annotation type for this annotation.
private ArrayList<AnnotationElement> array = new ArrayList<>();
private ClassData cls;
/*-------------------------------------------------------- */
public AnnotationData(boolean invisible, ClassData cls) {
@ -51,12 +52,12 @@ public class AnnotationData {
public void read(DataInputStream in) throws IOException {
type_cpx = in.readShort();
TraceUtils.traceln(" " + dataName + ": name[" + type_cpx + "]=" + cls.pool.getString(type_cpx));
int elemValueLength = in.readShort();
TraceUtils.traceln(" " + dataName + ": " + cls.pool.getString(type_cpx) + "num_elems: " + elemValueLength);
TraceUtils.traceln(3, format(" %s: name[%d]=%s", dataName, type_cpx, cls.pool.getString(type_cpx)),
format(" %s: %s num_elems: %d", dataName, cls.pool.getString(type_cpx), elemValueLength));
for (int evc = 0; evc < elemValueLength; evc++) {
AnnotElem elem = new AnnotElem(cls);
TraceUtils.traceln(" " + dataName + ": " + cls.pool.getString(type_cpx) + " reading [" + evc + "]");
AnnotationElement elem = new AnnotationElement(cls);
TraceUtils.traceln(3, format(" %s: %s reading [%d]", dataName, cls.pool.getString(type_cpx), evc));
elem.read(in, invisible);
array.add(elem);
}
@ -64,7 +65,7 @@ public class AnnotationData {
public void print(PrintWriter out, String tab) {
printHeader(out, tab);
printBody(out, tab);
printBody(out, "");
}
protected void printHeader(PrintWriter out, String tab) {
@ -92,16 +93,14 @@ public class AnnotationData {
// For a standard annotation, print out brackets,
// and list the name/value pairs.
out.print(" { ");
int i = 0;
for (AnnotElem elem : array) {
for (AnnotationElement elem : array) {
elem.print(out, tab);
if (i++ < array.size() - 1) {
out.print(", ");
}
}
out.print(tab + "}");
out.print(" }");
}
@Override
@ -126,7 +125,7 @@ public class AnnotationData {
sb.append(" { ");
int i = 0;
for (AnnotElem elem : array) {
for (AnnotationElement elem : array) {
sb.append(elem.toString());
if (i++ < array.size() - 1) {
@ -143,5 +142,5 @@ public class AnnotationData {
protected void _toString(StringBuilder sb) {
// sub-classes override this
}
} // end AnnotData
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,6 +22,7 @@
*/
package org.openjdk.asmtools.jdis;
import static java.lang.String.format;
import static org.openjdk.asmtools.jasm.Tables.*;
import java.io.DataInputStream;
import java.io.IOException;
@ -29,13 +30,9 @@ import java.io.PrintWriter;
import java.util.ArrayList;
/**
*
* AnnotElem
*
* Base class of all AnnotationElement entries
*
*/
public class AnnotElem {
public class AnnotationElement {
/**
*
@ -46,8 +43,6 @@ public class AnnotElem {
*/
public static class AnnotValue {
/*-------------------------------------------------------- */
/* AnnotElem Fields */
/**
* tag the descriptor for the constant
*/
@ -55,7 +50,6 @@ public class AnnotElem {
// internal references
protected ClassData cls;
/*-------------------------------------------------------- */
public AnnotValue(AnnotElemType tagval, ClassData cls) {
tag = tagval;
@ -67,7 +61,7 @@ public class AnnotElem {
}
public void print(PrintWriter out, String tab) {
out.print(tag.val() + "\t");
out.print(tag.val() + " ");
}
@Override
@ -362,7 +356,7 @@ public class AnnotElem {
protected ClassData cls;
/*-------------------------------------------------------- */
public AnnotElem(ClassData cls) {
public AnnotationElement(ClassData cls) {
this.cls = cls;
}
@ -376,9 +370,8 @@ public class AnnotElem {
*/
public void read(DataInputStream in, boolean invisible) throws IOException {
name_cpx = in.readShort();
TraceUtils.traceln(" AnnotElem: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx));
value = readValue(in, cls, invisible);
TraceUtils.traceln(" " + value.toString());
TraceUtils.traceln(format(" AnnotElem: name[%d]=%s value=%s", name_cpx, cls.pool.getString(name_cpx), value.toString()));
}
public String stringVal() {
@ -387,7 +380,7 @@ public class AnnotElem {
public void print(PrintWriter out, String tab) {
out.print(stringVal() + " = ");
value.print(out, tab);
value.print(out, "");
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -23,20 +23,28 @@
package org.openjdk.asmtools.jdis;
import org.openjdk.asmtools.jasm.Tables;
import java.io.DataInputStream;
import java.io.IOException;
import static java.lang.String.format;
/**
*
*/
public class AttrData {
int name_cpx;
byte data[];
ClassData cls;
public AttrData(ClassData cls) {
this.cls = cls;
}
/**
*
* attributeTag
*
* returns either -1 (not found), or the hashed integer tag key.
*
* <p>
* returns either -1 (not found), or the hashed integer tag tag.
*/
public static int attributeTag(String tagname) {
int intgr = Tables.attrtagValue(tagname);
@ -48,22 +56,10 @@ public class AttrData {
return intgr;
}
/*-------------------------------------------------------- */
/* AttrData Fields */
int name_cpx;
byte data[];
ClassData cls;
/*-------------------------------------------------------- */
public AttrData(ClassData cls) {
this.cls = cls;
}
public void read(int name_cpx, int attrlen, DataInputStream in) throws IOException {
this.name_cpx = name_cpx;
data = new byte[attrlen];
TraceUtils.traceln(" AttrData:#" + name_cpx + " len=" + attrlen);
TraceUtils.traceln(format("AttrData:#%d len=%d", name_cpx, attrlen));
in.readFully(data);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,9 +32,7 @@ import java.util.ArrayList;
/**
*
*/
public class BootstrapMethodData {
/*-------------------------------------------------------- */
/* BootstrapMethodData Fields */
public class BootstrapMethodData extends Indenter {
int bsm_index;
ArrayList<Integer> bsm_args_indexes;
@ -43,7 +41,6 @@ public class BootstrapMethodData {
private Options options = Options.OptionObject();
private ClassData cls;
private PrintWriter out;
/*-------------------------------------------------------- */
public BootstrapMethodData(ClassData cls) {
this.cls = cls;
@ -53,6 +50,7 @@ public class BootstrapMethodData {
/*========================================================*/
/* Read Methods */
/**
*
* read
@ -75,7 +73,7 @@ public class BootstrapMethodData {
/*========================================================*/
/* Print Methods */
public void print() throws IOException {
out.print(JasmTokens.Token.BOOTSTRAPMETHOD.parsekey() + " #" + bsm_index);
out.print(getIndentString() + JasmTokens.Token.BOOTSTRAPMETHOD.parseKey() + " #" + bsm_index);
for (int i = 0; i < bsm_args_indexes.size(); i++) {
out.print(" #" + bsm_args_indexes.get(i));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,10 +27,14 @@ import org.openjdk.asmtools.common.Tool;
import org.openjdk.asmtools.jasm.Modifiers;
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static java.lang.String.format;
import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
import static org.openjdk.asmtools.jasm.Tables.*;
@ -98,9 +102,9 @@ public class ClassData extends MemberData {
// other parsing fields
protected PrintWriter out;
protected String pkgPrefix = "";
private int pkgPrefixLen = 0;
private TextLines source = null;
private static final String initialTab = ""; //The number of elements in the buffer
// source file data
private TextLines sourceLines = null;
private Path classFile = null;
public ClassData(PrintWriter out, Tool tool) {
this.out = out;
@ -112,11 +116,17 @@ public class ClassData extends MemberData {
}
public void read(File in) throws IOException {
read(new DataInputStream(new FileInputStream(in)));
try ( DataInputStream dis = new DataInputStream(new FileInputStream(in))){
read(dis);
}
classFile = in.toPath();
}
public void read(String in) throws IOException {
read(new DataInputStream(new FileInputStream(in)));
try ( DataInputStream dis = new DataInputStream(new FileInputStream(in))){
read(dis);
}
classFile = Paths.get(in);
}
/**
@ -232,7 +242,7 @@ public class ClassData extends MemberData {
/**
* Read and resolve the class data
*/
public void read(DataInputStream in) throws IOException {
private void read(DataInputStream in) throws IOException {
// Read the header
int magic = in.readInt();
if (magic != JAVA_MAGIC) {
@ -261,22 +271,20 @@ public class ClassData extends MemberData {
// Read the attributes
readAttributes(in);
TraceUtils.traceln("");
TraceUtils.traceln("Reading is done-----------------------------------------------------");
TraceUtils.traceln("");
//
TraceUtils.traceln("", "<< Reading is done >>", "");
}
/**
* Read and resolve the attribute data
*/
public String getSrcLine(int lnum) {
if (source == null) {
if (sourceLines == null) {
return null; // impossible call
}
String line;
try {
line = source.getLine(lnum);
line = sourceLines.getLine(lnum);
} catch (ArrayIndexOutOfBoundsException e) {
line = "Line number " + lnum + " is out of bounds";
}
@ -286,23 +294,24 @@ public class ClassData extends MemberData {
private <T extends AnnotationData> void printAnnotations(List<T> annotations) {
if (annotations != null) {
for (T ad : annotations) {
ad.print(out, initialTab);
ad.print(out, "");
out.println();
}
}
}
@Override
public void print() throws IOException {
int k, l;
String className = "";
String sourceName = "";
String sourceName = null;
if( isModuleUnit() ) {
// Print the Annotations
printAnnotations(visibleAnnotations);
printAnnotations(invisibleAnnotations);
} else {
className = pool.getClassName(this_cpx);
pkgPrefixLen = className.lastIndexOf("/") + 1;
int pkgPrefixLen = className.lastIndexOf("/") + 1;
// Write the header
// package-info compilation unit
if (className.endsWith("package-info")) {
@ -415,11 +424,10 @@ printSugar:
out.println("{");
if ((options.contains(Options.PR.SRC)) && (source_cpx != 0)) {
sourceName = String.format(" compiled from %s" +
"" , pool.getName(source_cpx));
try {
source = new TextLines(sourceName);
} catch (IOException ignored) {}
sourceName = pool.getString(source_cpx);
if (sourceName != null) {
sourceLines = new TextLines(classFile.getParent(), sourceName);
}
}
// Print the constant pool
@ -430,23 +438,13 @@ printSugar:
if ( !isModuleUnit() ) {
// Print the fields
if (fields != null && !fields.isEmpty()) {
for (FieldData curf : fields) {
curf.print();
}
}
printMemberDataList(fields);
// Print the methods
if (methods != null && !methods.isEmpty()) {
for (MethodData curm : methods) {
boolean skipBlankLine = false;
curm.print(skipBlankLine);
}
out.println();
}
printMemberDataList(methods);
// Print the Record (since class file 58.65535 JEP 359)
if( record != null && !record.isEmpty()) {
if( record != null ) {
record.print();
}
@ -478,11 +476,9 @@ printSugar:
}
out.println();
}
out.println("} // end Class " + className + sourceName);
out.println(format("} // end Class %s%s",
className,
sourceName != null ? " compiled from \"" + sourceName +"\"" : ""));
} else {
// Print module attributes
moduleData.print();
@ -505,11 +501,27 @@ printSugar:
return moduleData != null;
}
private void printMemberDataList( List<? extends MemberData> list) throws IOException {
if( list != null ) {
int count = list.size();
if( count > 0 ) {
for( int i=0; i < count; i++ ) {
MemberData md = list.get(i);
md.setIndent(Options.BODY_INDENT);
if( i !=0 && md.getAnnotationsCount() > 0 )
out.println();
md.print();
}
out.println();
}
}
}
private List<IOException> getIssues() {
return this.pool.pool.stream().
filter(c->c!=null).
filter(Objects::nonNull).
filter(c->c.getIssue() != null).
map(c->c.getIssue()).
map(ConstantPool.Constant::getIssue).
collect(Collectors.toList());
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,9 +22,7 @@
*/
package org.openjdk.asmtools.jdis;
import static org.openjdk.asmtools.jasm.Tables.*;
import static org.openjdk.asmtools.jasm.OpcodeTables.*;
import static org.openjdk.asmtools.jdis.Utils.commentString;
import org.openjdk.asmtools.jasm.Tables;
import java.io.DataInputStream;
import java.io.IOException;
@ -32,90 +30,32 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import static org.openjdk.asmtools.jasm.OpcodeTables.Opcode;
import static org.openjdk.asmtools.jasm.OpcodeTables.opcode;
import static org.openjdk.asmtools.jasm.Tables.*;
import static org.openjdk.asmtools.jasm.Tables.AttrTag.ATT_RuntimeInvisibleTypeAnnotations;
import static org.openjdk.asmtools.jasm.Tables.AttrTag.ATT_RuntimeVisibleTypeAnnotations;
import static org.openjdk.asmtools.jdis.Utils.commentString;
/**
*
* Code data for a code attribute in method members in a class of the Java Disassembler
*/
public class CodeData {
public class CodeData extends Indenter {
/*-------------------------------------------------------- */
/* Code Data inner classes */
class LineNumData {
short start_pc, line_number;
public LineNumData() {
}
public LineNumData(DataInputStream in) throws IOException {
start_pc = in.readShort();
line_number = in.readShort();
//traceln(" line:"+start_pc+":="+line_number);
}
}
public static class LocVarData {
short start_pc, length, name_cpx, sig_cpx, slot;
public LocVarData() {
}
public LocVarData(DataInputStream in) throws IOException {
start_pc = in.readShort();
length = in.readShort();
name_cpx = in.readShort();
sig_cpx = in.readShort();
slot = in.readShort();
// cls.traceln(" var #"+name_cpx+" start:"+start_pc
// +" length:"+length+"sig_cpx:"+sig_cpx+" sig_cpx:"+sig_cpx);
}
}
/*-------------------------------------------------------- */
/* CodeData Fields */
/**
* Raw byte array for the byte codes
*/
protected byte[] code;
/**
* Limit for the stack size
*/
protected int max_stack;
/* CodeData Fields */
/**
* Limit for the number of local vars
*/
protected int max_locals;
/**
* (parsed) Trap table, describes exceptions caught
*/
private ArrayList<TrapData> trap_table = new ArrayList<>(0); // TrapData
/**
* (parsed) Line Number table, describes source lines associated with ByteCode indexes
*/
private ArrayList<LineNumData> lin_num_tb = new ArrayList<>(0); // LineNumData
/**
* (parsed) Local Variable table, describes variable scopes associated with ByteCode
* indexes
*/
private ArrayList<LocVarData> loc_var_tb = new ArrayList<>(0); // LocVarData
/**
* (parsed) stack map table, describes compiler hints for stack rep, associated with
* ByteCode indexes
*/
private ArrayList<StackMapData> stack_map = null;
/**
* (parsed) reversed bytecode index hash, associates labels with ByteCode indexes
*/
private HashMap<Integer, iAtt> iattrs = new HashMap<>();
/**
* The remaining attributes of this class
*/
@ -124,15 +64,49 @@ public class CodeData {
// internal references
protected ClassData cls;
protected MethodData meth;
private PrintWriter out;
/*-------------------------------------------------------- */
/**
* (parsed) Trap table, describes exceptions caught
*/
private ArrayList<TrapData> trap_table = new ArrayList<>(0); // TrapData
/**
* (parsed) Line Number table, describes source lines associated with ByteCode indexes
*/
private ArrayList<LineNumData> lin_num_tb = new ArrayList<>(0); // LineNumData
/**
* (parsed) Local Variable table, describes variable scopes associated with ByteCode
* indexes
*/
private ArrayList<LocVarData> loc_var_tb = new ArrayList<>(0); // LocVarData
/**
* (parsed) stack map table, describes compiler hints for stack rep, associated with
* ByteCode indexes
*/
private ArrayList<StackMapData> stack_map = null;
/**
* The visible type annotations for this method
*/
private ArrayList<TypeAnnotationData> visibleTypeAnnotations;
/**
* The invisible type annotations for this method
*/
private ArrayList<TypeAnnotationData> invisibleTypeAnnotations;
/**
* (parsed) reversed bytecode index hash, associates labels with ByteCode indexes
*/
private HashMap<Integer, iAtt> iattrs = new HashMap<>();
private PrintWriter out;
public CodeData(MethodData meth) {
this.meth = meth;
this.cls = meth.cls;
this.out = cls.out;
}
private static int align(int n) {
return (n + 3) & ~3;
}
/*-------------------------------------------------------- */
private int getbyte(int pc) {
return code[pc];
}
@ -153,10 +127,6 @@ public class CodeData {
return (getShort(pc) << 16) | (getShort(pc + 2) & 0xFFFF);
}
private static int align(int n) {
return (n + 3) & ~3;
}
protected iAtt get_iAtt(int pc) {
Integer PC = pc;
iAtt res = iattrs.get(PC);
@ -167,14 +137,13 @@ public class CodeData {
return res;
}
/*========================================================*/
/* Read Methods */
private void readLineNumTable(DataInputStream in) throws IOException {
int len = in.readInt(); // attr_length
int numlines = in.readUnsignedShort();
lin_num_tb = new ArrayList<>(numlines);
TraceUtils.traceln(" CodeAttr: LineNumTable[" + numlines + "] len=" + len);
TraceUtils.traceln(3, "CodeAttr: LineNumTable[" + numlines + "] len=" + len);
for (int l = 0; l < numlines; l++) {
lin_num_tb.add(new LineNumData(in));
}
@ -184,7 +153,7 @@ public class CodeData {
int len = in.readInt(); // attr_length
int numlines = in.readUnsignedShort();
loc_var_tb = new ArrayList<>(numlines);
TraceUtils.traceln(" CodeAttr: LocalVariableTable[" + numlines + "] len=" + len);
TraceUtils.traceln(3, "CodeAttr: LocalVariableTable[" + numlines + "] len=" + len);
for (int l = 0; l < numlines; l++) {
loc_var_tb.add(new LocVarData(in));
}
@ -192,7 +161,7 @@ public class CodeData {
private void readTrapTable(DataInputStream in) throws IOException {
int trap_table_len = in.readUnsignedShort();
TraceUtils.traceln(" CodeAttr: TrapTable[" + trap_table_len + "]");
TraceUtils.traceln(3, "CodeAttr: TrapTable[" + trap_table_len + "]");
trap_table = new ArrayList<>(trap_table_len);
for (int l = 0; l < trap_table_len; l++) {
trap_table.add(new TrapData(in, l));
@ -202,7 +171,7 @@ public class CodeData {
private void readStackMap(DataInputStream in) throws IOException {
int len = in.readInt(); // attr_length
int stack_map_len = in.readUnsignedShort();
TraceUtils.traceln(" CodeAttr: Stack_Map: attrlen=" + len + " num=" + stack_map_len);
TraceUtils.traceln(3, "CodeAttr: Stack_Map: attrlen=" + len + " num=" + stack_map_len);
stack_map = new ArrayList<>(stack_map_len);
StackMapData.prevFramePC = 0;
for (int k = 0; k < stack_map_len; k++) {
@ -213,7 +182,7 @@ public class CodeData {
private void readStackMapTable(DataInputStream in) throws IOException {
int len = in.readInt(); // attr_length
int stack_map_len = in.readUnsignedShort();
TraceUtils.traceln(" CodeAttr: Stack_Map_Table: attrlen=" + len + " num=" + stack_map_len);
TraceUtils.traceln(3, "CodeAttr: Stack_Map_Table: attrlen=" + len + " num=" + stack_map_len);
stack_map = new ArrayList<>(stack_map_len);
StackMapData.prevFramePC = 0;
for (int k = 0; k < stack_map_len; k++) {
@ -221,13 +190,33 @@ public class CodeData {
}
}
private void readTypeAnnotations(DataInputStream in, boolean isInvisible) throws IOException {
int attrLength = in.readInt();
// Read Type Annotations Attr
int count = in.readShort();
ArrayList<TypeAnnotationData> tannots = new ArrayList<>(count);
TraceUtils.traceln(3, "CodeAttr: Runtime" +
(isInvisible ? "Inv" : "V") +
"isibleTypeAnnotation: attrlen=" +
attrLength + " num=" + count);
for (int index = 0; index < count; index++) {
TraceUtils.traceln("\t\t\t[" + index +"]:");
TypeAnnotationData tannot = new TypeAnnotationData(isInvisible, cls);
tannot.read(in);
tannots.add(tannot);
}
if (isInvisible) {
invisibleTypeAnnotations = tannots;
} else {
visibleTypeAnnotations = tannots;
}
}
/**
*
* read
*
* <p>
* read and resolve the code attribute data called from MethodData. precondition:
* NumFields has already been read from the stream.
*
*/
public void read(DataInputStream in, int codeattrlen) throws IOException {
@ -235,7 +224,10 @@ public class CodeData {
max_stack = in.readUnsignedShort();
max_locals = in.readUnsignedShort();
int codelen = in.readInt();
TraceUtils.traceln(" CodeAttr: Codelen=" + codelen + " fulllen=" + codeattrlen + " max_stack=" + max_stack + " max_locals=" + max_locals);
TraceUtils.traceln(3, "CodeAttr: Codelen=" + codelen +
" fulllen=" + codeattrlen +
" max_stack=" + max_stack +
" max_locals=" + max_locals);
// read the raw code bytes
code = new byte[codelen];
@ -246,14 +238,14 @@ public class CodeData {
// Read any attributes of the Code Attribute
int nattr = in.readUnsignedShort();
TraceUtils.traceln(" CodeAttr: add.attr:" + nattr);
TraceUtils.traceln(3, "CodeAttr: add.attr:" + nattr);
for (int k = 0; k < nattr; k++) {
int name_cpx = in.readUnsignedShort();
// verify the Attrs name
ConstantPool.Constant name_const = cls.pool.getConst(name_cpx);
if (name_const != null && name_const.tag == ConstantPool.TAG.CONSTANT_UTF8) {
String attrname = cls.pool.getString(name_cpx);
TraceUtils.traceln(" CodeAttr: attr: " + attrname);
TraceUtils.traceln(3, "CodeAttr: attr: " + attrname);
// process the attr
AttrTag attrtag = attrtag(attrname);
switch (attrtag) {
@ -269,6 +261,10 @@ public class CodeData {
case ATT_StackMapTable:
readStackMapTable(in);
break;
case ATT_RuntimeVisibleTypeAnnotations:
case ATT_RuntimeInvisibleTypeAnnotations:
readTypeAnnotations(in, attrtag == ATT_RuntimeInvisibleTypeAnnotations);
break;
default:
AttrData attr = new AttrData(cls);
int attrlen = in.readInt(); // attr_length
@ -350,7 +346,7 @@ public class CodeData {
} // end checkForLabelRef
private void loadLabelTable() {
for (int pc = 0; pc < code.length;) {
for (int pc = 0; pc < code.length; ) {
pc = pc + checkForLabelRef(pc);
}
}
@ -382,7 +378,6 @@ public class CodeData {
}
}
/*========================================================*/
/* Print Methods */
private void PrintConstant(int cpx) {
@ -447,7 +442,7 @@ public class CodeData {
return 1;
}
out.print(opcode.parsekey());
// TraceUtils.traceln("****** [CodeData.printInstr]: got an '" + opcode.parsekey() + "' [" + opc + "] instruction ****** ");
// TraceUtils.traceln("****** [CodeData.printInstr]: got an '" + opcode.parseKey() + "' [" + opc + "] instruction ****** ");
switch (opcode) {
case opc_aload:
case opc_astore:
@ -525,7 +520,19 @@ public class CodeData {
out.print(" BOGUS TYPE:" + type);
}
return 2;
case opc_anewarray: {
case opc_anewarray:
case opc_ldc_w:
case opc_ldc2_w:
case opc_instanceof:
case opc_checkcast:
case opc_new:
case opc_putstatic:
case opc_getstatic:
case opc_putfield:
case opc_getfield:
case opc_invokevirtual:
case opc_invokespecial:
case opc_invokestatic: {
int index = getUShort(pc + 1);
if (pr_cpx) {
out.print("\t#" + index + "; //");
@ -547,28 +554,8 @@ public class CodeData {
PrintConstant(index);
return 2;
}
case opc_ldc_w:
case opc_ldc2_w:
case opc_instanceof:
case opc_checkcast:
case opc_new:
case opc_putstatic:
case opc_getstatic:
case opc_putfield:
case opc_getfield:
case opc_invokevirtual:
case opc_invokespecial:
case opc_invokestatic: {
int index = getUShort(pc + 1);
if (pr_cpx) {
out.print("\t#" + index + "; //");
}
PrintConstant(index);
return 3;
}
case opc_invokeinterface: {
int index = getUShort(pc + 1), nargs = getUbyte(pc + 3);
// getUbyte(pc + 4); // reserved byte
if (pr_cpx) {
out.print("\t#" + index + ", " + nargs + "; //");
PrintConstant(index);
@ -579,6 +566,7 @@ public class CodeData {
return 5;
}
case opc_invokedynamic: { // JSR-292
cls.pool.setPrintTAG(true);
int index = getUShort(pc + 1);
// getUbyte(pc + 3); // reserved byte
// getUbyte(pc + 4); // reserved byte
@ -588,6 +576,7 @@ public class CodeData {
} else {
PrintConstant(index);
}
cls.pool.setPrintTAG(false);
return 5;
}
case opc_multianewarray: {
@ -631,11 +620,9 @@ public class CodeData {
} // end printInstr
/**
*
* print
*
* <p>
* prints the code data to the current output stream. called from MethodData.
*
*/
public void print() throws IOException {
if (!lin_num_tb.isEmpty()) {
@ -658,10 +645,10 @@ public class CodeData {
// Need to print ParamAnnotations here.
meth.printPAnnotations();
out.println("{");
out.println(getIndentString() + "{");
iAtt iatt = iattrs.get(0);
for (int pc = 0; pc < code.length;) {
for (int pc = 0; pc < code.length; ) {
if (iatt != null) {
iatt.printBegins(); // equ. print("\t");
} else {
@ -693,7 +680,47 @@ public class CodeData {
iatt.printStackMap();
out.println();
}
out.println("}");
// print TypeAnnotations
if (visibleTypeAnnotations != null) {
out.println();
for (TypeAnnotationData visad : visibleTypeAnnotations) {
visad.print(out, getIndentString());
out.println();
}
}
if (invisibleTypeAnnotations != null) {
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
invisad.print(out, getIndentString());
out.println();
}
}
// end of code
out.println(getIndentString() + "}");
}
public static class LocVarData {
short start_pc, length, name_cpx, sig_cpx, slot;
public LocVarData(DataInputStream in) throws IOException {
start_pc = in.readShort();
length = in.readShort();
name_cpx = in.readShort();
sig_cpx = in.readShort();
slot = in.readShort();
}
}
/* Code Data inner classes */
class LineNumData {
short start_pc, line_number;
public LineNumData(DataInputStream in) throws IOException {
start_pc = in.readShort();
line_number = in.readShort();
}
}
}

View File

@ -23,6 +23,7 @@
package org.openjdk.asmtools.jdis;
import org.openjdk.asmtools.asmutils.HexUtils;
import org.openjdk.asmtools.asmutils.StringUtils;
import java.io.DataInputStream;
import java.io.IOException;
@ -31,8 +32,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static java.lang.String.format;
import static org.openjdk.asmtools.jdis.Utils.commentString;
/**
@ -46,6 +47,16 @@ public class ConstantPool {
private static final Hashtable<Byte, TAG> taghash = new Hashtable<>();
private static final Hashtable<Byte, SUBTAG> subtaghash = new Hashtable<>();
private boolean printTAG = false;
public void setPrintTAG(boolean value) {
this.printTAG = value;
}
public String getPrintedTAG(TAG tag) {
return (this.printTAG) ? tag.tagname + " " : "" ;
}
class Indent {
private int length, offset, step;
@ -77,7 +88,7 @@ public class ConstantPool {
* A Tag descriptor of constants in the constant pool
*
*/
static public enum TAG {
public enum TAG {
CONSTANT_UTF8 ((byte) 1, "Asciz", "CONSTANT_UTF8"),
CONSTANT_UNICODE ((byte) 2, "unicorn", "CONSTANT_UNICODE"),
CONSTANT_INTEGER ((byte) 3, "int", "CONSTANT_INTEGER"),
@ -105,7 +116,6 @@ public class ConstantPool {
value = val;
tagname = tgname;
printval = print;
// taghash.put(new Byte(val), this);
}
public byte value() {
@ -124,6 +134,7 @@ public class ConstantPool {
public String toString() {
return "<" + tagname + "> ";
}
};
@ -276,41 +287,7 @@ public class ConstantPool {
@Override
public String stringVal() {
StringBuilder sb = new StringBuilder();
String s = value;
sb.append('\"');
for (int k = 0; k < s.length(); k++) {
char c = s.charAt(k);
switch (c) {
case '\t':
sb.append('\\').append('t');
break;
case '\n':
sb.append('\\').append('n');
break;
case '\r':
sb.append('\\').append('r');
break;
case '\b':
sb.append('\\').append('b');
break;
case '\f':
sb.append('\\').append('f');
break;
case '\"':
sb.append('\\').append('\"');
break;
case '\'':
sb.append('\\').append('\'');
break;
case '\\':
sb.append('\\').append('\\');
break;
default:
sb.append(c);
}
}
return sb.append('\"').toString();
return StringUtils.Utf8ToString(value);
}
@Override
@ -532,6 +509,7 @@ public class ConstantPool {
class CPX2 extends Constant {
int value1, value2;
CPX2(TAG tagval, int cpx1, int cpx2) {
super(tagval);
this.value1 = cpx1;
@ -546,7 +524,7 @@ public class ConstantPool {
case CONSTANT_FIELD:
case CONSTANT_METHOD:
case CONSTANT_INTERFACEMETHOD:
str = getShortClassName(getClassName(value1), cd.pkgPrefix) + "." + StringValue(value2);
str = getPrintedTAG(tag) + getShortClassName(getClassName(value1), cd.pkgPrefix) + "." + StringValue(value2);
break;
case CONSTANT_NAMEANDTYPE:
str = getName(value1) + ":" + StringValue(value2);
@ -946,7 +924,7 @@ public class ConstantPool {
* getShortClassName
*
* shortens a class name (if the class is in the given package). works with a CP index
* to a ConstantClasss.
* to a ConstantClass.
*
*/
public String getShortClassName(int cpx, String pkgPrefix) {
@ -1018,7 +996,7 @@ public class ConstantPool {
* a tag descriptor in the beginning.
*
*/
String ConstantStrValue(int cpx) {
public String ConstantStrValue(int cpx) {
if (cpx == 0) {
return "#0";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,13 +22,16 @@
*/
package org.openjdk.asmtools.jdis;
import org.openjdk.asmtools.jasm.JasmTokens;
import org.openjdk.asmtools.jasm.Modifiers;
import java.io.DataInputStream;
import java.io.IOException;
import static java.lang.String.format;
import static org.openjdk.asmtools.jasm.Tables.AttrTag;
import static org.openjdk.asmtools.jasm.Tables.CF_Context;
import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
/**
* Field data for field members in a class of the Java Disassembler
@ -37,15 +40,11 @@ public class FieldData extends MemberData {
// CP index to the field name
protected int name_cpx;
// CP index to the field type
protected int sig_cpx;
// CP index to the field value
protected int type_cpx;
// CP index to the field value
protected int value_cpx = 0;
public static final String initialTab = "";
public FieldData(ClassData cls) {
super(cls);
memberType = "FieldData";
@ -56,9 +55,16 @@ public class FieldData extends MemberData {
// Read the Attributes
boolean handled = true;
switch (attrtag) {
case ATT_Signature:
if( signature != null ) {
traceln("Record attribute: more than one attribute Signature are in component.attribute_info_attributes[attribute_count]");
traceln("Last one will be used.");
}
signature = new SignatureData(cls).read(in, attrlen);
break;
case ATT_ConstantValue:
if (attrlen != 2) {
throw new ClassFormatError("invalid ConstantValue attr length");
throw new ClassFormatError(format("%s: Invalid attribute length #%d", AttrTag.ATT_ConstantValue.printval(), attrlen));
}
value_cpx = in.readUnsignedShort();
break;
@ -77,71 +83,44 @@ public class FieldData extends MemberData {
// read the Fields CP indexes
access = in.readUnsignedShort();
name_cpx = in.readUnsignedShort();
sig_cpx = in.readUnsignedShort();
TraceUtils.traceln(" FieldData: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx)
+ " sig[" + sig_cpx + "]=" + cls.pool.getString(sig_cpx));
type_cpx = in.readUnsignedShort();
// Read the attributes
readAttributes(in);
//
TraceUtils.traceln(2,
format("FieldData: name[%d]=%s type[%d]=%s%s",
name_cpx, cls.pool.getString(name_cpx),
type_cpx, cls.pool.getString(type_cpx),
signature != null ? signature : ""));
}
/**
* Prints the field data to the current output stream. called from ClassData.
*/
@Override
public void print() throws IOException {
// Print annotations first
// Print the Annotations
if (visibleAnnotations != null) {
out.println();
for (AnnotationData visad : visibleAnnotations) {
visad.print(out, initialTab);
}
}
if (invisibleAnnotations != null) {
out.println();
for (AnnotationData invisad : invisibleAnnotations) {
invisad.print(out, initialTab);
}
}
super.printAnnotations(getIndentString());
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();
}
}
StringBuilder bodyPrefix = new StringBuilder(getIndentString()).append(Modifiers.accessString(access, CF_Context.CTX_FIELD));
StringBuilder tailPrefix = new StringBuilder();
boolean pr_cpx = options.contains(Options.PR.CPX);
out.print(Modifiers.accessString(access, CF_Context.CTX_FIELD));
if (isSynthetic) {
out.print("synthetic ");
bodyPrefix.append(JasmTokens.Token.SYNTHETIC.parseKey()).append(' ');
}
if (isDeprecated) {
out.print("deprecated ");
}
out.print("Field ");
if (pr_cpx) {
out.print("#" + name_cpx + ":#" + sig_cpx);
} else {
out.print(cls.pool.getName(name_cpx) + ":" + cls.pool.getName(sig_cpx));
bodyPrefix.append(JasmTokens.Token.DEPRECATED.parseKey()).append(' ');
}
// field
bodyPrefix.append(JasmTokens.Token.FIELDREF.parseKey()).append(' ');
if (value_cpx != 0) {
out.print("\t= ");
cls.pool.PrintConstant(cls.out, value_cpx);
}
if (pr_cpx) {
out.println(";\t // " + cls.pool.getName(name_cpx) + ":" + cls.pool.getName(sig_cpx));
} else {
out.println(";");
tailPrefix.append("\t= ").append(cls.pool.ConstantStrValue(value_cpx));
}
printVar(bodyPrefix, tailPrefix,name_cpx, type_cpx);
}
} // end FieldData

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2020, 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.jdis;
public class Indenter {
private int indentLength;
public Indenter(int indentLength) {
this.indentLength = indentLength;
}
public Indenter() {
this.indentLength = Options.BODY_INDENT;
}
/**
* Returns current indentation length.
*
* @return current indentation length.
*/
public int indent() {
return indentLength;
}
/**
* Increases indentation length.
*
* @param indentLength new indent length
*
* @throws IllegalArgumentException if indentLength is negative.
*/
public Indenter setIndent(int indentLength) {
if (indentLength < 0) {
throw new IllegalArgumentException("indent length can't be negative");
}
this.indentLength = indentLength;
return this;
}
/**
* Increases indentation length.
*
* @param increase length to increase by.
*
* @throws IllegalArgumentException if increase is negative.
*/
public Indenter increaseIndent(int increase) {
if (increase < 0) {
throw new IllegalArgumentException("indent length can't be negative");
}
setIndent(indent() + increase);
return this;
}
/**
* Decreases indentation length.
*
* @param decrease length to decrease by
*
* @throws IllegalArgumentException if decrease is negative, or if decrease is greater than
* {@link #indent() current indentation length}.
*/
public Indenter decreaseIndent(int decrease) {
if (decrease < 0) {
throw new IllegalArgumentException("decrease can't be negative");
}
setIndent(indent() - decrease);
return this;
}
/**
* Creates indent string based on current indent size.
*/
public String getIndentString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indent(); i++) {
sb.append(' ');
}
return sb.toString();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -30,11 +30,7 @@ import java.io.IOException;
/**
*
*/
class InnerClassData {
/*-------------------------------------------------------- */
/* InnerClassData Fields */
private Options options = Options.OptionObject();
class InnerClassData extends Indenter {
ClassData cls;
int inner_class_info_index;
@ -55,8 +51,8 @@ class InnerClassData {
} // end read
public void print() throws IOException {
boolean pr_cpx = options.contains(Options.PR.CPX);
cls.out.print(Modifiers.accessString(access, CF_Context.CTX_INNERCLASS));
boolean pr_cpx = Options.OptionObject().contains(Options.PR.CPX);
cls.out.print(getIndentString() + Modifiers.accessString(access, CF_Context.CTX_INNERCLASS));
cls.out.print("InnerClass ");
if (pr_cpx) {
if (inner_name_index != 0) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -41,7 +41,7 @@ public class Main extends Tool {
public static final I18NResourceBundle i18n
= I18NResourceBundle.getBundleForClass(Main.class);
public Main(PrintWriter out, PrintWriter err, String programName) {
public Main(PrintWriter out, PrintWriter err, String programName) {
super(out, err, programName);
// tool specific initialization
options = Options.OptionObject();
@ -66,7 +66,7 @@ public class Main extends Tool {
/**
* Run the disassembler
*/
public synchronized boolean disasm(String argv[]) {
public synchronized boolean disasm(String argv[]) {
ArrayList<String> files = new ArrayList<>();
// Parse arguments
@ -105,27 +105,23 @@ public class Main extends Tool {
return false;
}
for (String inpname : files) {
if (inpname == null) {
for (String fname : files) {
if (fname == null) {
continue;
} // cross out by CompilerChoice.compile
try {
DataInputStream dataInputStream = getDataInputStream(inpname);
if( dataInputStream == null )
return false;
ClassData cc = new ClassData(out, this);
cc.read(dataInputStream);
cc.read(fname);
cc.print();
dataInputStream.close();
continue;
} catch (Error ee) {
if (DebugFlag.getAsBoolean())
ee.printStackTrace();
error(i18n.getString("jdis.error.fatal_error", inpname));
error(i18n.getString("jdis.error.fatal_error", fname));
} catch (Exception ee) {
if (DebugFlag.getAsBoolean())
ee.printStackTrace();
error(i18n.getString("jdis.error.fatal_exception", inpname));
error(i18n.getString("jdis.error.fatal_exception", fname));
}
return false;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -28,20 +28,23 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import static java.lang.String.format;
/**
* Base class for ClassData, MethodData, FieldData and RecordData(JEP 360)
*/
public class MemberData {
public abstract class MemberData extends Indenter {
/**
* access flags (modifiers)
*/
// access flags (modifiers)
protected int access;
// flags
protected boolean isSynthetic = false;
protected boolean isDeprecated = false;
// Signature can be located in ClassFile, field_info, method_info, and component_info
protected SignatureData signature;
/**
* The visible annotations for this class, member( field or method) or record component
*/
@ -68,12 +71,14 @@ public class MemberData {
protected ArrayList<AttrData> attrs;
// internal references
protected Options options = Options.OptionObject();
protected final Options options = Options.OptionObject();
protected final boolean pr_cpx = options.contains(Options.PR.CPX);;
protected ClassData cls;
protected PrintWriter out;
protected String memberType = "";
public MemberData(ClassData cls) {
this();
init(cls);
}
@ -83,26 +88,85 @@ public class MemberData {
public void init(ClassData cls) {
this.out = cls.out;
this.cls = cls;
this.options = cls.options;
}
protected boolean handleAttributes(DataInputStream in, Tables.AttrTag attrtag, int attrlen) throws IOException {
// sub-classes override
return false;
}
protected abstract void print() throws IOException;
final protected int getAnnotationsCount() {
return ((visibleAnnotations == null) ? 0 : visibleAnnotations.size()) +
((invisibleAnnotations == null) ? 0 : invisibleAnnotations.size()) +
((visibleTypeAnnotations == null) ? 0 : visibleTypeAnnotations.size()) +
((invisibleTypeAnnotations == null) ? 0 : invisibleTypeAnnotations.size());
}
final protected void printAnnotations(String initialTab) {
if( getAnnotationsCount() > 0 ) {
if (visibleAnnotations != null) {
for (AnnotationData visad : visibleAnnotations) {
// out.print(initialTab);
visad.print(out, initialTab);
out.println();
}
}
if (invisibleAnnotations != null) {
for (AnnotationData invisad : invisibleAnnotations) {
invisad.print(out, initialTab);
out.println();
}
}
if (visibleTypeAnnotations != null) {
for (TypeAnnotationData visad : visibleTypeAnnotations) {
visad.print(out, initialTab);
out.println();
}
}
if (invisibleTypeAnnotations != null) {
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
invisad.print(out, initialTab);
out.println();
}
}
}
}
protected void printVar(StringBuilder bodyPrefix, StringBuilder tailPrefix, int name_cpx, int type_cpx) {
if( pr_cpx ) {
bodyPrefix.append('#').append(name_cpx).append(":#").append(type_cpx);
tailPrefix.append(";\t // ").append(cls.pool.getName(name_cpx)).append(':').append(cls.pool.getName(type_cpx));
} else {
bodyPrefix.append(cls.pool.getName(name_cpx)).append(':').append(cls.pool.getName(type_cpx));
tailPrefix.append(';');
}
if (signature != null) {
signature.print(bodyPrefix.append(':').toString(), tailPrefix.append( pr_cpx ? ":" : "" ).toString());
} else {
out.print(bodyPrefix);
out.print(tailPrefix);
}
out.println();
}
protected void readAttributes(DataInputStream in) throws IOException {
// Read the Attributes
int natt = in.readUnsignedShort();
TraceUtils.traceln("natt=" + natt);
attrs = new ArrayList<>(natt);
TraceUtils.traceln(memberType + " - Attributes: " + natt);
TraceUtils.traceln(format("%s - Attributes[%d]", memberType , natt));
AttrData attr;
for (int k = 0; k < natt; k++) {
int name_cpx = in.readUnsignedShort();
attr = new AttrData(cls);
attrs.add(attr);
String attr_name = cls.pool.getString(name_cpx);
TraceUtils.traceln(" " + memberType + ": #" + k + " name[" + name_cpx + "]=" + attr_name);
TraceUtils.traceln(format(" #%d name[%d]=\"%s\"", k, name_cpx, attr_name));
Tables.AttrTag tag = Tables.attrtag(attr_name);
int attrlen = in.readInt();
switch (tag) {
@ -168,5 +232,4 @@ public class MemberData {
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -37,11 +37,6 @@ import static org.openjdk.asmtools.jasm.Tables.CF_Context;
*/
public class MethodData extends MemberData {
/*-------------------------------------------------------- */
/* MethodData Fields */
public static final String initialTab = "";
/*-------------------------------------------------------- */
/**
* CP index to the method name
*/
@ -67,7 +62,7 @@ public class MethodData extends MemberData {
/**
* The invisible parameter annotations for this method
*/
protected AnnotElem.AnnotValue defaultAnnotation;
protected AnnotationElement.AnnotValue defaultAnnotation;
/**
* The code data for this method. May be null
*/
@ -103,17 +98,17 @@ public class MethodData extends MemberData {
break;
case ATT_RuntimeVisibleParameterAnnotations:
case ATT_RuntimeInvisibleParameterAnnotations:
boolean invisible1 = (attrtag == AttrTag.ATT_RuntimeInvisibleParameterAnnotations);
ParameterAnnotationData pannots = new ParameterAnnotationData(cls, invisible1);
boolean invisible = (attrtag == AttrTag.ATT_RuntimeInvisibleParameterAnnotations);
ParameterAnnotationData pannots = new ParameterAnnotationData(cls, invisible);
pannots.read(in);
if (invisible1) {
if (invisible) {
invisibleParameterAnnotations = pannots;
} else {
visibleParameterAnnotations = pannots;
}
break;
case ATT_AnnotationDefault:
defaultAnnotation = AnnotElem.readValue(in, cls, false);
defaultAnnotation = AnnotationElement.readValue(in, cls, false);
break;
default:
handled = false;
@ -132,9 +127,8 @@ public class MethodData extends MemberData {
access = in.readUnsignedShort(); // & MM_METHOD; // Q
name_cpx = in.readUnsignedShort();
sig_cpx = in.readUnsignedShort();
TraceUtils.traceln(" MethodData: {modifiers}: " + Modifiers.toString(access, CF_Context.CTX_METHOD));
TraceUtils.traceln(" MethodData: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx)
+ " sig[" + sig_cpx + "]=" + cls.pool.getString(sig_cpx));
TraceUtils.traceln(2,"MethodData: {modifiers}: " + Modifiers.toString(access, CF_Context.CTX_METHOD),
" MethodData: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx) + " sig[" + sig_cpx + "]=" + cls.pool.getString(sig_cpx));
// Read the attributes
readAttributes(in);
}
@ -142,11 +136,11 @@ public class MethodData extends MemberData {
private void readExceptions(DataInputStream in) throws IOException {
// this is not really a CodeAttr attribute, it's part of the CodeAttr
int exc_table_len = in.readUnsignedShort();
TraceUtils.traceln(" ExceptionsAttr[" + exc_table_len + "]");
TraceUtils.traceln(3,"ExceptionsAttr[" + exc_table_len + "]");
exc_table = new int[exc_table_len];
for (int l = 0; l < exc_table_len; l++) {
int exc = in.readShort();
TraceUtils.traceln(" throws:#" + exc);
TraceUtils.traceln(4,"throws:#" + exc);
exc_table[l] = exc;
}
}
@ -154,12 +148,12 @@ public class MethodData extends MemberData {
private void readMethodParameters(DataInputStream in) throws IOException {
// this is not really a CodeAttr attribute, it's part of the CodeAttr
int num_params = in.readUnsignedByte();
TraceUtils.traceln(" MethodParametersAttr[" + num_params + "]");
TraceUtils.traceln(3,"MethodParametersAttr[" + num_params + "]");
paramNames = new ArrayList<>(num_params);
for (int l = 0; l < num_params; l++) {
short pname_cpx = (short) in.readUnsignedShort();
int paccess = in.readUnsignedShort();
TraceUtils.traceln(" P[" + l + "] ={ name[" + pname_cpx + "]: " + cls.pool.getString(pname_cpx)
TraceUtils.traceln(4,"P[" + l + "] ={ name[" + pname_cpx + "]: " + cls.pool.getString(pname_cpx)
+ " modifiers [" + paccess + "]: " + Modifiers.toString(paccess, CF_Context.CTX_METHOD) + "}");
paramNames.add(l, new ParamNameData(pname_cpx, paccess));
}
@ -218,12 +212,12 @@ public class MethodData extends MemberData {
// Print the Parameter name
if (pname != null) {
out.print(Token.PARAM_NAME.parsekey());
out.print(Token.LBRACE.parsekey());
out.print(Token.PARAM_NAME.parseKey());
out.print(Token.LBRACE.parseKey());
out.print(cls.pool.getString(pname.name_cpx));
out.print(" ");
out.print(Modifiers.toString(pname.access, CF_Context.CTX_METHOD));
out.print(Token.RBRACE.parsekey());
out.print(Token.RBRACE.parseKey());
out.print(" ");
}
@ -233,7 +227,7 @@ public class MethodData extends MemberData {
if (!firstTime) {
out.print("\t ");
}
annot.print(out, initialTab);
annot.print(out, getIndentString());
// out.println();
firstTime = false;
}
@ -245,7 +239,7 @@ public class MethodData extends MemberData {
if (!firstTime) {
out.print("\t ");
}
annot.print(out, initialTab);
annot.print(out, getIndentString());
// out.println();
firstTime = false;
}
@ -253,68 +247,30 @@ public class MethodData extends MemberData {
// Reset the line, if there were parameters
if ((pname != null) || !nullAnnots) {
out.println("");
out.println();
}
}
}
/*========================================================*/
/* Print Methods */
/**
* Prints the method data to the current output stream. called from ClassData.
*/
public void print(boolean skipBlankLine) throws IOException {
// Print the Annotations
if (visibleAnnotations != null) {
out.println();
for (AnnotationData visad : visibleAnnotations) {
visad.print(out, initialTab);
out.println();
skipBlankLine = true;
}
}
if (invisibleAnnotations != null) {
out.println();
for (AnnotationData invisad : invisibleAnnotations) {
invisad.print(out, initialTab);
out.println();
skipBlankLine = true;
}
}
@Override
public void print() throws IOException {
if (visibleTypeAnnotations != null) {
out.println();
for (TypeAnnotationData visad : visibleTypeAnnotations) {
visad.print(out, initialTab);
out.println();
skipBlankLine = true;
}
}
if (invisibleTypeAnnotations != null) {
out.println();
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
invisad.print(out, initialTab);
out.println();
skipBlankLine = true;
}
}
printAnnotations(getIndentString());
boolean pr_cpx = options.contains(Options.PR.CPX);
out.print(getIndentString() + Modifiers.accessString(access, CF_Context.CTX_METHOD));
if (!skipBlankLine) {
out.println();
}
out.print(Modifiers.accessString(access, CF_Context.CTX_METHOD));
if (isSynthetic) {
out.print(Token.SYNTHETIC.parsekey() + " ");
out.print(Token.SYNTHETIC.parseKey() + " ");
}
if (isDeprecated) {
out.print(Token.DEPRECATED.parsekey() + " ");
out.print(Token.DEPRECATED.parseKey() + " ");
}
out.print(Token.METHODREF.parsekey() + " ");
out.print(Token.METHODREF.parseKey() + " ");
if (pr_cpx) {
// print the CPX method descriptor
@ -328,7 +284,7 @@ public class MethodData extends MemberData {
// followed by default annotation
if (defaultAnnotation != null) {
out.print(" default { ");
defaultAnnotation.print(out, initialTab);
defaultAnnotation.print(out, getIndentString());
out.print(" }" + ((code == null && exc_table == null) ? ";" : " "));
}
// followed by exception table
@ -337,6 +293,9 @@ public class MethodData extends MemberData {
if (code != null) {
code.print();
} else {
if( exc_table != null ) {
out.print(';');
}
out.println();
}
}
@ -366,6 +325,5 @@ public class MethodData extends MemberData {
this.access = access;
this.name_cpx = name;
}
}
} // end MethodData

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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
@ -62,7 +62,7 @@ public class ModuleData {
return "N/A";
} else {
StringBuilder sb = new StringBuilder(module.getModuleFlags());
sb.append(JasmTokens.Token.MODULE.parsekey()).append(" ");
sb.append(JasmTokens.Token.MODULE.parseKey()).append(" ");
sb.append(module.getModuleName());
if (module.getModuleVersion() != null)
sb.append("// @").append(module.getModuleVersion());
@ -195,7 +195,7 @@ public class ModuleData {
}
/* Print Methods */
public void print() throws IOException {
public void print() {
if (module != null)
out.println(module.toString());
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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
@ -33,7 +33,7 @@ import java.io.IOException;
* <p>
* since class file 55.0 (JEP 181)
*/
public class NestHostData {
public class NestHostData extends Indenter{
ClassData cls;
int host_class_index;
private Options options = Options.OptionObject();
@ -52,7 +52,7 @@ public class NestHostData {
public void print() {
boolean pr_cpx = options.contains(Options.PR.CPX);
cls.out.print(JasmTokens.Token.NESTHOST.parsekey() + " ");
cls.out.print(getIndentString() + JasmTokens.Token.NESTHOST.parseKey() + " ");
if (pr_cpx) {
cls.out.print("#" + host_class_index + "; //");
}

View File

@ -40,7 +40,7 @@ import java.io.IOException;
*/
public class NestMembersData extends ClassArrayData {
public NestMembersData(ClassData cls) {
super(cls, JasmTokens.Token.NESTMEMBERS.parsekey());
super(cls, JasmTokens.Token.NESTMEMBERS.parseKey());
}
public NestMembersData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,11 +29,12 @@ import java.util.EnumSet;
*/
public class Options {
/*-------------------------------------------------------- */
public static final int BODY_INDENT = 2;
/* Options Fields */
private static Options ref;
static public enum PR {
public enum PR {
CP, // print Constant Pool
LNT, // print Line Number table

View File

@ -40,7 +40,7 @@ import java.io.IOException;
*/
public class PermittedSubtypesData extends ClassArrayData {
public PermittedSubtypesData(ClassData cls) {
super(cls, JasmTokens.Token.PERMITTEDSUBTYPES.parsekey());
super(cls, JasmTokens.Token.PERMITTEDSUBTYPES.parseKey());
}
public PermittedSubtypesData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
@ -30,6 +30,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static java.lang.String.format;
import static org.openjdk.asmtools.jasm.JasmTokens.Token.*;
import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
/**
@ -37,11 +39,10 @@ import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
* <p>
* since class file 58.65535 (JEP 359)
*/
public class RecordData {
public class RecordData extends Indenter {
private final ClassData cls;
private final boolean pr_cpx = Options.OptionObject().contains(Options.PR.CPX);
private String initialTab = " ";
private List<Component> components;
public RecordData(ClassData cls) {
@ -62,28 +63,26 @@ public class RecordData {
* Prints the record data to the current output stream. called from ClassData.
*/
public void print() throws IOException {
int bound = components.size()-1;
cls.out.println(JasmTokens.Token.RECORD.parsekey());
for(int cn = 0; cn <= bound; cn++) {
components.get(cn).print( cn == bound ? ";" : ",");
int count = components.size();
if (count > 0) {
cls.out.println(getIndentString() + RECORD.parseKey() + getIndentString() + LBRACE.parseKey());
for (int i = 0; i < count; i++) {
Component cn = components.get(i);
cn.setIndent(indent() * 2);
if (i != 0 && cn.getAnnotationsCount() > 0)
cn.out.println();
cn.print();
}
cls.out.println(getIndentString() + RBRACE.parseKey());
cls.out.println();
}
cls.out.println();
}
public boolean isEmpty() {
return components.isEmpty();
}
private class Component extends MemberData {
// CP index to the name
private int name_cpx;
// CP index to the descriptor
private int desc_cpx;
// Signature can be located in component_info
private SignatureData signature;
//
private int countAttr = 0;
// CP index to the type descriptor
private int type_cpx;
public Component(ClassData cls) {
super(cls);
@ -115,92 +114,33 @@ public class RecordData {
public Component read(DataInputStream in) throws IOException {
// read the Component CP indexes
name_cpx = in.readUnsignedShort();
desc_cpx = in.readUnsignedShort();
traceln(" RecordComponent: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx)
+ " descriptor[" + desc_cpx + "]=" + cls.pool.getString(desc_cpx));
type_cpx = in.readUnsignedShort();
traceln(2, "RecordComponent: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx)
+ " descriptor[" + type_cpx + "]=" + cls.pool.getString(type_cpx));
// Read the attributes
readAttributes(in);
// Calculate amount of attributes
countAttr = (visibleAnnotations == null ? 0 : visibleAnnotations.size()) +
(invisibleAnnotations == null ? 0 : invisibleAnnotations.size()) +
(visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size()) +
(invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations.size()) +
(signature != null ? 1 : 0);
return this;
}
public boolean isEmpty() {
return countAttr == 0;
}
private void printAnnotations(String endOfComponent) {
if( signature != null ) {
signature.print(initialTab);
countAttr--;
if(countAttr != 0)
out.println();
}
if (visibleAnnotations != null) {
for (AnnotationData visad : visibleAnnotations) {
// out.print(initialTab);
visad.print(out, initialTab);
countAttr--;
if(countAttr != 0)
out.println();
}
}
if (invisibleAnnotations != null) {
for (AnnotationData invisad : invisibleAnnotations) {
invisad.print(out, initialTab);
countAttr--;
if(countAttr != 0)
out.println();
}
}
if (visibleTypeAnnotations != null) {
for (TypeAnnotationData visad : visibleTypeAnnotations) {
visad.print(out, initialTab);
countAttr--;
if(countAttr != 0)
out.println();
}
}
if (invisibleTypeAnnotations != null) {
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
invisad.print(out, initialTab);
countAttr--;
if(countAttr != 0)
out.println();
}
}
out.println(endOfComponent);
}
/**
* Prints the component data to the current output stream. called from RecordData.
*/
public void print(String endOfComponent) throws IOException {
out.print(initialTab);
public void print() throws IOException {
// print component's attributes
super.printAnnotations(getIndentString());
// print component
StringBuilder bodyPrefix = new StringBuilder(getIndentString());
StringBuilder tailPrefix = new StringBuilder();
if (isSynthetic) {
out.print("synthetic ");
bodyPrefix.append(JasmTokens.Token.SYNTHETIC.parseKey()).append(' ');
}
if (isDeprecated) {
out.print("deprecated ");
bodyPrefix.append(JasmTokens.Token.DEPRECATED.parseKey()).append(' ');
}
// component
bodyPrefix.append(JasmTokens.Token.COMPONENT.parseKey()).append(' ');
if (pr_cpx) {
out.print("#" + name_cpx + ":#" + desc_cpx + (isEmpty() ? endOfComponent : ""));
out.println("\t // " + cls.pool.getName(name_cpx) + ":" + cls.pool.getName(desc_cpx));
} else {
out.println(cls.pool.getName(name_cpx) + ":" + cls.pool.getName(desc_cpx) + (isEmpty() ? endOfComponent : ""));
}
// print component's attributes
if (!isEmpty()) {
printAnnotations(endOfComponent);
}
printVar(bodyPrefix, tailPrefix,name_cpx, type_cpx);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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
@ -23,9 +23,13 @@
package org.openjdk.asmtools.jdis;
import org.openjdk.asmtools.jasm.Tables;
import java.io.DataInputStream;
import java.io.IOException;
import static java.lang.String.format;
/**
* The Signature attribute data
* <p>
@ -42,18 +46,23 @@ public class SignatureData {
public SignatureData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
if (attribute_length != 2) {
throw new ClassFormatError("ATT_Signature: Invalid attribute length");
throw new ClassFormatError(format("%s: Invalid attribute length #%d", Tables.AttrTag.ATT_Signature.printval(), attribute_length));
}
signature_index = in.readUnsignedShort();
return this;
}
public void print(String initialTab) {
public void print(String bodyPrefix, String commentPrefix) {
boolean pr_cpx = options.contains(Options.PR.CPX);
if (pr_cpx) {
cls.out.print(initialTab + "#" + signature_index + "\t\t // Signature: " + cls.pool.StringValue(signature_index));
cls.out.print(format("%s#%d%s%s", bodyPrefix, signature_index, commentPrefix, cls.pool.StringValue(signature_index)));
} else {
cls.out.print(initialTab + cls.pool.StringValue(signature_index));
cls.out.print(format("%s%s%s", bodyPrefix, cls.pool.getName(signature_index), commentPrefix));
}
}
@Override
public String toString() {
return format("signature[%d]=%s", signature_index, cls.pool.StringValue(signature_index));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,8 +22,11 @@
*/
package org.openjdk.asmtools.jdis;
import org.openjdk.asmtools.asmutils.HexUtils;
import static java.lang.String.format;
import static org.openjdk.asmtools.jasm.Tables.*;
import static org.openjdk.asmtools.jdis.TraceUtils.mapToHexString;
import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
@ -32,28 +35,19 @@ import java.io.IOException;
* represents one entry of StackMap attribute
*/
class StackMapData {
/*-------------------------------------------------------- */
/* StackMapData Fields */
static int prevFramePC = 0;
boolean isStackMapTable = false;
StackMapFrameType stackFrameType = null;
int start_pc;
int[] lockMap;
int[] stackMap;
/*-------------------------------------------------------- */
public StackMapData() {
}
public StackMapData(CodeData code, DataInputStream in) throws IOException {
start_pc = in.readUnsignedShort();
TraceUtils.trace(" stack_map_entry:pc=" + start_pc);
TraceUtils.trace(" numloc=");
lockMap = readMap(code, in);
TraceUtils.trace(" numstack=");
stackMap = readMap(code, in);
TraceUtils.traceln("");
traceln(2, format("stack_map_entry:pc=%d numloc=%s numstack=%s",
start_pc, mapToHexString(lockMap), mapToHexString(stackMap)));
}
public StackMapData(CodeData code, DataInputStream in,
@ -65,69 +59,52 @@ class StackMapData {
switch (frame_type) {
case SAME_FRAME:
// type is same_frame;
TraceUtils.trace(" same_frame=" + ft_val);
TraceUtils.traceln("");
offset = ft_val;
traceln(2, format("same_frame=%d", ft_val));
break;
case SAME_FRAME_EX:
// type is same_frame_extended;
TraceUtils.trace(" same_frame_extended=" + ft_val);
TraceUtils.traceln("");
offset = in.readUnsignedShort();
TraceUtils.trace(" offset=" + offset);
traceln(2, format("same_frame_extended=%d, offset=%d", ft_val, offset));
break;
case SAME_LOCALS_1_STACK_ITEM_FRAME:
// type is same_locals_1_stack_item_frame
TraceUtils.trace(" same_locals_1_stack_item_frame=" + ft_val);
offset = ft_val - 64;
TraceUtils.trace(" offset=" + offset);
// read additional single stack element
TraceUtils.trace(" numstack=");
stackMap = readMapElements(code, in, 1);
TraceUtils.traceln("");
traceln(2, format("same_locals_1_stack_item_frame=%d, offset=%d, numstack=%s",
ft_val, offset, mapToHexString(stackMap)));
break;
case SAME_LOCALS_1_STACK_ITEM_EXTENDED_FRAME:
// type is same_locals_1_stack_item_frame_extended
TraceUtils.trace(" same_locals_1_stack_item_frame_extended=" + ft_val);
offset = in.readUnsignedShort();
TraceUtils.trace(" offset=" + offset);
// read additional single stack element
TraceUtils.trace(" numstack=");
stackMap = readMapElements(code, in, 1);
TraceUtils.traceln("");
traceln(2, format("same_locals_1_stack_item_frame_extended=%d, offset=%d, numstack=%s",
ft_val, offset, mapToHexString(stackMap)));
break;
case CHOP_1_FRAME:
case CHOP_2_FRAME:
case CHOP_3_FRAME:
// type is chop_frame
TraceUtils.trace(" chop_frame=" + ft_val);
TraceUtils.traceln("");
offset = in.readUnsignedShort();
TraceUtils.trace(" offset=" + offset);
traceln(2, format("chop_frame=%d offset=%d", ft_val, offset));
break;
case APPEND_FRAME:
// type is append_frame
TraceUtils.trace(" append_frame=" + ft_val);
offset = in.readUnsignedShort();
TraceUtils.trace(" offset=" + offset);
// read additional locals
TraceUtils.trace(" numloc=");
lockMap = readMapElements(code, in, ft_val - 251);
TraceUtils.traceln("");
traceln(2, format("append_frame=%d offset=%d numlock=%s",
ft_val, offset, mapToHexString(lockMap)));
break;
case FULL_FRAME:
// type is full_frame
TraceUtils.trace(" full_frame=" + ft_val);
offset = in.readUnsignedShort();
TraceUtils.trace(" offset=" + offset);
TraceUtils.trace(" numloc=");
lockMap = readMap(code, in);
TraceUtils.trace(" numstack=");
stackMap = readMap(code, in);
TraceUtils.traceln("");
traceln(2, format("full_frame=%d offset=%d numloc=%s numstack=%s",
ft_val, offset, mapToHexString(lockMap), mapToHexString(stackMap)));
break;
default:
TraceUtils.trace("incorrect frame_type argument");
TraceUtils.traceln("incorrect frame_type argument");
}
stackFrameType = frame_type;
@ -137,7 +114,6 @@ class StackMapData {
private int[] readMap(CodeData code, DataInputStream in) throws IOException {
int num = in.readUnsignedShort();
TraceUtils.trace("" + num);
return readMapElements(code, in, num);
}
@ -148,7 +124,6 @@ class StackMapData {
try {
mt_val = in.readUnsignedByte();
} catch (EOFException eofe) {
TraceUtils.traceln("");
throw eofe;
}
StackMapType maptype = stackMapType(mt_val, null);
@ -164,7 +139,6 @@ class StackMapData {
}
}
map[k] = mt_val;
TraceUtils.trace(" " + HexUtils.toHex(mt_val));
}
return map;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,59 +22,35 @@
*/
package org.openjdk.asmtools.jdis;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
/**
*
* A container for the java sources tied to an jasm output when -sl in on
*/
public class TextLines {
/*-------------------------------------------------------- */
/* TextLines Fields */
byte data[];
// ends[k] points to the end of k-th line
ArrayList<Integer> ends = new ArrayList<>(60);
public int length;
/*-------------------------------------------------------- */
final Path file;
List<String> lines;
public TextLines() {
public TextLines(Path directory, String sourceFileName) {
file = directory == null ? Paths.get(sourceFileName) : directory.resolve(sourceFileName);
try {
lines = Files.readAllLines(file, StandardCharsets.UTF_8);
} catch (IOException ignore) {}
}
public TextLines(String textfilename) throws IOException {
read(textfilename);
}
private void read(String textfilename) throws IOException {
FileInputStream in = new FileInputStream(textfilename);
data = new byte[in.available()];
in.read(data);
in.close();
ends.add(-1);
for (int k = 0; k < data.length; k++) {
if (data[k] == '\n') {
ends.add(k);
public String getLine(int index) {
if( lines != null ) {
if (index < 1 || index >= lines.size()) {
return String.format("Line number %d is out of range in \"%s\"", index, file);
}
return lines.get(index - 1);
}
length = ends.size(); // but if text is empty??
}
public String getLine(int linenumber) {
int entry = linenumber - 1;
int start;
int end;
ends.add(entry);
start = ends.size() + 1;
searchEnd:
for (end = start; end < data.length; end++) {
switch (data[end]) {
case '\n':
case '\r':
break searchEnd;
}
}
//System.out.println("start="+start+" end="+end);
return new String(data, start, end - start);
return String.format("\"%s\" not found", file);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,8 +22,17 @@
*/
package org.openjdk.asmtools.jdis;
import org.openjdk.asmtools.asmutils.HexUtils;
import java.util.Arrays;
import java.util.stream.Collectors;
import static java.lang.String.format;
public class TraceUtils {
/* ====================================================== */
public static String prefixString = "\t";
public static void trace(String s) {
if (!(Options.OptionObject()).debug()) {
return;
@ -31,10 +40,60 @@ public class TraceUtils {
System.out.print(s);
}
public static void trace(int prefixLength, String s) {
if (!(Options.OptionObject()).debug()) {
return;
}
System.out.print((prefixLength > 0) ? new String(new char[prefixLength]).replace("\0", prefixString) + s : s);
}
public static void traceln(String s) {
if (!(Options.OptionObject()).debug()) {
return;
}
System.out.println(s);
}
public static void traceln(String... lines) {
if (!(Options.OptionObject()).debug()) {
return;
}
if (lines.length == 0) {
System.out.println();
} else {
for (String s : lines) {
System.out.println(s);
}
}
}
public static void traceln(int prefixLength, String s) {
if (!(Options.OptionObject()).debug()) {
return;
}
System.out.println((prefixLength > 0) ? new String(new char[prefixLength]).replace("\0", prefixString) + s : s);
}
public static void traceln(int prefixLength, String... lines) {
if (!(Options.OptionObject()).debug()) {
return;
}
if (lines.length == 0) {
System.out.println();
} else {
String prefix = (prefixLength > 0) ? new String(new char[prefixLength]).replace("\0", prefixString) : "";
for (String s : lines) {
System.out.println(prefix + s);
}
}
}
public static String mapToHexString(int[] array) {
return format("%d %s",
array.length,
Arrays.stream(array).
mapToObj(val -> HexUtils.toHex(val)).
collect(Collectors.joining(" ")));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -22,30 +22,35 @@
*/
package org.openjdk.asmtools.jdis;
import static org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
import org.openjdk.asmtools.jasm.TypeAnnotationTargetInfoData;
import org.openjdk.asmtools.jasm.TypeAnnotationTypePathData;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import static org.openjdk.asmtools.jasm.TypeAnnotationTargetInfoData.*;
import static org.openjdk.asmtools.jasm.TypeAnnotationTypes.*;
/**
* Type Annotation data is a specific kind of AnnotationData. As well as the normal data
* items needed to present an annotation, Type annotations require a TargetInfo
* descriptor. This descriptor is based on a TargetType, and it optionally may contain a
* location descriptor (when the Type is embedded in a collection).
*
* <p>
* The TypeAnnotationData class is based on JDis's AnnotationData class, and contains the
* (jasm) class for representing TargetInfo.
*/
public class TypeAnnotationData extends AnnotationData {
private TargetInfo target_info;
private ArrayList<TypePathEntry> target_path;
private static TTVis TT_Visitor = new TTVis();
private TypeAnnotationTargetInfoData targetInfo;
private TypeAnnotationTypePathData typePath;
public TypeAnnotationData(boolean invisible, ClassData cls) {
super(invisible, cls);
target_info = null;
targetInfo = null;
typePath = new TypeAnnotationTypePathData();
visAnnotToken = "@T+";
invAnnotToken = "@T-";
dataName = "TypeAnnotationData";
@ -53,42 +58,33 @@ public class TypeAnnotationData extends AnnotationData {
@Override
public void read(DataInputStream in) throws IOException {
super.read(in);
// read everything related to the Type Annotation
// target type tag
// KTL 1/10/13 (changed short-> byte for latest spec rev)
// int tt = (char) in.readUnsignedShort(); // cast to introduce signedness
int tt = (byte) in.readUnsignedByte(); // cast to introduce signedness
Integer ttInt = tt;
TargetType ttype;
ttype = targetTypeEnum(ttInt);
int ttype = in.readUnsignedByte();
ETargetType targetType = ETargetType.getTargetType(ttype);
if (ttype == null) {
if (targetType == null) {
// Throw some kind of error for bad target type index
throw new IOException("Bad target type: " + tt + " in TypeAnnotationData");
throw new IOException("Bad target type: " + ttype + " in TypeAnnotationData");
}
// read the target info
TT_Visitor.init(in);
TT_Visitor.visitExcept(ttype);
target_info = TT_Visitor.getTargetInfo();
TT_Visitor.visitExcept(targetType);
targetInfo = TT_Visitor.getTargetInfo();
// read the target path info
int len = in.readUnsignedShort();
target_path = new ArrayList<>(len);
TraceUtils.traceln(" --------- [TypeAnnotationData.read]: Reading Location (length = " + len + ").");
TraceUtils.trace(" --------- [TypeAnnotationData.read]: [ ");
int len = in.readUnsignedByte();
TraceUtils.traceln(4,"[TypeAnnotationData.read]: Reading Location (length = " + len + ").");
TraceUtils.trace(4,"[TypeAnnotationData.read]: [ ");
for (int i = 0; i < len; i++) {
int pathType = in.readUnsignedByte();
String pk = (getPathKind(pathType)).parsekey();
String pk = (getPathKind(pathType)).parseKey();
char pathArgIndex = (char) in.readUnsignedByte();
target_path.add(new TypePathEntry(pathType, pathArgIndex));
typePath.addTypePathEntry(new TypePathEntry(pathType, pathArgIndex));
TraceUtils.trace(" " + pk + "(" + pathType + "," + pathArgIndex + "), ");
}
TraceUtils.traceln("] ");
// target_info.setLocation(location);
super.read(in);
}
@Override
@ -97,51 +93,24 @@ public class TypeAnnotationData extends AnnotationData {
// print out the (regular) annotation name/value pairs,
// then print out the target types.
out.print(" {");
super.printBody(out, tab);
target_info.print(out, tab);
printPath(out, tab);
out.print("}");
}
protected void printPath(PrintWriter out, String tab) {
// For a type annotation, print out brackets,
// print out the (regular) annotation name/value pairs,
// then print out the target types.
out.print(" {");
boolean first = true;
for (TypePathEntry tpe : target_path) {
if (!first) {
out.print(", ");
}
first = false;
out.print(tpe.toString());
}
target_info.print(out, tab);
printPath(out, tab);
out.print("}");
}
@Override
protected void _toString(StringBuilder sb) {
// sub-classes override this
sb.append(target_info.toString());
super.printBody(out, "");
targetInfo.print(out, tab);
typePath.print(out, tab);
out.print(tab + "}");
}
/**
* TTVis
*
* <p>
* Target Type visitor, used for constructing the target-info within a type
* annotation. visitExcept() is the entry point. ti is the constructed target info.
*/
private static class TTVis extends TypeAnnotationTargetVisitor {
private TargetInfo ti = null;
private TypeAnnotationTargetInfoData targetInfo = null;
private IOException IOProb = null;
private DataInputStream in;
public TTVis() {
}
public void init(DataInputStream in) {
this.in = in;
}
@ -166,22 +135,12 @@ public class TypeAnnotationData extends AnnotationData {
return val;
}
public int scanIntVal() {
int val = 0;
try {
val = in.readInt();
} catch (IOException e) {
IOProb = e;
}
return val;
}
//This is the entry point for a visitor that tunnels exceptions
public void visitExcept(TargetType tt) throws IOException {
public void visitExcept(ETargetType tt) throws IOException {
IOProb = null;
ti = null;
targetInfo = null;
TraceUtils.traceln(" Target Type: " + tt.parseKey());
TraceUtils.traceln(4,"Target Type: " + tt.parseKey());
visit(tt);
if (IOProb != null) {
@ -189,8 +148,8 @@ public class TypeAnnotationData extends AnnotationData {
}
}
public TargetInfo getTargetInfo() {
return ti;
public TypeAnnotationTargetInfoData getTargetInfo() {
return targetInfo;
}
private boolean error() {
@ -198,28 +157,28 @@ public class TypeAnnotationData extends AnnotationData {
}
@Override
public void visit_type_param_target(TargetType tt) {
TraceUtils.trace(" Type Param Target: ");
public void visit_type_param_target(ETargetType tt) {
TraceUtils.trace(4,"Type Param Target: ");
int byteval = scanByteVal(); // param index
TraceUtils.traceln("{ param_index: " + byteval + "}");
if (!error()) {
ti = new typeparam_target(tt, byteval);
targetInfo = new type_parameter_target(tt, byteval);
}
}
@Override
public void visit_supertype_target(TargetType tt) {
TraceUtils.trace(" SuperType Target: ");
public void visit_supertype_target(ETargetType tt) {
TraceUtils.trace(4,"SuperType Target: ");
int shortval = scanShortVal(); // type index
TraceUtils.traceln("{ type_index: " + shortval + "}");
if (!error()) {
ti = new supertype_target(tt, shortval);
targetInfo = new supertype_target(tt, shortval);
}
}
@Override
public void visit_typeparam_bound_target(TargetType tt) {
TraceUtils.trace(" TypeParam Bound Target: ");
public void visit_typeparam_bound_target(ETargetType tt) {
TraceUtils.trace(4,"TypeParam Bound Target: ");
int byteval1 = scanByteVal(); // param index
if (error()) {
return;
@ -229,46 +188,46 @@ public class TypeAnnotationData extends AnnotationData {
return;
}
TraceUtils.traceln("{ param_index: " + byteval1 + " bound_index: " + byteval2 + "}");
ti = new typeparam_bound_target(tt, byteval1, byteval2);
targetInfo = new type_parameter_bound_target(tt, byteval1, byteval2);
}
@Override
public void visit_empty_target(TargetType tt) {
TraceUtils.traceln(" Empty Target: ");
public void visit_empty_target(ETargetType tt) {
TraceUtils.traceln(4,"Empty Target: ");
if (!error()) {
ti = new empty_target(tt);
targetInfo = new empty_target(tt);
}
}
@Override
public void visit_methodformalparam_target(TargetType tt) {
TraceUtils.trace(" MethodFormalParam Target: ");
public void visit_methodformalparam_target(ETargetType tt) {
TraceUtils.trace(4,"MethodFormalParam Target: ");
int byteval = scanByteVal(); // param index
TraceUtils.traceln("{ param_index: " + byteval + "}");
if (!error()) {
ti = new methodformalparam_target(tt, byteval);
targetInfo = new formal_parameter_target(tt, byteval);
}
}
@Override
public void visit_throws_target(TargetType tt) {
TraceUtils.trace(" Throws Target: ");
public void visit_throws_target(ETargetType tt) {
TraceUtils.trace(4,"Throws Target: ");
int shortval = scanShortVal(); // exception index
TraceUtils.traceln("{ exception_index: " + shortval + "}");
if (!error()) {
ti = new throws_target(tt, shortval);
targetInfo = new throws_target(tt, shortval);
}
}
@Override
public void visit_localvar_target(TargetType tt) {
TraceUtils.traceln(" LocalVar Target: ");
public void visit_localvar_target(ETargetType tt) {
TraceUtils.traceln(4,"LocalVar Target: ");
int tblsize = scanShortVal(); // table length (short)
if (error()) {
return;
}
localvar_target locvartab = new localvar_target(tt, tblsize);
ti = locvartab;
targetInfo = locvartab;
for (int i = 0; i < tblsize; i++) {
int shortval1 = scanShortVal(); // startPC
@ -280,35 +239,35 @@ public class TypeAnnotationData extends AnnotationData {
return;
}
int shortval3 = scanShortVal(); // CPX
TraceUtils.trace(" LocalVar[" + i + "]: ");
TraceUtils.trace(4,"LocalVar[" + i + "]: ");
TraceUtils.traceln("{ startPC: " + shortval1 + ", length: " + shortval2 + ", CPX: " + shortval3 + "}");
locvartab.addEntry(shortval1, shortval2, shortval3);
}
}
@Override
public void visit_catch_target(TargetType tt) {
TraceUtils.trace(" Catch Target: ");
public void visit_catch_target(ETargetType tt) {
TraceUtils.trace(4,"Catch Target: ");
int shortval = scanShortVal(); // catch index
TraceUtils.traceln("{ catch_index: " + shortval + "}");
if (!error()) {
ti = new catch_target(tt, shortval);
targetInfo = new catch_target(tt, shortval);
}
}
@Override
public void visit_offset_target(TargetType tt) {
TraceUtils.trace(" Offset Target: ");
public void visit_offset_target(ETargetType tt) {
TraceUtils.trace(4,"Offset Target: ");
int shortval = scanShortVal(); // offset index
TraceUtils.traceln("{ offset_index: " + shortval + "}");
if (!error()) {
ti = new offset_target(tt, shortval);
targetInfo = new offset_target(tt, shortval);
}
}
@Override
public void visit_typearg_target(TargetType tt) {
TraceUtils.trace(" TypeArg Target: ");
public void visit_typearg_target(ETargetType tt) {
TraceUtils.trace(4,"TypeArg Target: ");
int shortval = scanShortVal(); // offset
if (error()) {
return;
@ -318,9 +277,7 @@ public class TypeAnnotationData extends AnnotationData {
return;
}
TraceUtils.traceln("{ offset: " + shortval + " type_index: " + byteval + "}");
ti = new typearg_target(tt, shortval, byteval);
targetInfo = new type_argument_target(tt, shortval, byteval);
}
}
}

View File

@ -122,7 +122,7 @@ public class I18NResourceBundle extends ResourceBundle {
* A required internal method for ResourceBundle. Load the actual resource bundle, if
* it has not yet been loaded, then hand the request off to that bundle. If the
* resource cannot be found, a message is printed to the console and the result will
* be the original key.
* be the original tag.
*/
protected Object handleGetObject(String key) throws MissingResourceException {
try {