From f09c156565b61129bedc501b2eb43db17a4273bb Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 27 Jul 2017 18:04:46 +0000 Subject: [PATCH 01/42] Added tag jdk-9+180 for changeset cf6820c6f184 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 7de83411416..07b5d344916 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -422,3 +422,4 @@ b25838a28195f4b6dab34668411eedd2d366a16c jdk-9+169 a4371edb589c60db01142e45c317adb9ccbcb083 jdk-9+177 ec4159ebe7050fcc5dcee8a2d150cf948ecc97db jdk-9+178 252475ccfd84cc249f8d6faf4b7806b5e2c384ce jdk-9+179 +d2982a786f53814367698e63efe6349c9128e1db jdk-9+180 From 0c004999da04d1d9a17fbf712dbd179a4d4d9a37 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 27 Jul 2017 18:04:47 +0000 Subject: [PATCH 02/42] Added tag jdk-9+180 for changeset 52aba14d5a8e --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 3afcce0f7c6..3e06b395fe6 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -582,3 +582,4 @@ e64b1cb48d6e7703928a9d1da106fc27f8cb65fd jdk-9+173 1ca8f038fceb88c640badf9bd18905205bc63b43 jdk-9+177 9d032191f82fca5ba0aac98682f69c4ff0f1283d jdk-9+178 d2661aa42bff322badbe6c1337fc638d2e0f5730 jdk-9+179 +d7baadc223e790c08bc69bf7e553bce65b4e7e40 jdk-9+180 From c95f91e83bd856ca039969a829fa3069e7d0be74 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 27 Jul 2017 18:04:47 +0000 Subject: [PATCH 03/42] Added tag jdk-9+180 for changeset 03207b7f16e6 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index c70104da520..688de6cbf1b 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -422,3 +422,4 @@ dc78a3dd6b3a4f11cdae8a3e3d160e6a78bc7838 jdk-9+175 c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177 9c1e9712648921ae389d623042d22561fad82d75 jdk-9+178 24390da83c5ee9e23ceafbcaff4460a01e37bb3a jdk-9+179 +6ce6cb8ff41c71c49f23b15e0f0468aca5d52b17 jdk-9+180 From 9b84cfb7f6f599a39da22268c1ba0cd3ee4a90e0 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 27 Jul 2017 18:04:48 +0000 Subject: [PATCH 04/42] Added tag jdk-9+180 for changeset c3e45a079573 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 9126335d0c5..df28072c0e4 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -422,3 +422,4 @@ e6c4f6ef717d104dba880e2dae538690c993b46f jdk-9+175 80acf577b7d0b886fb555c9916552844f6cc72af jdk-9+177 443025bee731eb2225371b92c1c74b519b7baf33 jdk-9+178 06df1ce4b9b887d05ce6a13f4def3547e434dd1a jdk-9+179 +4feab1acec6a9c3620a19ff379a65ab8618d0e2a jdk-9+180 From 82eda52b5b60f96b5775a49038010208a1ccacfd Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 27 Jul 2017 18:04:48 +0000 Subject: [PATCH 05/42] Added tag jdk-9+180 for changeset 0e3c57d1a59c --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index a15959a57fb..3258a82cbab 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -422,3 +422,4 @@ b9c0b105002272d7414c8b34af9aded151f9cad6 jdk-9+174 332ad9f92632f56f337b8c40edef9a95a42b26bc jdk-9+177 0983b2dbe17ba4fed3af34e0512ca77a9845fe8a jdk-9+178 87243a3131f79e8b3903eaca6b629abc48f08ace jdk-9+179 +9934a03646f91ce55f61f53d8448c629828f8088 jdk-9+180 From 0fe7fc20ab7ee89c99fb6a51aa96424c04c6440b Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 27 Jul 2017 18:04:50 +0000 Subject: [PATCH 06/42] Added tag jdk-9+180 for changeset bea4f059dce4 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 1d349ed7276..e890681b0bc 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -413,3 +413,4 @@ fa8e4de50e821eed876388c84f7129a6739268be jdk-9+173 aa7404e062b95f679018f25eaaf933dcf0cf3f2b jdk-9+177 7497ad85759ff010f44344b553223d1647fb6eba jdk-9+178 3adfb547e3e49e304ffc82d8c6489cb830b74d62 jdk-9+179 +bece58f762168a6615bd036626a572a647f6b507 jdk-9+180 From c27877713e1cb15212caff7a2cf2655331877088 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Thu, 3 Aug 2017 18:56:59 +0000 Subject: [PATCH 07/42] Added tag jdk-9+181 for changeset 35dc62e43188 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index df28072c0e4..eca17387148 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -423,3 +423,4 @@ e6c4f6ef717d104dba880e2dae538690c993b46f jdk-9+175 443025bee731eb2225371b92c1c74b519b7baf33 jdk-9+178 06df1ce4b9b887d05ce6a13f4def3547e434dd1a jdk-9+179 4feab1acec6a9c3620a19ff379a65ab8618d0e2a jdk-9+180 +bd66ea2fdde3d60a73b5272263a7b8b0ca926a33 jdk-9+181 From 36378834a9ffa98066a4d7b6097e7adcdb8fc6b7 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Tue, 8 Aug 2017 12:32:41 +0100 Subject: [PATCH 08/42] 8185852: HttpConnection should resolve addresses before SocketChannel.connect() is called HttpConnection checks whether the proxy address is resolved and if not attempts to resolve it before creating the underlying connection that connects to the proxy. Reviewed-by: chegar --- .../jdk/incubator/http/HttpConnection.java | 6 + jdk/test/java/net/httpclient/ProxyTest.java | 346 ++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 jdk/test/java/net/httpclient/ProxyTest.java diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java index 96bd67f969e..a520390ba2d 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java @@ -154,6 +154,12 @@ abstract class HttpConnection implements Closeable { { HttpConnection c = null; InetSocketAddress proxy = request.proxy(client); + if (proxy != null && proxy.isUnresolved()) { + // The default proxy selector may select a proxy whose + // address is unresolved. We must resolve the address + // before using it to connect. + proxy = new InetSocketAddress(proxy.getHostString(), proxy.getPort()); + } boolean secure = request.secure(); ConnectionPool pool = client.connectionPool(); String[] alpn = null; diff --git a/jdk/test/java/net/httpclient/ProxyTest.java b/jdk/test/java/net/httpclient/ProxyTest.java new file mode 100644 index 00000000000..8dc90dfb1a1 --- /dev/null +++ b/jdk/test/java/net/httpclient/ProxyTest.java @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; +import com.sun.net.httpserver.HttpsServer; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Writer; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import jdk.incubator.http.HttpClient; +import jdk.incubator.http.HttpRequest; +import jdk.incubator.http.HttpResponse; +import jdk.testlibrary.SimpleSSLContext; + +/** + * @test + * @bug 8185852 + * @summary verifies that passing a proxy with an unresolved address does + * not cause java.nio.channels.UnresolvedAddressException + * @modules jdk.incubator.httpclient + * @library /lib/testlibrary/ + * @build jdk.testlibrary.SimpleSSLContext ProxyTest + * @run main/othervm ProxyTest + * @author danielfuchs + */ +public class ProxyTest { + + static { + try { + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + SSLContext.setDefault(new SimpleSSLContext().get()); + } catch (IOException ex) { + throw new ExceptionInInitializerError(ex); + } + } + + static final String RESPONSE = "

Hello World!"; + static final String PATH = "/foo/"; + + static HttpServer createHttpsServer() throws IOException, NoSuchAlgorithmException { + HttpsServer server = com.sun.net.httpserver.HttpsServer.create(); + HttpContext context = server.createContext(PATH); + context.setHandler(new HttpHandler() { + @Override + public void handle(HttpExchange he) throws IOException { + he.getResponseHeaders().add("encoding", "UTF-8"); + he.sendResponseHeaders(200, RESPONSE.length()); + he.getResponseBody().write(RESPONSE.getBytes(StandardCharsets.UTF_8)); + he.close(); + } + }); + + server.setHttpsConfigurator(new Configurator(SSLContext.getDefault())); + server.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0); + return server; + } + + public static void main(String[] args) + throws IOException, + URISyntaxException, + NoSuchAlgorithmException, + InterruptedException + { + HttpServer server = createHttpsServer(); + server.start(); + try { + test(server, HttpClient.Version.HTTP_1_1); + // test(server, HttpClient.Version.HTTP_2); + } finally { + server.stop(0); + System.out.println("Server stopped"); + } + } + + public static void test(HttpServer server, HttpClient.Version version) + throws IOException, + URISyntaxException, + NoSuchAlgorithmException, + InterruptedException + { + System.out.println("Server is: " + server.getAddress().toString()); + System.out.println("Verifying communication with server"); + URI uri = new URI("https:/" + server.getAddress().toString() + PATH + "x"); + try (InputStream is = uri.toURL().openConnection().getInputStream()) { + String resp = new String(is.readAllBytes(), StandardCharsets.UTF_8); + System.out.println(resp); + if (!RESPONSE.equals(resp)) { + throw new AssertionError("Unexpected response from server"); + } + } + System.out.println("Communication with server OK"); + + TunnelingProxy proxy = new TunnelingProxy(server); + proxy.start(); + try { + System.out.println("Proxy started"); + Proxy p = new Proxy(Proxy.Type.HTTP, + InetSocketAddress.createUnresolved("localhost", proxy.getAddress().getPort())); + System.out.println("Verifying communication with proxy"); + HttpURLConnection conn = (HttpURLConnection)uri.toURL().openConnection(p); + try (InputStream is = conn.getInputStream()) { + String resp = new String(is.readAllBytes(), StandardCharsets.UTF_8); + System.out.println(resp); + if (!RESPONSE.equals(resp)) { + throw new AssertionError("Unexpected response from proxy"); + } + } + System.out.println("Communication with proxy OK"); + System.out.println("\nReal test begins here."); + System.out.println("Setting up request with HttpClient for version: " + + version.name()); + ProxySelector ps = ProxySelector.of( + InetSocketAddress.createUnresolved("localhost", proxy.getAddress().getPort())); + HttpClient client = HttpClient.newBuilder() + .version(version) + .proxy(ps) + .build(); + HttpRequest request = HttpRequest.newBuilder() + .uri(uri) + .GET() + .build(); + + System.out.println("Sending request with HttpClient"); + HttpResponse response + = client.send(request, HttpResponse.BodyHandler.asString()); + System.out.println("Got response"); + String resp = response.body(); + System.out.println("Received: " + resp); + if (!RESPONSE.equals(resp)) { + throw new AssertionError("Unexpected response"); + } + } finally { + System.out.println("Stopping proxy"); + proxy.stop(); + System.out.println("Proxy stopped"); + } + } + + static class TunnelingProxy { + final Thread accept; + final ServerSocket ss; + final boolean DEBUG = false; + final HttpServer serverImpl; + TunnelingProxy(HttpServer serverImpl) throws IOException { + this.serverImpl = serverImpl; + ss = new ServerSocket(); + accept = new Thread(this::accept); + } + + void start() throws IOException { + ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + accept.start(); + } + + // Pipe the input stream to the output stream. + private synchronized Thread pipe(InputStream is, OutputStream os, char tag) { + return new Thread("TunnelPipe("+tag+")") { + @Override + public void run() { + try { + try { + int c; + while ((c = is.read()) != -1) { + os.write(c); + os.flush(); + // if DEBUG prints a + or a - for each transferred + // character. + if (DEBUG) System.out.print(tag); + } + is.close(); + } finally { + os.close(); + } + } catch (IOException ex) { + if (DEBUG) ex.printStackTrace(System.out); + } + } + }; + } + + public InetSocketAddress getAddress() { + return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort()); + } + + // This is a bit shaky. It doesn't handle continuation + // lines, but our client shouldn't send any. + // Read a line from the input stream, swallowing the final + // \r\n sequence. Stops at the first \n, doesn't complain + // if it wasn't preceded by '\r'. + // + String readLine(InputStream r) throws IOException { + StringBuilder b = new StringBuilder(); + int c; + while ((c = r.read()) != -1) { + if (c == '\n') break; + b.appendCodePoint(c); + } + if (b.codePointAt(b.length() -1) == '\r') { + b.delete(b.length() -1, b.length()); + } + return b.toString(); + } + + public void accept() { + Socket clientConnection = null; + try { + while (true) { + System.out.println("Tunnel: Waiting for client"); + Socket previous = clientConnection; + try { + clientConnection = ss.accept(); + } catch (IOException io) { + if (DEBUG) io.printStackTrace(System.out); + break; + } finally { + // we have only 1 client at a time, so it is safe + // to close the previous connection here + if (previous != null) previous.close(); + } + System.out.println("Tunnel: Client accepted"); + Socket targetConnection = null; + InputStream ccis = clientConnection.getInputStream(); + OutputStream ccos = clientConnection.getOutputStream(); + Writer w = new OutputStreamWriter(ccos, "UTF-8"); + PrintWriter pw = new PrintWriter(w); + System.out.println("Tunnel: Reading request line"); + String requestLine = readLine(ccis); + System.out.println("Tunnel: Request status line: " + requestLine); + if (requestLine.startsWith("CONNECT ")) { + // We should probably check that the next word following + // CONNECT is the host:port of our HTTPS serverImpl. + // Some improvement for a followup! + + // Read all headers until we find the empty line that + // signals the end of all headers. + while(!requestLine.equals("")) { + System.out.println("Tunnel: Reading header: " + + (requestLine = readLine(ccis))); + } + + // Open target connection + targetConnection = new Socket( + serverImpl.getAddress().getAddress(), + serverImpl.getAddress().getPort()); + + // Then send the 200 OK response to the client + System.out.println("Tunnel: Sending " + + "HTTP/1.1 200 OK\r\n\r\n"); + pw.print("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); + pw.flush(); + } else { + // This should not happen. + throw new IOException("Tunnel: Unexpected status line: " + + requestLine); + } + + // Pipe the input stream of the client connection to the + // output stream of the target connection and conversely. + // Now the client and target will just talk to each other. + System.out.println("Tunnel: Starting tunnel pipes"); + Thread t1 = pipe(ccis, targetConnection.getOutputStream(), '+'); + Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-'); + t1.start(); + t2.start(); + + // We have only 1 client... wait until it has finished before + // accepting a new connection request. + // System.out.println("Tunnel: Waiting for pipes to close"); + // t1.join(); + // t2.join(); + System.out.println("Tunnel: Done - waiting for next client"); + } + } catch (Throwable ex) { + try { + ss.close(); + } catch (IOException ex1) { + ex.addSuppressed(ex1); + } + ex.printStackTrace(System.err); + } + } + + void stop() throws IOException { + ss.close(); + } + + } + + static class Configurator extends HttpsConfigurator { + public Configurator(SSLContext ctx) { + super(ctx); + } + + @Override + public void configure (HttpsParameters params) { + params.setSSLParameters (getSSLContext().getSupportedSSLParameters()); + } + } + +} From 43ead07d44b05a199ed455cc83a36a8b1f33af27 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 8 Aug 2017 21:37:38 +0800 Subject: [PATCH 09/42] 8185934: keytool shows "Signature algorithm: SHA1withECDSA, -1-bit key" Reviewed-by: mullan --- .../share/classes/sun/security/tools/keytool/Main.java | 10 ++++++++-- .../classes/sun/security/tools/keytool/Resources.java | 1 + .../classes/sun/security/tools/jarsigner/Main.java | 8 ++++++-- .../sun/security/tools/jarsigner/Resources.java | 1 + 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java index ec5e59c07fc..dac650b1451 100644 --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -3071,8 +3071,14 @@ public final class Main { private String withWeak(PublicKey key) { if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - return String.format(rb.getString("key.bit"), - KeyUtil.getKeySize(key), key.getAlgorithm()); + int kLen = KeyUtil.getKeySize(key); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), + kLen, key.getAlgorithm()); + } else { + return String.format( + rb.getString("unknown.size.1"), key.getAlgorithm()); + } } else { return String.format(rb.getString("key.bit.weak"), KeyUtil.getKeySize(key), key.getAlgorithm()); diff --git a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java index a78eb6bc3e6..9bdd95cbda0 100644 --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java @@ -462,6 +462,7 @@ public class Resources extends java.util.ListResourceBundle { {"with.weak", "%s (weak)"}, {"key.bit", "%d-bit %s key"}, {"key.bit.weak", "%d-bit %s key (weak)"}, + {"unknown.size.1", "unknown size %s key"}, {".PATTERN.printX509Cert.with.weak", "Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignature algorithm name: {7}\nSubject Public Key Algorithm: {8}\nVersion: {9}"}, {"PKCS.10.with.weak", diff --git a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index cb86682f7da..12d4e1ba380 100644 --- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -1088,8 +1088,12 @@ public class Main { private String withWeak(PublicKey key) { if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - return String.format( - rb.getString("key.bit"), KeyUtil.getKeySize(key)); + int kLen = KeyUtil.getKeySize(key); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), kLen); + } else { + return rb.getString("unknown.size"); + } } else { seeWeak = true; return String.format( diff --git a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java index 26e0553ebb2..ebdd79d792e 100644 --- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java @@ -164,6 +164,7 @@ public class Resources extends java.util.ListResourceBundle { {"with.weak", "%s (weak)"}, {"key.bit", "%d-bit key"}, {"key.bit.weak", "%d-bit key (weak)"}, + {"unknown.size", "unknown size"}, {"jarsigner.", "jarsigner: "}, {"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.", From 74419eb34a83fe6502f0ba360b3d9821bfbe9e8e Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 8 Aug 2017 12:01:02 -0700 Subject: [PATCH 10/42] 8185867: fix a11y and html issues in jdk.jdi docs Reviewed-by: alanb --- .../com/sun/jdi/InvalidModuleException.java | 1 - .../classes/com/sun/jdi/JDIPermission.java | 14 +- .../share/classes/com/sun/jdi/Type.java | 109 +++++----- .../share/classes/com/sun/jdi/Value.java | 201 ++++++++++-------- .../com/sun/jdi/VirtualMachineManager.java | 17 +- .../com/sun/jdi/doc-files/signature.html | 38 ++-- 6 files changed, 207 insertions(+), 173 deletions(-) diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java index 5351594c952..422a7cbfce8 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java @@ -28,7 +28,6 @@ package com.sun.jdi; /** * Thrown to indicate that the requested module is invalid * or became invalid after the module was unloaded. - *

* * @since 9 */ diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/JDIPermission.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/JDIPermission.java index 8f9b4da9980..2c80497d3f1 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/JDIPermission.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/JDIPermission.java @@ -40,17 +40,20 @@ package com.sun.jdi; * permission allows, and discusses the risks of granting code the * permission. * - * + *
* + * * - * - * - * + * + * + * * + * * + * * - * + * * @@ -59,6 +62,7 @@ package com.sun.jdi; * misbehave. * * + * * *
Table shows permission target name, what the * permission allows, and associated risks
Permission Target NameWhat the Permission AllowsRisks of Allowing this PermissionPermission Target NameWhat the Permission AllowsRisks of Allowing this Permission
virtualMachineManagervirtualMachineManagerAbility to inspect and modify the JDI objects in the * {@code VirtualMachineManager} *
* diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Type.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Type.java index 50ad02747e8..0eb7eae3e0e 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Type.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Type.java @@ -43,79 +43,86 @@ package com.sun.jdi; * {@link ArrayType#componentType()} * *

- * The following table illustrates which subinterfaces of Type + * The following tables illustrate which subinterfaces of Type * are used to mirror types in the target VM -- - * - * - * - * - * - * - * + *
Maps each type declared in target to a mirrored - * instance of a subinterface of PrimitiveType or ReferenceType"
Subinterfaces of {@link PrimitiveType}
Type declared in target asIs mirrored as an instance of
+ * + * * - * - * + * + * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * - * - * - * - * - * - * + * + * * - * - * - * + * + * + * + *
Subinterfaces of {@link PrimitiveType}
boolean {@link BooleanType}Type declared in target asIs mirrored as an instance of
byte{@link ByteType}boolean {@link BooleanType}
char{@link CharType}byte{@link ByteType}
double{@link DoubleType}char{@link CharType}
float{@link FloatType}double{@link DoubleType}
int{@link IntegerType}float{@link FloatType}
long{@link LongType}int{@link IntegerType}
short{@link ShortType}long{@link LongType}
void{@link VoidType}
Subinterfaces of {@link ReferenceType}
Type declared in target asFor exampleIs mirrored as an instance ofshort{@link ShortType}
a classDate{@link ClassType}void{@link VoidType}
+ * + * + * + * * - * - * - * + * + * + * + * + * * - * - * - * + * + * + * * - * - * - * + * + * + * + * + * + * + * + * + * + * * - * - * - * + * * - * - * - * + * + * *
Subinterfaces of {@link ReferenceType}
an interfaceRunnable{@link InterfaceType}Type declared in target asFor exampleIs mirrored as an instance of
an array {@link ArrayType}a classDate{@link ClassType}
an arrayint[]{@link ArrayType} whose + * an interfaceRunnable{@link InterfaceType}
an array(any){@link ArrayType}
int[]{@link ArrayType} whose * {@link ArrayType#componentType() componentType()} is * {@link IntegerType}
an arrayDate[]{@link ArrayType} whose + * + * Date[]{@link ArrayType} whose * {@link ArrayType#componentType() componentType()} is * {@link ClassType}
an arrayRunnable[]{@link ArrayType} whose + * + * Runnable[]{@link ArrayType} whose * {@link ArrayType#componentType() componentType()} is * {@link InterfaceType}
* * @see PrimitiveType Subinterface PrimitiveType diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Value.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Value.java index 99568fe60bc..42afbc2bfdf 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Value.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Value.java @@ -33,7 +33,7 @@ import com.sun.jdi.event.ModificationWatchpointEvent; * value hierarchy encompassing primitive values and object values. *

* Some examples of where values may be accessed: - *

+ *
layout
* *
{@link ObjectReference#getValue(Field) * ObjectReference.getValue(Field)} @@ -52,117 +52,130 @@ import com.sun.jdi.event.ModificationWatchpointEvent; * - returned with an event *
*

- * The following table illustrates which subinterfaces of Value + * The following tables illustrate which subinterfaces of Value * are used to mirror values in the target VM -- - * - * - * - * - * - * - * - * - * + *
Maps each kind of value to a mirrored - * instance of a subinterface of Value
Subinterfaces of {@link PrimitiveValue}
Kind of valueFor example -
expression in target
Is mirrored as an
instance of
{@link Type} of value
{@link #type() Value.type()}
+ * + * * - * - * - * - * + * + * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * + * + *
Subinterfaces of {@link PrimitiveValue}
a boolean {@code true} {@link BooleanValue} {@link BooleanType}Kind of valueFor example -
expression in target
Is mirrored as an
instance of
{@link Type} of value
{@link #type() Value.type()}
a byte {@code (byte)4} {@link ByteValue} {@link ByteType}a boolean{@code true}{@link BooleanValue}{@link BooleanType}
a char {@code 'a'} {@link CharValue} {@link CharType}a byte{@code (byte)4}{@link ByteValue}{@link ByteType}
a double {@code 3.1415926} {@link DoubleValue} {@link DoubleType}a char{@code 'a'}{@link CharValue}{@link CharType}
a float {@code 2.5f} {@link FloatValue} {@link FloatType}a double{@code 3.1415926}{@link DoubleValue}{@link DoubleType}
an int {@code 22} {@link IntegerValue} {@link IntegerType}a float{@code 2.5f}{@link FloatValue}{@link FloatType}
a long {@code 1024L} {@link LongValue} {@link LongType}an int{@code 22}{@link IntegerValue}{@link IntegerType}
a short {@code (short)12} {@link ShortValue} {@link ShortType}a long{@code 1024L}{@link LongValue}{@link LongType}
a void {@link VoidValue} {@link VoidType}
Subinterfaces of {@link ObjectReference}
Kind of valueFor example -
expression in target
Is mirrored as an
instance of
{@link Type} of value
{@link #type() Value.type()}
a short{@code (short)12}{@link ShortValue}{@link ShortType}
a class instance {@code this} {@link ObjectReference} {@link ClassType}a void{@link VoidValue}{@link VoidType}
+ * + * + * + * * - * - * - * - * + * + * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + *
Subinterfaces of {@link ObjectReference}
an array {@code new int[5]} {@link ArrayReference} {@link ArrayType}Kind of valueFor example -
expression in target
Is mirrored as an
instance of
{@link Type} of value
{@link #type() Value.type()}
a string {@code "hello"} {@link StringReference} {@link ClassType}a class instance{@code this}{@link ObjectReference}{@link ClassType}
a thread {@code Thread.currentThread()} {@link ThreadReference} {@link ClassType}an array{@code new int[5]}{@link ArrayReference}{@link ArrayType}
a thread group {@code Thread.currentThread()}
  {@code .getThreadGroup()}
{@link ThreadGroupReference} {@link ClassType}a string{@code "hello"}{@link StringReference}{@link ClassType}
a {@code java.lang.Class}
instance
{@code this.getClass()} {@link ClassObjectReference} {@link ClassType}a thread{@code Thread.currentThread()}{@link ThreadReference}{@link ClassType}
a class loader {@code this.getClass()}
  {@code .getClassLoader()}
{@link ClassLoaderReference} {@link ClassType}
Other
Kind of valueFor example -
expression in target
Is mirrored as{@link Type} of valuea thread group{@code Thread.currentThread()}
  {@code .getThreadGroup()}
{@link ThreadGroupReference}{@link ClassType}
null {@code null} {@code null} n/aa {@code java.lang.Class}
instance
{@code this.getClass()}{@link ClassObjectReference}{@link ClassType}
a class loader{@code this.getClass()}
  {@code .getClassLoader()}
{@link ClassLoaderReference}{@link ClassType}
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * *
Other values
Kind of valueFor example -
expression in target
Is mirrored as{@link Type} of value
null{@code null}{@code null}n/a
* * @author Robert Field diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java index ae3c5ffd016..2431f6c02ed 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java @@ -59,13 +59,16 @@ import com.sun.jdi.event.VMStartEvent; * Some {@link Connector} implementations may require slightly * different handling than presented below. * - * + *
* + * * - * - * + * + * + * + * * - * + * * * * * - * + * * * * - * + * * * * - * + * * + *
Four scenarios for connecting a debugger to a virtual machine"
ScenarioDescriptionScenarioDescription
Debugger launches target VM (simplest, most-common scenario)Debugger launches target VM (simplest, most-common scenario)Debugger calls the {@link LaunchingConnector#launch(java.util.Map)} * method of the default connector, obtained with {@link #defaultConnector}. The @@ -86,7 +89,7 @@ import com.sun.jdi.event.VMStartEvent; *
Debugger attaches to previously-running VMDebugger attaches to previously-running VM *
    *
  • @@ -113,7 +116,7 @@ import com.sun.jdi.event.VMStartEvent; *
Target VM attaches to previously-running debuggerTarget VM attaches to previously-running debugger *
    *
  • @@ -146,7 +149,7 @@ import com.sun.jdi.event.VMStartEvent; *
Target VM launches debugger (sometimes called "Just-In-Time" debugging)Target VM launches debugger (sometimes called "Just-In-Time" debugging) *
    *
  • diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html index 75bb46c1c32..8c7d4f95398 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html @@ -1,34 +1,42 @@ - + JDI Type Signatures + +
    - - + + + +
    JDI Type Signatures
    Type Signature -Java Type -
    Zboolean -
    Bbyte -
    Cchar -
    Sshort -
    Iint -
    Jlong -
    Ffloat -
    Ddouble -
    L fully-qualified-class +
    JDI Type Signatures
    Type Signature +Java Type +
    Zboolean +
    Bbyte +
    Cchar +
    Sshort +
    Iint +
    Jlong +
    Ffloat +
    Ddouble +
    L fully-qualified-class ; fully-qualified-class -
    [ type +
    [ type type[] -
    +
    ( arg-types ) ret-type method type (including constructors) +

    For example, the Java method: From 7be03f32008a9fa56fe907c42451e408d9c8dd08 Mon Sep 17 00:00:00 2001 From: Abhijit Saha Date: Tue, 8 Aug 2017 22:11:12 +0000 Subject: [PATCH 11/42] Added tag jdk-10+19 for changeset 22316369c9b0 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 012f8dd2e2a..23d7344f3c1 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -441,3 +441,4 @@ e069834e2c518a7bc2ffadc8c7e3cd7ec69fa8a0 jdk-10+15 06df1ce4b9b887d05ce6a13f4def3547e434dd1a jdk-9+179 d93f2fd542b7d7855c2cd49ae15ebcc3d441a83b jdk-10+17 c4b709bad6c5d29294124de5e74e1e2ac84fcf1f jdk-10+18 +b561eeca30decc6258b4aca8bb23beffbb6e2f7d jdk-10+19 From 880c64b6af69125d9a048354b34756a030c3c0d8 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 9 Aug 2017 15:39:50 -0700 Subject: [PATCH 12/42] 8185984: fix a11y and html issues in java.logging module Reviewed-by: dfuchs, mchung --- .../classes/java/util/logging/LogManager.java | 21 ++++++++++++------- .../classes/java/util/logging/Logger.java | 6 +++--- .../java/util/logging/SimpleFormatter.java | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java index 74bda0a928f..31c5e74c624 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -1887,13 +1887,17 @@ public class LogManager { * The registered {@linkplain #addConfigurationListener configuration * listeners} will be invoked after the configuration is successfully updated. *

    - * + *
    Updating configuration properties
    + * + * * - * - * + * + * * + * + * * - * + * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * + * *
    Updating configuration properties
    PropertyResulting BehaviorPropertyResulting Behavior
    {@code .level}{@code .level} *
      *
    • If the resulting configuration defines a level for a logger and @@ -1914,7 +1918,7 @@ public class LogManager { *
    *
    {@code .useParentHandlers}{@code .useParentHandlers} *
      *
    • If either the resulting or the old value for the useParentHandlers @@ -1928,7 +1932,7 @@ public class LogManager { *
    {@code .handlers}{@code .handlers} *
      *
    • If the resulting configuration defines a list of handlers for a @@ -1952,7 +1956,7 @@ public class LogManager { *
    {@code .*}{@code .*} *
      *
    • Properties configured/changed on handler classes will only affect @@ -1964,7 +1968,7 @@ public class LogManager { *
    {@code config} and any other property{@code config} and any other property *
      *
    • The resulting value for these property will be stored in the @@ -1974,6 +1978,7 @@ public class LogManager { *
    *
    *

    * Example mapper functions: diff --git a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java index dea269302d2..6a1d4b5bc30 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1497,7 +1497,7 @@ public class Logger { * The {@code msg} string is localized using the given resource bundle. * If the resource bundle is {@code null}, then the {@code msg} string is not * localized. - *

    + * * @param level One of the message level identifiers, e.g., {@code SEVERE} * @param bundle Resource bundle to localize {@code msg}; * can be {@code null}. @@ -1614,7 +1614,7 @@ public class Logger { * processed specially by output {@code Formatter} objects and is not treated * as a formatting parameter to the {@code LogRecord} {@code message} * property. - *

    + * * @param level One of the message level identifiers, e.g., {@code SEVERE} * @param bundle Resource bundle to localize {@code msg}; * can be {@code null}. diff --git a/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java b/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java index fe81640654b..2324940502e 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java @@ -41,7 +41,7 @@ import jdk.internal.logger.SurrogateLogger; * The {@code SimpleFormatter} is initialized with the * format string * specified in the {@code java.util.logging.SimpleFormatter.format} - * property to {@linkplain #format format} the log messages. + * property to {@linkplain #format(LogRecord) format} the log messages. * This property can be defined * in the {@linkplain LogManager#getProperty logging properties} * configuration file From 9f28d43df598d07815a3b78a192a203607733168 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Wed, 9 Aug 2017 17:30:51 -0700 Subject: [PATCH 13/42] 8185830: ConcurrentSkipListSet.clone() fails with UnsupportedOperationException Reviewed-by: martin, psandoz, plevart --- .../concurrent/ConcurrentSkipListSet.java | 27 ++++++++++--------- .../tck/ConcurrentSkipListSetTest.java | 20 +++++++++++++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 8149d0877dd..82e4b987781 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -35,8 +35,7 @@ package java.util.concurrent; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.VarHandle; +import java.lang.reflect.Field; import java.util.AbstractSet; import java.util.Collection; import java.util.Collections; @@ -506,19 +505,21 @@ public class ConcurrentSkipListSet : ((ConcurrentSkipListMap.SubMap)m).new SubMapKeyIterator(); } - // Support for resetting map in clone + /** Initializes map field; for use in clone. */ private void setMap(ConcurrentNavigableMap map) { - MAP.setVolatile(this, map); - } - - // VarHandle mechanics - private static final VarHandle MAP; - static { + Field mapField = java.security.AccessController.doPrivileged( + (java.security.PrivilegedAction) () -> { + try { + Field f = ConcurrentSkipListSet.class + .getDeclaredField("m"); + f.setAccessible(true); + return f; + } catch (ReflectiveOperationException e) { + throw new Error(e); + }}); try { - MethodHandles.Lookup l = MethodHandles.lookup(); - MAP = l.findVarHandle(ConcurrentSkipListSet.class, "m", - ConcurrentNavigableMap.class); - } catch (ReflectiveOperationException e) { + mapField.set(this, map); + } catch (IllegalAccessException e) { throw new Error(e); } } diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java index cb28b6ae0e7..97331e63501 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java @@ -553,7 +553,25 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { } /** - * A deserialized serialized set has same elements + * A cloned set equals original + */ + public void testClone() { + ConcurrentSkipListSet x = populatedSet(SIZE); + ConcurrentSkipListSet y = x.clone(); + + assertNotSame(x, y); + assertEquals(x.size(), y.size()); + assertEquals(x, y); + assertEquals(y, x); + while (!x.isEmpty()) { + assertFalse(y.isEmpty()); + assertEquals(x.pollFirst(), y.pollFirst()); + } + assertTrue(y.isEmpty()); + } + + /** + * A deserialized/reserialized set equals original */ public void testSerialization() throws Exception { NavigableSet x = populatedSet(SIZE); From 2f31db126d5500e17ff2d79facb701ba5541e2ed Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Wed, 9 Aug 2017 17:40:38 -0700 Subject: [PATCH 14/42] 8185099: Miscellaneous changes imported from jsr166 CVS 2017-08 Reviewed-by: martin, psandoz --- .../classes/java/util/concurrent/Flow.java | 4 +- .../util/concurrent/ThreadPoolExecutor.java | 8 ++-- .../tck/ArrayBlockingQueueTest.java | 2 +- .../util/concurrent/tck/ArrayDequeTest.java | 2 +- .../util/concurrent/tck/ArrayListTest.java | 24 ++++++++++ .../concurrent/tck/AtomicBooleanTest.java | 2 +- .../tck/AtomicIntegerArrayTest.java | 2 +- .../concurrent/tck/AtomicIntegerTest.java | 2 +- .../concurrent/tck/AtomicLongArrayTest.java | 2 +- .../util/concurrent/tck/AtomicLongTest.java | 2 +- .../tck/AtomicReferenceArrayTest.java | 2 +- .../concurrent/tck/AtomicReferenceTest.java | 2 +- .../tck/ConcurrentHashMap8Test.java | 2 +- .../concurrent/tck/ConcurrentHashMapTest.java | 2 +- .../tck/ConcurrentLinkedDequeTest.java | 2 +- .../tck/ConcurrentLinkedQueueTest.java | 2 +- .../tck/ConcurrentSkipListMapTest.java | 22 ++++++++- .../tck/ConcurrentSkipListSubMapTest.java | 4 +- .../tck/ConcurrentSkipListSubSetTest.java | 4 +- .../tck/CopyOnWriteArrayListTest.java | 2 +- .../tck/CopyOnWriteArraySetTest.java | 2 +- .../util/concurrent/tck/DoubleAdderTest.java | 2 +- .../util/concurrent/tck/JSR166TestCase.java | 47 ------------------- .../tck/LinkedBlockingDequeTest.java | 2 +- .../tck/LinkedBlockingQueueTest.java | 2 +- .../tck/LinkedTransferQueueTest.java | 2 +- .../util/concurrent/tck/LongAdderTest.java | 2 +- .../tck/PriorityBlockingQueueTest.java | 2 +- .../concurrent/tck/PriorityQueueTest.java | 2 +- .../concurrent/tck/SynchronousQueueTest.java | 2 +- .../tck/ThreadLocalRandom8Test.java | 4 +- .../tck/ThreadPoolExecutorSubclassTest.java | 4 +- .../util/concurrent/tck/TimeUnitTest.java | 2 +- .../java/util/concurrent/tck/TreeMapTest.java | 2 +- .../java/util/concurrent/tck/TreeSetTest.java | 2 +- .../util/concurrent/tck/TreeSubMapTest.java | 4 +- .../util/concurrent/tck/TreeSubSetTest.java | 4 +- 37 files changed, 89 insertions(+), 92 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/Flow.java b/jdk/src/java.base/share/classes/java/util/concurrent/Flow.java index 65e994350ce..1aefaea43b0 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/Flow.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/Flow.java @@ -85,9 +85,9 @@ package java.util.concurrent; * this.executor = executor; * } * public synchronized void request(long n) { - * if (n != 0 && !completed) { + * if (!completed) { * completed = true; - * if (n < 0) { + * if (n <= 0) { * IllegalArgumentException ex = new IllegalArgumentException(); * executor.execute(() -> subscriber.onError(ex)); * } else { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java index 1b3b866b25c..21221005f52 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java @@ -576,7 +576,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { private static final RuntimePermission shutdownPerm = new RuntimePermission("modifyThread"); - /* The context to be used when executing the finalizer, or null. */ + /** The context to be used when executing the finalizer, or null. */ private final AccessControlContext acc; /** @@ -1314,9 +1314,9 @@ public class ThreadPoolExecutor extends AbstractExecutorService { throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); - this.acc = System.getSecurityManager() == null ? - null : - AccessController.getContext(); + this.acc = (System.getSecurityManager() == null) + ? null + : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; diff --git a/jdk/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java b/jdk/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java index 589037bd511..a2744c2646f 100644 --- a/jdk/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java @@ -903,7 +903,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { } /** - * A deserialized serialized queue has same elements in same order + * A deserialized/reserialized queue has same elements in same order */ public void testSerialization() throws Exception { Queue x = populatedQueue(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/ArrayDequeTest.java b/jdk/test/java/util/concurrent/tck/ArrayDequeTest.java index 344b63c9b79..4ea7ee7a475 100644 --- a/jdk/test/java/util/concurrent/tck/ArrayDequeTest.java +++ b/jdk/test/java/util/concurrent/tck/ArrayDequeTest.java @@ -939,7 +939,7 @@ public class ArrayDequeTest extends JSR166TestCase { } /** - * A deserialized serialized deque has same elements in same order + * A deserialized/reserialized deque has same elements in same order */ public void testSerialization() throws Exception { Queue x = populatedDeque(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/ArrayListTest.java b/jdk/test/java/util/concurrent/tck/ArrayListTest.java index 535f04d34b5..203c04c6ea9 100644 --- a/jdk/test/java/util/concurrent/tck/ArrayListTest.java +++ b/jdk/test/java/util/concurrent/tck/ArrayListTest.java @@ -33,6 +33,7 @@ */ import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import junit.framework.Test; @@ -61,4 +62,27 @@ public class ArrayListTest extends JSR166TestCase { CollectionTest.testSuite(new SubListImplementation())); } + /** + * A cloned list equals original + */ + public void testClone() throws Exception { + ArrayList x = new ArrayList<>(); + x.add(1); + x.add(2); + x.add(3); + ArrayList y = (ArrayList) x.clone(); + + assertNotSame(y, x); + assertEquals(x, y); + assertEquals(y, x); + assertEquals(x.size(), y.size()); + assertEquals(x.toString(), y.toString()); + assertTrue(Arrays.equals(x.toArray(), y.toArray())); + while (!x.isEmpty()) { + assertFalse(y.isEmpty()); + assertEquals(x.remove(0), y.remove(0)); + } + assertTrue(y.isEmpty()); + } + } diff --git a/jdk/test/java/util/concurrent/tck/AtomicBooleanTest.java b/jdk/test/java/util/concurrent/tck/AtomicBooleanTest.java index be136357ff1..05a196ca724 100644 --- a/jdk/test/java/util/concurrent/tck/AtomicBooleanTest.java +++ b/jdk/test/java/util/concurrent/tck/AtomicBooleanTest.java @@ -147,7 +147,7 @@ public class AtomicBooleanTest extends JSR166TestCase { } /** - * a deserialized serialized atomic holds same value + * a deserialized/reserialized atomic holds same value */ public void testSerialization() throws Exception { AtomicBoolean x = new AtomicBoolean(); diff --git a/jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java b/jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java index e12284063f1..cdcf0061667 100644 --- a/jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java +++ b/jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java @@ -342,7 +342,7 @@ public class AtomicIntegerArrayTest extends JSR166TestCase { } /** - * a deserialized serialized array holds same values + * a deserialized/reserialized array holds same values in same order */ public void testSerialization() throws Exception { AtomicIntegerArray x = new AtomicIntegerArray(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/AtomicIntegerTest.java b/jdk/test/java/util/concurrent/tck/AtomicIntegerTest.java index d148788d792..6f3546038bc 100644 --- a/jdk/test/java/util/concurrent/tck/AtomicIntegerTest.java +++ b/jdk/test/java/util/concurrent/tck/AtomicIntegerTest.java @@ -218,7 +218,7 @@ public class AtomicIntegerTest extends JSR166TestCase { } /** - * a deserialized serialized atomic holds same value + * a deserialized/reserialized atomic holds same value */ public void testSerialization() throws Exception { AtomicInteger x = new AtomicInteger(); diff --git a/jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java b/jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java index b312388dd6a..72d0e0677ab 100644 --- a/jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java +++ b/jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java @@ -341,7 +341,7 @@ public class AtomicLongArrayTest extends JSR166TestCase { } /** - * a deserialized serialized array holds same values + * a deserialized/reserialized array holds same values in same order */ public void testSerialization() throws Exception { AtomicLongArray x = new AtomicLongArray(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/AtomicLongTest.java b/jdk/test/java/util/concurrent/tck/AtomicLongTest.java index f5191af99e6..c41a861ce09 100644 --- a/jdk/test/java/util/concurrent/tck/AtomicLongTest.java +++ b/jdk/test/java/util/concurrent/tck/AtomicLongTest.java @@ -220,7 +220,7 @@ public class AtomicLongTest extends JSR166TestCase { } /** - * a deserialized serialized atomic holds same value + * a deserialized/reserialized atomic holds same value */ public void testSerialization() throws Exception { AtomicLong x = new AtomicLong(); diff --git a/jdk/test/java/util/concurrent/tck/AtomicReferenceArrayTest.java b/jdk/test/java/util/concurrent/tck/AtomicReferenceArrayTest.java index 019446cc14d..8a9cf20a2ca 100644 --- a/jdk/test/java/util/concurrent/tck/AtomicReferenceArrayTest.java +++ b/jdk/test/java/util/concurrent/tck/AtomicReferenceArrayTest.java @@ -220,7 +220,7 @@ public class AtomicReferenceArrayTest extends JSR166TestCase { } /** - * a deserialized serialized array holds same values + * a deserialized/reserialized array holds same values in same order */ public void testSerialization() throws Exception { AtomicReferenceArray x = new AtomicReferenceArray(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/AtomicReferenceTest.java b/jdk/test/java/util/concurrent/tck/AtomicReferenceTest.java index eb8c0b7b565..f46bd786c8f 100644 --- a/jdk/test/java/util/concurrent/tck/AtomicReferenceTest.java +++ b/jdk/test/java/util/concurrent/tck/AtomicReferenceTest.java @@ -143,7 +143,7 @@ public class AtomicReferenceTest extends JSR166TestCase { } /** - * a deserialized serialized atomic holds same value + * a deserialized/reserialized atomic holds same value */ public void testSerialization() throws Exception { AtomicReference x = new AtomicReference(); diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java b/jdk/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java index e0d9f81a7f1..e5c75b13516 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java @@ -570,7 +570,7 @@ public class ConcurrentHashMap8Test extends JSR166TestCase { } /** - * A deserialized serialized set is equal + * A deserialized/reserialized set equals original */ public void testSerialization() throws Exception { int size = 20; diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java index 729a6e3d146..007d3b6798d 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java @@ -811,7 +811,7 @@ public class ConcurrentHashMapTest extends JSR166TestCase { } /** - * A deserialized map equals original + * A deserialized/reserialized map equals original */ public void testSerialization() throws Exception { Map x = map5(); diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java index 65a73621ef3..4ad7303b1f7 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java @@ -889,7 +889,7 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { } /** - * A deserialized serialized deque has same elements in same order + * A deserialized/reserialized deque has same elements in same order */ public void testSerialization() throws Exception { Queue x = populatedDeque(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java index f2cbc950ce1..e78ba3f20ca 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java @@ -538,7 +538,7 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { } /** - * A deserialized serialized queue has same elements in same order + * A deserialized/reserialized queue has same elements in same order */ public void testSerialization() throws Exception { Queue x = populatedQueue(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java index 0b1faad2824..fdd9892f09a 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java @@ -828,7 +828,24 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { } /** - * A deserialized map equals original + * A cloned map equals original + */ + public void testClone() { + ConcurrentSkipListMap x = map5(); + ConcurrentSkipListMap y = x.clone(); + + assertNotSame(x, y); + assertEquals(x.size(), y.size()); + assertEquals(x.toString(), y.toString()); + assertEquals(x, y); + assertEquals(y, x); + y.clear(); + assertTrue(y.isEmpty()); + assertFalse(x.equals(y)); + } + + /** + * A deserialized/reserialized map equals original */ public void testSerialization() throws Exception { NavigableMap x = map5(); @@ -839,6 +856,9 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { assertEquals(x.toString(), y.toString()); assertEquals(x, y); assertEquals(y, x); + y.clear(); + assertTrue(y.isEmpty()); + assertFalse(x.equals(y)); } /** diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubMapTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubMapTest.java index ddc82f78a56..e3f6c577cf2 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubMapTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubMapTest.java @@ -625,7 +625,7 @@ public class ConcurrentSkipListSubMapTest extends JSR166TestCase { } /** - * A deserialized map equals original + * A deserialized/reserialized map equals original */ public void testSerialization() throws Exception { NavigableMap x = map5(); @@ -1299,7 +1299,7 @@ public class ConcurrentSkipListSubMapTest extends JSR166TestCase { } /** - * A deserialized map equals original + * A deserialized/reserialized map equals original */ public void testDescendingSerialization() throws Exception { NavigableMap x = dmap5(); diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java index 19d34cc01e1..3cc968f4b1b 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java @@ -503,7 +503,7 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { } /** - * A deserialized serialized set has same elements + * A deserialized/reserialized set equals original */ public void testSerialization() throws Exception { NavigableSet x = populatedSet(SIZE); @@ -1002,7 +1002,7 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { } /** - * A deserialized serialized set has same elements + * A deserialized/reserialized set equals original */ public void testDescendingSerialization() throws Exception { NavigableSet x = dset5(); diff --git a/jdk/test/java/util/concurrent/tck/CopyOnWriteArrayListTest.java b/jdk/test/java/util/concurrent/tck/CopyOnWriteArrayListTest.java index 2b13e130701..5e04d4cc4dd 100644 --- a/jdk/test/java/util/concurrent/tck/CopyOnWriteArrayListTest.java +++ b/jdk/test/java/util/concurrent/tck/CopyOnWriteArrayListTest.java @@ -774,7 +774,7 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { } /** - * a deserialized serialized list is equal + * a deserialized/reserialized list equals original */ public void testSerialization() throws Exception { List x = populatedArray(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/CopyOnWriteArraySetTest.java b/jdk/test/java/util/concurrent/tck/CopyOnWriteArraySetTest.java index 2595589cc78..c28051a9b68 100644 --- a/jdk/test/java/util/concurrent/tck/CopyOnWriteArraySetTest.java +++ b/jdk/test/java/util/concurrent/tck/CopyOnWriteArraySetTest.java @@ -403,7 +403,7 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { } /** - * A deserialized serialized set is equal + * A deserialized/reserialized set equals original */ public void testSerialization() throws Exception { Set x = populatedSet(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/DoubleAdderTest.java b/jdk/test/java/util/concurrent/tck/DoubleAdderTest.java index fc7d1f47834..ba3fbc4a455 100644 --- a/jdk/test/java/util/concurrent/tck/DoubleAdderTest.java +++ b/jdk/test/java/util/concurrent/tck/DoubleAdderTest.java @@ -89,7 +89,7 @@ public class DoubleAdderTest extends JSR166TestCase { } /** - * a deserialized serialized adder holds same value + * a deserialized/reserialized adder holds same value */ public void testSerialization() throws Exception { DoubleAdder x = new DoubleAdder(); diff --git a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java index f01acb4c6d7..2b25238201a 100644 --- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java +++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java @@ -1142,53 +1142,6 @@ public class JSR166TestCase extends TestCase { fail("timed out waiting for thread to enter thread state " + expected); } - /** - * Checks that thread does not terminate within the default - * millisecond delay of {@code timeoutMillis()}. - * TODO: REMOVEME - */ - void assertThreadStaysAlive(Thread thread) { - assertThreadStaysAlive(thread, timeoutMillis()); - } - - /** - * Checks that thread does not terminate within the given millisecond delay. - * TODO: REMOVEME - */ - void assertThreadStaysAlive(Thread thread, long millis) { - try { - // No need to optimize the failing case via Thread.join. - delay(millis); - assertTrue(thread.isAlive()); - } catch (InterruptedException fail) { - threadFail("Unexpected InterruptedException"); - } - } - - /** - * Checks that the threads do not terminate within the default - * millisecond delay of {@code timeoutMillis()}. - * TODO: REMOVEME - */ - void assertThreadsStayAlive(Thread... threads) { - assertThreadsStayAlive(timeoutMillis(), threads); - } - - /** - * Checks that the threads do not terminate within the given millisecond delay. - * TODO: REMOVEME - */ - void assertThreadsStayAlive(long millis, Thread... threads) { - try { - // No need to optimize the failing case via Thread.join. - delay(millis); - for (Thread thread : threads) - assertTrue(thread.isAlive()); - } catch (InterruptedException fail) { - threadFail("Unexpected InterruptedException"); - } - } - /** * Checks that future.get times out, with the default timeout of * {@code timeoutMillis()}. diff --git a/jdk/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java b/jdk/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java index bc611770605..5388fbaa1a9 100644 --- a/jdk/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java +++ b/jdk/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java @@ -1800,7 +1800,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { } /** - * A deserialized serialized deque has same elements in same order + * A deserialized/reserialized deque has same elements in same order */ public void testSerialization() throws Exception { Queue x = populatedDeque(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java b/jdk/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java index 596f30dad2f..b880ea28724 100644 --- a/jdk/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java @@ -823,7 +823,7 @@ public class LinkedBlockingQueueTest extends JSR166TestCase { } /** - * A deserialized serialized queue has same elements in same order + * A deserialized/reserialized queue has same elements in same order */ public void testSerialization() throws Exception { Queue x = populatedQueue(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java b/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java index 401b0da9025..4e972676bfb 100644 --- a/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java @@ -674,7 +674,7 @@ public class LinkedTransferQueueTest extends JSR166TestCase { } /** - * A deserialized serialized queue has same elements in same order + * A deserialized/reserialized queue has same elements in same order */ public void testSerialization() throws Exception { Queue x = populatedQueue(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/LongAdderTest.java b/jdk/test/java/util/concurrent/tck/LongAdderTest.java index 4f0d5e07f75..c4c16a81a3d 100644 --- a/jdk/test/java/util/concurrent/tck/LongAdderTest.java +++ b/jdk/test/java/util/concurrent/tck/LongAdderTest.java @@ -111,7 +111,7 @@ public class LongAdderTest extends JSR166TestCase { } /** - * a deserialized serialized adder holds same value + * a deserialized/reserialized adder holds same value */ public void testSerialization() throws Exception { LongAdder x = new LongAdder(); diff --git a/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java b/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java index 603a66ff4a4..0279a6f03b2 100644 --- a/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java @@ -686,7 +686,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { } /** - * A deserialized serialized queue has same elements + * A deserialized/reserialized queue has same elements */ public void testSerialization() throws Exception { Queue x = populatedQueue(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java b/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java index 81e8d770e51..179e9cda0b0 100644 --- a/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java @@ -522,7 +522,7 @@ public class PriorityQueueTest extends JSR166TestCase { } /** - * A deserialized serialized queue has same elements + * A deserialized/reserialized queue has same elements */ public void testSerialization() throws Exception { Queue x = populatedQueue(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/SynchronousQueueTest.java b/jdk/test/java/util/concurrent/tck/SynchronousQueueTest.java index 521dd8950cb..0a431d286a8 100644 --- a/jdk/test/java/util/concurrent/tck/SynchronousQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/SynchronousQueueTest.java @@ -557,7 +557,7 @@ public class SynchronousQueueTest extends JSR166TestCase { } /** - * a deserialized serialized queue is usable + * a deserialized/reserialized queue is usable */ public void testSerialization() { final SynchronousQueue x = new SynchronousQueue(); diff --git a/jdk/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java b/jdk/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java index eef34d34149..dcf83eeefeb 100644 --- a/jdk/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java +++ b/jdk/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java @@ -260,8 +260,8 @@ public class ThreadLocalRandom8Test extends JSR166TestCase { } /** - * A deserialized ThreadLocalRandom is always identical to - * ThreadLocalRandom.current() + * A deserialized/reserialized ThreadLocalRandom is always + * identical to ThreadLocalRandom.current() */ public void testSerialization() { assertSame( diff --git a/jdk/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java b/jdk/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java index cf877007875..74c8abdee4f 100644 --- a/jdk/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java +++ b/jdk/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java @@ -1319,8 +1319,8 @@ public class ThreadPoolExecutorSubclassTest extends JSR166TestCase { public void testMaximumPoolSizeIllegalArgumentException2() { final ThreadPoolExecutor p = new CustomTPE(2, 3, - LONG_DELAY_MS, - MILLISECONDS,new ArrayBlockingQueue(10)); + LONG_DELAY_MS, MILLISECONDS, + new ArrayBlockingQueue(10)); try (PoolCleaner cleaner = cleaner(p)) { try { p.setMaximumPoolSize(-1); diff --git a/jdk/test/java/util/concurrent/tck/TimeUnitTest.java b/jdk/test/java/util/concurrent/tck/TimeUnitTest.java index 6e9aaa8bf4b..df924e3151c 100644 --- a/jdk/test/java/util/concurrent/tck/TimeUnitTest.java +++ b/jdk/test/java/util/concurrent/tck/TimeUnitTest.java @@ -623,7 +623,7 @@ public class TimeUnitTest extends JSR166TestCase { } /** - * a deserialized serialized unit is the same instance + * a deserialized/reserialized unit is the same instance */ public void testSerialization() throws Exception { for (TimeUnit x : TimeUnit.values()) diff --git a/jdk/test/java/util/concurrent/tck/TreeMapTest.java b/jdk/test/java/util/concurrent/tck/TreeMapTest.java index ada561ea119..bd24e32e951 100644 --- a/jdk/test/java/util/concurrent/tck/TreeMapTest.java +++ b/jdk/test/java/util/concurrent/tck/TreeMapTest.java @@ -633,7 +633,7 @@ public class TreeMapTest extends JSR166TestCase { } /** - * A deserialized map equals original + * A deserialized/reserialized map equals original */ public void testSerialization() throws Exception { NavigableMap x = map5(); diff --git a/jdk/test/java/util/concurrent/tck/TreeSetTest.java b/jdk/test/java/util/concurrent/tck/TreeSetTest.java index 55b28d613d9..4d3fe24815a 100644 --- a/jdk/test/java/util/concurrent/tck/TreeSetTest.java +++ b/jdk/test/java/util/concurrent/tck/TreeSetTest.java @@ -549,7 +549,7 @@ public class TreeSetTest extends JSR166TestCase { } /** - * A deserialized serialized set has same elements + * A deserialized/reserialized set equals original */ public void testSerialization() throws Exception { NavigableSet x = populatedSet(SIZE); diff --git a/jdk/test/java/util/concurrent/tck/TreeSubMapTest.java b/jdk/test/java/util/concurrent/tck/TreeSubMapTest.java index 1b5fa424b1c..05e876292b8 100644 --- a/jdk/test/java/util/concurrent/tck/TreeSubMapTest.java +++ b/jdk/test/java/util/concurrent/tck/TreeSubMapTest.java @@ -460,7 +460,7 @@ public class TreeSubMapTest extends JSR166TestCase { } /** - * A deserialized map equals original + * A deserialized/reserialized map equals original */ public void testSerialization() throws Exception { NavigableMap x = map5(); @@ -987,7 +987,7 @@ public class TreeSubMapTest extends JSR166TestCase { } /** - * A deserialized map equals original + * A deserialized/reserialized map equals original */ public void testDescendingSerialization() throws Exception { NavigableMap x = dmap5(); diff --git a/jdk/test/java/util/concurrent/tck/TreeSubSetTest.java b/jdk/test/java/util/concurrent/tck/TreeSubSetTest.java index a0f2b96ee57..10e37e9f7b4 100644 --- a/jdk/test/java/util/concurrent/tck/TreeSubSetTest.java +++ b/jdk/test/java/util/concurrent/tck/TreeSubSetTest.java @@ -500,7 +500,7 @@ public class TreeSubSetTest extends JSR166TestCase { } /** - * A deserialized serialized set has same elements + * A deserialized/reserialized set equals original */ public void testSerialization() throws Exception { NavigableSet x = populatedSet(SIZE); @@ -988,7 +988,7 @@ public class TreeSubSetTest extends JSR166TestCase { } /** - * A deserialized serialized set has same elements + * A deserialized/reserialized set equals original */ public void testDescendingSerialization() throws Exception { NavigableSet x = dset5(); From 330008fbf2dc20c05c558227579081bd4db26b5f Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 10 Aug 2017 15:21:17 -0700 Subject: [PATCH 15/42] 8185994: Fix a11y and HTML issues in the java.base/java.io and java.base/java.nio packages Reviewed-by: bpb, smarks --- .../share/classes/java/io/DataInput.java | 101 ++++++----- .../java/nio/channels/package-info.java | 166 ++++++++++-------- .../java/nio/charset/package-info.java | 29 +-- .../classes/java/nio/file/FileSystem.java | 24 +-- .../share/classes/java/nio/file/Files.java | 17 +- .../java/nio/file/attribute/package-info.java | 60 ++++--- .../share/classes/java/nio/package-info.java | 61 ++++--- 7 files changed, 253 insertions(+), 205 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/io/DataInput.java b/jdk/src/java.base/share/classes/java/io/DataInput.java index 70f78a6a068..86d8d3eb9fd 100644 --- a/jdk/src/java.base/share/classes/java/io/DataInput.java +++ b/jdk/src/java.base/share/classes/java/io/DataInput.java @@ -54,83 +54,90 @@ package java.io; * Unicode strings in a format that is a slight modification of UTF-8. * (For information regarding the standard UTF-8 format, see section * 3.9 Unicode Encoding Forms of The Unicode Standard, Version - * 4.0). - * Note that in the following table, the most significant bit appears in the - * far left-hand column. + * 4.0) * - *

    - * - * + *
      + *
    • Characters in the range {@code '\u005Cu0001'} to + * {@code '\u005Cu007F'} are represented by a single byte. + *
    • The null character {@code '\u005Cu0000'} and characters + * in the range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are + * represented by a pair of bytes. + *
    • Characters in the range {@code '\u005Cu0800'} + * to {@code '\u005CuFFFF'} are represented by three bytes. + *
    + * + *
    Bit values and bytes
    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * * * - * - * - * - * - * - * - * - * + * + * * * - * - * - * - * - * - * - * - * + * + * * * - * + * + * * * - * - * - * - * - * - * - * - * + * + * * * - * + * + * * * - * + * + * * * *
    Encoding of UTF-8 values
    ValueByteBit Values
    7 6 5 4 3 2 1 0
    - * All characters in the range {@code '\u005Cu0001'} to - * {@code '\u005Cu007F'} are represented by a single byte:
    Bit Values
    Byte 1 + * {@code \u005Cu0001} to {@code \u005Cu007F} 1 0 - * bits 6-0 + * bits 6-0 *
    - * The null character {@code '\u005Cu0000'} and characters - * in the range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are - * represented by a pair of bytes:
    Bit Values
    Byte 1 + * {@code \u005Cu0000},
    + * {@code \u005Cu0080} to {@code \u005Cu07FF}
    1 1 * 1 * 0 - * bits 10-6 + * bits 10-6 *
    Byte 2 2 1 * 0 - * bits 5-0 + * bits 5-0 *
    - * {@code char} values in the range {@code '\u005Cu0800'} - * to {@code '\u005CuFFFF'} are represented by three bytes:
    Bit Values
    Byte 1 + * {@code \u005Cu0800} to {@code \u005CuFFFF} 1 1 * 1 * 1 * 0 - * bits 15-12 + * bits 15-12 *
    Byte 2 2 1 * 0 - * bits 11-6 + * bits 11-6 *
    Byte 3 3 1 * 0 - * bits 5-0 + * bits 5-0 *
    - *
    + * *

    * The differences between this format and the * standard UTF-8 format are the following: diff --git a/jdk/src/java.base/share/classes/java/nio/channels/package-info.java b/jdk/src/java.base/share/classes/java/nio/channels/package-info.java index d29ae67590f..0dc410ddd76 100644 --- a/jdk/src/java.base/share/classes/java/nio/channels/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/channels/package-info.java @@ -30,46 +30,50 @@ * * * - *

    + *
    * - * - * - * + * + * + * + * + * + * * - * + * * - * - * - * + * + * + * * - * - * - * - * - * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - *
    Lists channels and their descriptions
    ChannelsDescription
    {@link java.nio.channels.Channel}
    ChannelsDescription
    {@link java.nio.channels.Channel}A nexus for I/O operations
    - *   {@link java.nio.channels.ReadableByteChannel}
    + * {@link java.nio.channels.ReadableByteChannel}Can read into a buffer
    - *     {@link java.nio.channels.ScatteringByteChannel}  Can read into a sequence of buffers
    - *   {@link java.nio.channels.WritableByteChannel}
    + * {@link java.nio.channels.ScatteringByteChannel}Can read into a sequence of buffers
    + * {@link java.nio.channels.WritableByteChannel}Can write from a buffer
    - *     {@link java.nio.channels.GatheringByteChannel}Can write from a sequence of buffers
    - *   {@link java.nio.channels.ByteChannel}Can read/write to/from a buffer
    - *     {@link java.nio.channels.SeekableByteChannel}
    + * {@link java.nio.channels.GatheringByteChannel}Can write from a sequence of buffers
    + * {@link java.nio.channels.ByteChannel}Can read/write to/from a buffer
    + * {@link java.nio.channels.SeekableByteChannel}A {@code ByteChannel} connected to an entity that contains a variable-length * sequence of bytes
    - *   {@link java.nio.channels.AsynchronousChannel}
    + * {@link java.nio.channels.AsynchronousChannel}Supports asynchronous I/O operations.
    - *     {@link java.nio.channels.AsynchronousByteChannel}
    + * {@link java.nio.channels.AsynchronousByteChannel}Can read and write bytes asynchronously
    - *   {@link java.nio.channels.NetworkChannel}
    + * {@link java.nio.channels.NetworkChannel}A channel to a network socket
    - *     {@link java.nio.channels.MulticastChannel}
    + * {@link java.nio.channels.MulticastChannel}Can join Internet Protocol (IP) multicast groups
    {@link java.nio.channels.Channels}
    {@link java.nio.channels.Channels}Utility methods for channel/stream interoperation
    + *
* *

A channel represents an open connection to an entity such as a * hardware device, a file, a network socket, or a program component that is @@ -122,21 +126,25 @@ * be constructed that uses a given charset to encode characters into bytes and * write them to a given writable byte channel. * - *

+ *
* - * - * - * + * + * + * + * + * + * * - * + * * - * - * - *
* Lists file channels and their descriptions
File channelsDescription
- * {@link java.nio.channels.FileChannel}
File channelsDescription
+ * {@link java.nio.channels.FileChannel}Reads, writes, maps, and manipulates files
- * {@link java.nio.channels.FileLock}
+ * {@link java.nio.channels.FileLock}A lock on a (region of a) file
- * {@link java.nio.MappedByteBuffer}  A direct byte buffer mapped to a region of a file
+ * + * {@link java.nio.MappedByteBuffer} + * A direct byte buffer mapped to a region of a file + * + * * *

The {@link java.nio.channels.FileChannel} class supports the usual * operations of reading bytes from, and writing bytes to, a channel connected to @@ -156,36 +164,40 @@ * class. * * - *

+ *
* - * - * - * + * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * - * - * - * - *
* Lists multiplexed, non-blocking channels and their descriptions
Multiplexed, non-blocking I/ODescription
{@link java.nio.channels.SelectableChannel}
Multiplexed, non-blocking I/ODescription
{@link java.nio.channels.SelectableChannel}A channel that can be multiplexed
- *   {@link java.nio.channels.DatagramChannel}
+ * {@link java.nio.channels.DatagramChannel}A channel to a datagram-oriented socket
- *   {@link java.nio.channels.Pipe.SinkChannel}
+ * {@link java.nio.channels.Pipe.SinkChannel}The write end of a pipe
- *   {@link java.nio.channels.Pipe.SourceChannel}
+ * {@link java.nio.channels.Pipe.SourceChannel}The read end of a pipe
- *   {@link java.nio.channels.ServerSocketChannel}  
+ * {@link java.nio.channels.ServerSocketChannel}A channel to a stream-oriented listening socket
- *   {@link java.nio.channels.SocketChannel}
+ * {@link java.nio.channels.SocketChannel}A channel for a stream-oriented connecting socket
{@link java.nio.channels.Selector}
{@link java.nio.channels.Selector}A multiplexor of selectable channels
{@link java.nio.channels.SelectionKey}A token representing the registration
of a channel - * with a selector
{@link java.nio.channels.Pipe}Two channels that form a unidirectional pipe
+ * {@link java.nio.channels.SelectionKey} + * A token representing the registration of a channel + * with a selector + * {@link java.nio.channels.Pipe} + * Two channels that form a unidirectional pipe + * + * * *

Multiplexed, non-blocking I/O, which is much more scalable than * thread-oriented, blocking I/O, is provided by selectors, selectable @@ -251,27 +263,31 @@ * * * - *

+ *
* - * - * + * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - *
* Lists asynchronous channels and their descriptions
- * Asynchronous I/ODescription
- * {@link java.nio.channels.AsynchronousFileChannel}
Asynchronous I/ODescription
+ * {@link java.nio.channels.AsynchronousFileChannel}An asynchronous channel for reading, writing, and manipulating a file
- * {@link java.nio.channels.AsynchronousSocketChannel}
+ * {@link java.nio.channels.AsynchronousSocketChannel}An asynchronous channel to a stream-oriented connecting socket
- * {@link java.nio.channels.AsynchronousServerSocketChannel}  
+ * {@link java.nio.channels.AsynchronousServerSocketChannel}An asynchronous channel to a stream-oriented listening socket
- * {@link java.nio.channels.CompletionHandler}
+ * {@link java.nio.channels.CompletionHandler}A handler for consuming the result of an asynchronous operation
- * {@link java.nio.channels.AsynchronousChannelGroup}
+ * {@link java.nio.channels.AsynchronousChannelGroup}A grouping of asynchronous channels for the purpose of resource sharing
+ * + * * *

{@link java.nio.channels.AsynchronousChannel Asynchronous channels} are a * special type of channel capable of asynchronous I/O operations. Asynchronous diff --git a/jdk/src/java.base/share/classes/java/nio/charset/package-info.java b/jdk/src/java.base/share/classes/java/nio/charset/package-info.java index 80141dc8b6a..046606a57db 100644 --- a/jdk/src/java.base/share/classes/java/nio/charset/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/charset/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,22 +27,25 @@ * Defines charsets, decoders, and encoders, for translating between * bytes and Unicode characters. * - *

+ *
* - * - * - * - * + * + * + * + * + * + * + * * - * + * * - * + * * - * - * - * - *
Summary of charsets, decoders, and encoders in this package
Class nameDescriptiPath - *
{@link java.nio.charset.Charset}A named mapping between characters
and bytes
{@link java.nio.charset.CharsetDecoder}
Class nameDescription + *
{@link java.nio.charset.Charset}A named mapping between characters and bytes
{@link java.nio.charset.CharsetDecoder}Decodes bytes into characters
{@link java.nio.charset.CharsetEncoder}
{@link java.nio.charset.CharsetEncoder}Encodes characters into bytes
{@link java.nio.charset.CoderResult}
{@link java.nio.charset.CoderResult}Describes coder results
{@link java.nio.charset.CodingErrorAction}Describes actions to take when
coding errors are detected
+ * {@link java.nio.charset.CodingErrorAction} + * Describes actions to take when coding errors are detected + * + * * *

A charset is named mapping between sequences of * sixteen-bit Unicode characters and sequences of bytes, in the sense diff --git a/jdk/src/java.base/share/classes/java/nio/file/FileSystem.java b/jdk/src/java.base/share/classes/java/nio/file/FileSystem.java index 0fd5be4fcf0..27bca11922e 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/FileSystem.java +++ b/jdk/src/java.base/share/classes/java/nio/file/FileSystem.java @@ -314,45 +314,49 @@ public abstract class FileSystem * representation of the path is matched using a limited pattern language * that resembles regular expressions but with a simpler syntax. For example: * - *

- * + *
* + * + * + * + * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * * * - * * * - * * * *
Pattern Language
Example + * Description + *
{@code *.java}{@code *.java}Matches a path that represents a file name ending in {@code .java}
{@code *.*}{@code *.*}Matches file names containing a dot
{@code *.{java,class}}{@code *.{java,class}}Matches file names ending with {@code .java} or {@code .class}
{@code foo.?}{@code foo.?}Matches file names starting with {@code foo.} and a single * character extension
/home/*/* + * /home/*/* * Matches /home/gus/data on UNIX platforms
/home/** + * /home/** * Matches /home/gus and * /home/gus/data on UNIX platforms
C:\\* + * C:\\* * Matches C:\foo and C:\bar on the Windows * platform (note that the backslash is escaped; as a string literal in the * Java Language the pattern would be "C:\\\\*")
- *
* *

The following rules are used to interpret glob patterns: * diff --git a/jdk/src/java.base/share/classes/java/nio/file/Files.java b/jdk/src/java.base/share/classes/java/nio/file/Files.java index 09bce16a844..f5dbba9c358 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/Files.java +++ b/jdk/src/java.base/share/classes/java/nio/file/Files.java @@ -1923,30 +1923,33 @@ public final class Files { *

The following examples demonstrate possible values for the {@code * attributes} parameter: * - *

- * + *
* + * + * + * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * *
Possible values
Example + * Description + *
{@code "*"} {@code "*"} Read all {@link BasicFileAttributes basic-file-attributes}.
{@code "size,lastModifiedTime,lastAccessTime"} {@code "size,lastModifiedTime,lastAccessTime"} Reads the file size, last modified time, and last access time * attributes.
{@code "posix:*"} {@code "posix:*"} Read all {@link PosixFileAttributes POSIX-file-attributes}.
{@code "posix:permissions,owner,size"} {@code "posix:permissions,owner,size"} Reads the POSIX file permissions, owner, and file size.
- *
* *

The {@code options} array may be used to indicate how symbolic links * are handled for the case that the file is a symbolic link. By default, diff --git a/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java b/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java index 11f5d6e2720..911d38a9bea 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,43 +26,47 @@ /** * Interfaces and classes providing access to file and file system attributes. * - *

+ *
* - * - * - * + * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - *
Attribute views
Attribute viewsDescription
{@link java.nio.file.attribute.AttributeView}
Attribute viewsDescription
{@link java.nio.file.attribute.AttributeView}Can read or update non-opaque values associated with objects in a file system
- *   {@link java.nio.file.attribute.FileAttributeView}
+ * {@link java.nio.file.attribute.FileAttributeView}Can read or update file attributes
- *      - * {@link java.nio.file.attribute.BasicFileAttributeView}  
+ * + * {@link java.nio.file.attribute.BasicFileAttributeView}Can read or update a basic set of file attributes
- *        - * {@link java.nio.file.attribute.PosixFileAttributeView}  
+ * + * {@link java.nio.file.attribute.PosixFileAttributeView}Can read or update POSIX defined file attributes
- *        - * {@link java.nio.file.attribute.DosFileAttributeView}  
+ * + * {@link java.nio.file.attribute.DosFileAttributeView}Can read or update FAT file attributes
- *      - * {@link java.nio.file.attribute.FileOwnerAttributeView}  
+ * + * {@link java.nio.file.attribute.FileOwnerAttributeView}Can read or update the owner of a file
- *       - * {@link java.nio.file.attribute.AclFileAttributeView}  
+ * + * {@link java.nio.file.attribute.AclFileAttributeView}Can read or update Access Control Lists
- *      - * {@link java.nio.file.attribute.UserDefinedFileAttributeView}  
+ * + * {@link java.nio.file.attribute.UserDefinedFileAttributeView}Can read or update user-defined file attributes
- *   {@link java.nio.file.attribute.FileStoreAttributeView}
+ * {@link java.nio.file.attribute.FileStoreAttributeView}Can read or update file system attributes
+ * + * * *

An attribute view provides a read-only or updatable view of the non-opaque * values, or metadata, associated with objects in a file system. diff --git a/jdk/src/java.base/share/classes/java/nio/package-info.java b/jdk/src/java.base/share/classes/java/nio/package-info.java index 9fa17c945e0..c743a058fc7 100644 --- a/jdk/src/java.base/share/classes/java/nio/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/package-info.java @@ -48,7 +48,7 @@ *

  • Selectors and selection keys, which * together with
    selectable channels define a multiplexed, - * non-blocking
    I/O
     facility.

  • + * non-blocking
    I/O facility.

    * * * @@ -62,33 +62,44 @@ * * * - *
    + *
    * - * - * - * + * + * + * + * + * + * * - * - * - * + * clear, flip, rewind, and mark/reset + * + * + * * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Description of the various buffers
    BuffersDescription
    {@link java.nio.Buffer}
    BuffersDescription
    {@link java.nio.Buffer}Position, limit, and capacity; - *
    clear, flip, rewind, and mark/reset
      {@link java.nio.ByteBuffer}Get/put, compact, views; allocate, wrap
    - *     {@link java.nio.MappedByteBuffer}  
    + * {@link java.nio.ByteBuffer}Get/put, compact, views; allocate, wrap
    + * {@link java.nio.MappedByteBuffer}A byte buffer mapped to a file
      {@link java.nio.CharBuffer}Get/put, compact; allocate, wrap
      {@link java.nio.DoubleBuffer}    ' '
      {@link java.nio.FloatBuffer}    ' '
      {@link java.nio.IntBuffer}    ' '
      {@link java.nio.LongBuffer}    ' '
      {@link java.nio.ShortBuffer}    ' '
    {@link java.nio.ByteOrder}Typesafe enumeration for byte orders
    + * + * {@link java.nio.CharBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.DoubleBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.FloatBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.IntBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.LongBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.ShortBuffer} + * Get/put, compact; allocate, wrap + * {@link java.nio.ByteOrder} + * Typesafe enumeration for byte orders + * + * * *

    A buffer is a container for a fixed amount of data of a * specific primitive type. In addition to its content a buffer has a From c79d52b1030de135b2d7afcba57db6c0f76c854b Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 10 Aug 2017 15:23:03 -0700 Subject: [PATCH 16/42] 8186052: Fix a11y and HTML issues in the java.base/java.lang[.*] packages Reviewed-by: smarks --- .../share/classes/java/lang/Character.java | 17 +++-- .../share/classes/java/lang/Class.java | 26 +++---- .../share/classes/java/lang/Double.java | 26 +++---- .../share/classes/java/lang/Float.java | 24 +++--- .../share/classes/java/lang/String.java | 73 ++++++++++--------- .../share/classes/java/lang/System.java | 42 ++++++----- .../share/classes/java/lang/Thread.java | 6 +- .../java/lang/invoke/LambdaMetafactory.java | 12 +-- .../java/lang/invoke/MethodHandle.java | 6 +- .../java/lang/invoke/MethodHandles.java | 31 ++++---- .../java/lang/invoke/package-info.java | 45 +++++++----- .../java/lang/reflect/AnnotatedElement.java | 40 ++++++---- 12 files changed, 186 insertions(+), 162 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/Character.java b/jdk/src/java.base/share/classes/java/lang/Character.java index fd6682e6196..e2c65b1567f 100644 --- a/jdk/src/java.base/share/classes/java/lang/Character.java +++ b/jdk/src/java.base/share/classes/java/lang/Character.java @@ -9566,18 +9566,23 @@ class Character implements java.io.Serializable, Comparable { * Determines if the specified character is ISO-LATIN-1 white space. * This method returns {@code true} for the following five * characters only: - * + *
    * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * * *
    truechars
    Character + * Code + * Name + *
    {@code '\t'} {@code U+0009}
    {@code '\t'} {@code U+0009}{@code HORIZONTAL TABULATION}
    {@code '\n'} {@code U+000A}
    {@code '\n'} {@code U+000A}{@code NEW LINE}
    {@code '\f'} {@code U+000C}
    {@code '\f'} {@code U+000C}{@code FORM FEED}
    {@code '\r'} {@code U+000D}
    {@code '\r'} {@code U+000D}{@code CARRIAGE RETURN}
    {@code ' '} {@code U+0020}
    {@code ' '} {@code U+0020}{@code SPACE}
    diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java index 81dd846c26a..54415e990f2 100644 --- a/jdk/src/java.base/share/classes/java/lang/Class.java +++ b/jdk/src/java.base/share/classes/java/lang/Class.java @@ -728,22 +728,22 @@ public final class Class implements java.io.Serializable, * one or more '{@code [}' characters representing the depth of the array * nesting. The encoding of element type names is as follows: * - *

    + *
    * * - * - * - * + * *
    Element types and encodings
    Element Type Encoding + *
    Element Type Encoding *
    boolean Z - *
    byte B - *
    char C - *
    class or interface - * Lclassname; - *
    double D - *
    float F - *
    int I - *
    long J - *
    short S + *
    boolean Z + *
    byte B + *
    char C + *
    class or interface + * Lclassname; + *
    double D + *
    float F + *
    int I + *
    long J + *
    short S *
    * diff --git a/jdk/src/java.base/share/classes/java/lang/Double.java b/jdk/src/java.base/share/classes/java/lang/Double.java index a7aa0a0f626..52bf32c8153 100644 --- a/jdk/src/java.base/share/classes/java/lang/Double.java +++ b/jdk/src/java.base/share/classes/java/lang/Double.java @@ -255,25 +255,25 @@ public final class Double extends Number implements Comparable { * * * - * + *
    * * - * + * * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * * - * + * * - * + * * - * + * * * *
    Examples
    Floating-point ValueHexadecimal String
    Floating-point ValueHexadecimal String
    {@code 1.0} {@code 0x1.0p0}
    {@code -1.0} {@code -0x1.0p0}
    {@code 2.0} {@code 0x1.0p1}
    {@code 3.0} {@code 0x1.8p1}
    {@code 0.5} {@code 0x1.0p-1}
    {@code 0.25} {@code 0x1.0p-2}
    {@code Double.MAX_VALUE}
    {@code 1.0} {@code 0x1.0p0}
    {@code -1.0} {@code -0x1.0p0}
    {@code 2.0} {@code 0x1.0p1}
    {@code 3.0} {@code 0x1.8p1}
    {@code 0.5} {@code 0x1.0p-1}
    {@code 0.25} {@code 0x1.0p-2}
    {@code Double.MAX_VALUE}{@code 0x1.fffffffffffffp1023}
    {@code Minimum Normal Value}
    {@code Minimum Normal Value}{@code 0x1.0p-1022}
    {@code Maximum Subnormal Value}
    {@code Maximum Subnormal Value}{@code 0x0.fffffffffffffp-1022}
    {@code Double.MIN_VALUE}
    {@code Double.MIN_VALUE}{@code 0x0.0000000000001p-1022}
    diff --git a/jdk/src/java.base/share/classes/java/lang/Float.java b/jdk/src/java.base/share/classes/java/lang/Float.java index 77c1d1671d5..52cb2c09b79 100644 --- a/jdk/src/java.base/share/classes/java/lang/Float.java +++ b/jdk/src/java.base/share/classes/java/lang/Float.java @@ -256,25 +256,25 @@ public final class Float extends Number implements Comparable { * * * - * + *
    * * - * + * * * - * - * - * - * - * - * - * + * + * + * + * + * + * + * * - * + * * - * + * * - * + * * * *
    Examples
    Floating-point ValueHexadecimal String
    Floating-point ValueHexadecimal String
    {@code 1.0} {@code 0x1.0p0}
    {@code -1.0} {@code -0x1.0p0}
    {@code 2.0} {@code 0x1.0p1}
    {@code 3.0} {@code 0x1.8p1}
    {@code 0.5} {@code 0x1.0p-1}
    {@code 0.25} {@code 0x1.0p-2}
    {@code Float.MAX_VALUE}
    {@code 1.0} {@code 0x1.0p0}
    {@code -1.0} {@code -0x1.0p0}
    {@code 2.0} {@code 0x1.0p1}
    {@code 3.0} {@code 0x1.8p1}
    {@code 0.5} {@code 0x1.0p-1}
    {@code 0.25} {@code 0x1.0p-2}
    {@code Float.MAX_VALUE}{@code 0x1.fffffep127}
    {@code Minimum Normal Value}
    {@code Minimum Normal Value}{@code 0x1.0p-126}
    {@code Maximum Subnormal Value}
    {@code Maximum Subnormal Value}{@code 0x0.fffffep-126}
    {@code Float.MIN_VALUE}
    {@code Float.MIN_VALUE}{@code 0x0.000002p-126}
    diff --git a/jdk/src/java.base/share/classes/java/lang/String.java b/jdk/src/java.base/share/classes/java/lang/String.java index 6d06764c1b4..a41a4200b39 100644 --- a/jdk/src/java.base/share/classes/java/lang/String.java +++ b/jdk/src/java.base/share/classes/java/lang/String.java @@ -2208,29 +2208,29 @@ public final class String * Split example showing regex, limit, and result * * - * Regex - * Limit - * Result + * Regex + * Limit + * Result * * * - * : - * 2 + * : + * 2 * {@code { "boo", "and:foo" }} - * : - * 5 + * + * 5 * {@code { "boo", "and", "foo" }} - * : - * -2 + * + * -2 * {@code { "boo", "and", "foo" }} - * o - * 5 + * o + * 5 * {@code { "b", "", ":and:f", "", "" }} - * o - * -2 + * + * -2 * {@code { "b", "", ":and:f", "", "" }} - * o - * 0 + * + * 0 * {@code { "b", "", ":and:f" }} * * @@ -2336,14 +2336,14 @@ public final class String * Split examples showing regex and result * * - * Regex - * Result + * Regex + * Result * * * - * : + * : * {@code { "boo", "and", "foo" }} - * o + * o * {@code { "b", "", ":and:f" }} * * @@ -2460,36 +2460,37 @@ public final class String * Lowercase mapping examples showing language code of locale, upper case, lower case, and description * * - * Language Code of Locale - * Upper Case - * Lower Case - * Description + * Language Code of Locale + * Upper Case + * Lower Case + * Description * * * * * tr (Turkish) - * \u0130 + * \u0130 * \u0069 * capital letter I with dot above -> small letter i * * * tr (Turkish) - * \u0049 + * \u0049 * \u0131 * capital letter I -> small letter dotless i * * * (all) - * French Fries + * French Fries * french fries * lowercased all chars in String * * * (all) - * capiotacapchi + * + * capiotacapchi * capthetacapupsil - * capsigma + * capsigma * iotachi * thetaupsilon * sigma @@ -2546,34 +2547,34 @@ public final class String * Examples of locale-sensitive and 1:M case mappings. Shows Language code of locale, lower case, upper case, and description. * * - * Language Code of Locale - * Lower Case - * Upper Case - * Description + * Language Code of Locale + * Lower Case + * Upper Case + * Description * * * * * tr (Turkish) - * \u0069 + * \u0069 * \u0130 * small letter i -> capital letter I with dot above * * * tr (Turkish) - * \u0131 + * \u0131 * \u0049 * small letter dotless i -> capital letter I * * * (all) - * \u00df + * \u00df * \u0053 \u0053 * small letter sharp s -> two letters: SS * * * (all) - * Fahrvergnügen + * Fahrvergnügen * FAHRVERGNÜGEN * * diff --git a/jdk/src/java.base/share/classes/java/lang/System.java b/jdk/src/java.base/share/classes/java/lang/System.java index 995b2c4e90f..8388dce7562 100644 --- a/jdk/src/java.base/share/classes/java/lang/System.java +++ b/jdk/src/java.base/share/classes/java/lang/System.java @@ -583,7 +583,7 @@ public final class System { * system properties, a set of system properties is first created and * initialized. This set of system properties always includes values * for the following keys: - * + *
    * * * @@ -1049,26 +1049,28 @@ public final class System { * of corresponding severity. *
    The mapping is as follows: *

    - *
    Shows property keys and associated values
    Key
    + *
    * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * *
    System.Logger Severity Level Mapping
    System.Logger Levels{@link Logger.Level#ALL ALL}{@link Logger.Level#TRACE TRACE}{@link Logger.Level#DEBUG DEBUG}{@link Logger.Level#INFO INFO}{@link Logger.Level#WARNING WARNING}{@link Logger.Level#ERROR ERROR}{@link Logger.Level#OFF OFF}
    java.util.logging Levels{@link java.util.logging.Level#ALL ALL}{@link java.util.logging.Level#FINER FINER}{@link java.util.logging.Level#FINE FINE}{@link java.util.logging.Level#INFO INFO}{@link java.util.logging.Level#WARNING WARNING}{@link java.util.logging.Level#SEVERE SEVERE}{@link java.util.logging.Level#OFF OFF}
    System.Logger Levelsjava.util.logging Levels
    {@link Logger.Level#ALL ALL}{@link java.util.logging.Level#ALL ALL}
    {@link Logger.Level#TRACE TRACE}{@link java.util.logging.Level#FINER FINER}
    {@link Logger.Level#DEBUG DEBUG}{@link java.util.logging.Level#FINE FINE}
    {@link Logger.Level#INFO INFO}{@link java.util.logging.Level#INFO INFO}
    {@link Logger.Level#WARNING WARNING}{@link java.util.logging.Level#WARNING WARNING}
    {@link Logger.Level#ERROR ERROR}{@link java.util.logging.Level#SEVERE SEVERE}
    {@link Logger.Level#OFF OFF}{@link java.util.logging.Level#OFF OFF}
    * * @since 9 diff --git a/jdk/src/java.base/share/classes/java/lang/Thread.java b/jdk/src/java.base/share/classes/java/lang/Thread.java index 8ecc90dd964..5d25df81906 100644 --- a/jdk/src/java.base/share/classes/java/lang/Thread.java +++ b/jdk/src/java.base/share/classes/java/lang/Thread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -347,7 +347,7 @@ class Thread implements Runnable { * the calling thread indicates to the runtime that it is busy-waiting. * The runtime may take action to improve the performance of invoking * spin-wait loop constructions. - *

    + * * @apiNote * As an example consider a method in a class that spins in a loop until * some flag is set outside of that method. A call to the {@code onSpinWait} @@ -373,7 +373,7 @@ class Thread implements Runnable { * method was not called at all. However on some architectures the Java * Virtual Machine may issue the processor instructions to address such * code patterns in a more beneficial way. - *

    + * * @since 9 */ @HotSpotIntrinsicCandidate diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java index 95719763b0f..b9bfd64432c 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java @@ -149,24 +149,24 @@ import java.util.Arrays; * capture argument (corresponding to the receiver) must be non-null. * *

    A type Q is considered adaptable to S as follows: - * + *
    * * - * + * * * * - * + * * * * * - * + * * * * * - * + * * * * - * + * * * diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java index 6e913a84fd9..1c8eb5a1a9e 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -889,7 +889,7 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray *

    * This method behaves very much like {@link #asSpreader(Class, int)}, but accepts an additional {@code spreadArgPos} * argument to indicate at which position in the parameter list the spreading should take place. - *

    + * * @apiNote Example: *

    {@code
         MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class));
    @@ -1094,7 +1094,7 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
          * This method behaves very much like {@link #asCollector(Class, int)}, but differs in that its {@code
          * collectArgPos} argument indicates at which position in the parameter list arguments should be collected. This
          * index is zero-based.
    -     * 

    + * * @apiNote Examples: *

    {@code
         StringWriter swr = new StringWriter();
    diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
    index 45ccb909490..3671ab11833 100644
    --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
    +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
    @@ -3353,7 +3353,7 @@ assert((int)twice.invokeExact(21) == 42);
          * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
          * 

    The returned method handle is equivalent to * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}. - *

    + * * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as * {@code guardWithTest(pred, target, empty(target.type())}. * @param type the type of the desired method handle @@ -3676,7 +3676,7 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z")); * Given these assumptions, the result of an invocation of {@code dropArgumentsToMatch} will have the parameter type * list {@code S..., P..., M..., A...}, with the {@code P} and {@code A} types inserted as if by * {@link #dropArguments(MethodHandle, int, Class[])}. - *

    + * * @apiNote * Two method handles whose argument lists are "effectively identical" (i.e., identical in a common prefix) may be * mutually converted to a common type by two calls to {@code dropArgumentsToMatch}, as follows: @@ -4169,7 +4169,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum")); * position in the parameter list at which folding takes place. The argument controlling this, {@code pos}, is a * zero-based index. The aforementioned method {@link #foldArguments(MethodHandle, MethodHandle)} assumes position * 0. - *

    + * * @apiNote Example: *

    {@code
         import static java.lang.invoke.MethodHandles.*;
    @@ -4698,7 +4698,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * Note that the parameter type lists {@code (V...)} and {@code (A...)} have been expanded
          * to their full length, even though individual clause functions may neglect to take them all.
          * As noted above, missing parameters are filled in as if by {@link #dropArgumentsToMatch}.
    -     * 

    + * * @apiNote Example: *

    {@code
          * // iterative implementation of the factorial function as a loop handle
    @@ -4991,7 +4991,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          *   return v;
          * }
          * }
    - *

    + * * @apiNote Example: *

    {@code
          * // implement the zip function for lists as a loop handle
    @@ -5010,7 +5010,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * assertEquals(zipped, (List) loop.invoke(a.iterator(), b.iterator()));
          * }
    * - *

    + * * @apiNote The implementation of this method can be expressed as follows: *

    {@code
          * MethodHandle whileLoop(MethodHandle init, MethodHandle pred, MethodHandle body) {
    @@ -5104,7 +5104,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          *   return v;
          * }
          * }
    - *

    + * * @apiNote Example: *

    {@code
          * // int i = 0; while (i < limit) { ++i; } return i; => limit
    @@ -5116,7 +5116,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * assertEquals(23, loop.invoke(23));
          * }
    * - *

    + * * @apiNote The implementation of this method can be expressed as follows: *

    {@code
          * MethodHandle doWhileLoop(MethodHandle init, MethodHandle body, MethodHandle pred) {
    @@ -5248,7 +5248,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          *   return v;
          * }
          * }
    - *

    + * * @apiNote Example with a fully conformant body method: *

    {@code
          * // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s;
    @@ -5260,7 +5260,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * MethodHandle loop = MethodHandles.countedLoop(fit13, start, MH_step);
          * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
          * }
    - *

    + * * @apiNote Example with the simplest possible body method type, * and passing the number of iterations to the loop invocation: *

    {@code
    @@ -5273,7 +5273,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * MethodHandle loop = MethodHandles.countedLoop(count, start, MH_step);  // (v, i) -> "na " + v
          * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke(13, "Lambdaman!"));
          * }
    - *

    + * * @apiNote Example that treats the number of iterations, string to append to, and string to append * as loop parameters: *

    {@code
    @@ -5286,7 +5286,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * MethodHandle loop = MethodHandles.countedLoop(count, start, MH_step);  // (v, i, _, pre, _) -> pre + " " + v
          * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke(13, "na", "Lambdaman!"));
          * }
    - *

    + * * @apiNote Example that illustrates the usage of {@link #dropArgumentsToMatch(MethodHandle, int, List, int)} * to enforce a loop type: *

    {@code
    @@ -5301,7 +5301,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * MethodHandle loop = MethodHandles.countedLoop(count, start, body);  // (v, i, pre, _, _) -> pre + " " + v
          * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("na", 13, "Lambdaman!"));
          * }
    - *

    + * * @apiNote The implementation of this method can be expressed as follows: *

    {@code
          * MethodHandle countedLoop(MethodHandle iterations, MethodHandle init, MethodHandle body) {
    @@ -5406,7 +5406,6 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * }
          * }
    * - *

    * @apiNote The implementation of this method can be expressed as follows: *

    {@code
          * MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
    @@ -5607,7 +5606,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          *   return v;
          * }
          * }
    - *

    + * * @apiNote Example: *

    {@code
          * // get an iterator from a list
    @@ -5622,7 +5621,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
          * List reversedList = Arrays.asList("e", "d", "c", "b", "a");
          * assertEquals(reversedList, (List) loop.invoke(list));
          * }
    - *

    + * * @apiNote The implementation of this method can be expressed approximately as follows: *

    {@code
          * MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
    diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java
    index 7e4ce134ec0..e59b5ec9f43 100644
    --- a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java
    +++ b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java
    @@ -165,28 +165,33 @@
      * 

    * Given these rules, here are examples of legal bootstrap method declarations, * given various numbers {@code N} of extra arguments. - * The first rows (marked {@code *}) will work for any number of extra arguments. - *

    adaptable types
    QSLink-time checksInvocation-time checks
    QSLink-time checksInvocation-time checks
    PrimitivePrimitivePrimitivePrimitiveQ can be converted to S via a primitive widening conversionNone
    PrimitiveReferencePrimitiveReferenceS is a supertype of the Wrapper(Q)Cast from Wrapper(Q) to S
    ReferencePrimitiveReferencePrimitivefor parameter types: Q is a primitive wrapper and Primitive(Q) * can be widened to S *
    for return types: If Q is a primitive wrapper, check that @@ -175,7 +175,7 @@ import java.util.Arrays; * for example Number for numeric types
    ReferenceReferenceReferenceReferencefor parameter types: S is a supertype of Q *
    for return types: none
    Cast from Q to S
    + * The first row (marked {@code *}) will work for any number of extra arguments. + *
    * - * - * - * - * - * - * - * - * + * + * + * + * + * + * - * - * - * - * + * + * *
    Static argument types
    NSample bootstrap method
    *CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
    * - * CallSite bootstrap(Object... args)
    * - * CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs)
    0 - * CallSite bootstrap(Lookup caller, String name, MethodType type)
    0 - * CallSite bootstrap(Lookup caller, Object... nameAndType)
    1 + *
    NSample bootstrap method
    * + *
      + *
    • CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args) + *
    • CallSite bootstrap(Object... args) + *
    • CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs) + *
    0 + *
      + *
    • CallSite bootstrap(Lookup caller, String name, MethodType type) + *
    • CallSite bootstrap(Lookup caller, Object... nameAndType) + *
    1 * CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg)
    2 - * CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
    2 - * CallSite bootstrap(Lookup caller, String name, MethodType type, String... args)
    2CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y)
    2 + *
      + *
    • CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args) + *
    • CallSite bootstrap(Lookup caller, String name, MethodType type, String... args) + *
    • CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y) + *
    * The last example assumes that the extra arguments are of type * {@code CONSTANT_String} and {@code CONSTANT_Integer}, respectively. diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java index fd15669931b..c466c82f90c 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java @@ -108,27 +108,39 @@ import sun.reflect.annotation.AnnotationType; * * * - * - * + * + * + * + * + * + * + * + * * * - * + * + * * - * + * + * * - * + * + * * - * + * + * * - * + * + * * - * + * + * * * *
    Overview of kind of presence detected by different AnnotatedElement methods
    Kind of Presence
    MethodDirectly PresentIndirectly PresentPresentAssociated
    MethodKind of Presence
    Return TypeSignatureDirectly PresentIndirectly PresentPresentAssociated
    {@code T}{@link #getAnnotation(Class) getAnnotation(Class<T>)} - * X
    {@code T}{@link #getAnnotation(Class) getAnnotation(Class<T>)} + * X
    {@code Annotation[]}{@link #getAnnotations getAnnotations()} - * X
    {@code Annotation[]}{@link #getAnnotations getAnnotations()} + * X
    {@code T[]}{@link #getAnnotationsByType(Class) getAnnotationsByType(Class<T>)} - * X
    {@code T[]}{@link #getAnnotationsByType(Class) getAnnotationsByType(Class<T>)} + * X
    {@code T}{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class<T>)} - * X
    {@code T}{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class<T>)} + * X
    {@code Annotation[]}{@link #getDeclaredAnnotations getDeclaredAnnotations()} - * X
    {@code Annotation[]}{@link #getDeclaredAnnotations getDeclaredAnnotations()} + * X
    {@code T[]}{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class<T>)} - * XX
    {@code T[]}{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class<T>)} + * XX
    From 1b9cc2f7a257f09e4ed2192a0653e28b6a097d25 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 11 Aug 2017 14:07:14 -0700 Subject: [PATCH 17/42] 8186153: Fix a11y and HTML issues in the java.math, java.text and java.time packages Reviewed-by: lancea, bpb --- .../share/classes/java/math/BigDecimal.java | 18 +- .../share/classes/java/math/RoundingMode.java | 264 +++++++++--------- .../classes/java/text/MessageFormat.java | 126 ++++----- .../java/time/chrono/HijrahChronology.java | 30 +- .../classes/java/time/chrono/IsoEra.java | 16 +- .../classes/java/time/chrono/MinguoEra.java | 18 +- .../java/time/chrono/ThaiBuddhistEra.java | 18 +- .../java/time/format/DateTimeFormatter.java | 100 +++---- .../classes/java/time/temporal/IsoFields.java | 16 +- .../java/time/temporal/WeekFields.java | 24 +- 10 files changed, 315 insertions(+), 315 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/math/BigDecimal.java b/jdk/src/java.base/share/classes/java/math/BigDecimal.java index f4e1f4985d6..cffed200b4e 100644 --- a/jdk/src/java.base/share/classes/java/math/BigDecimal.java +++ b/jdk/src/java.base/share/classes/java/math/BigDecimal.java @@ -120,18 +120,18 @@ import java.util.Arrays; * preferred scale for representing a result. The preferred * scale for each operation is listed in the table below. * - * - * + *
    Preferred Scales for Results of Arithmetic Operations - *
    + * * - * + * * * - * - * - * - * - * + * + * + * + * + * * *
    Preferred Scales for Results of Arithmetic Operations + *
    OperationPreferred Scale of Result
    OperationPreferred Scale of Result
    Addmax(addend.scale(), augend.scale())
    Subtractmax(minuend.scale(), subtrahend.scale())
    Multiplymultiplier.scale() + multiplicand.scale()
    Dividedividend.scale() - divisor.scale()
    Square rootradicand.scale()/2
    Addmax(addend.scale(), augend.scale())
    Subtractmax(minuend.scale(), subtrahend.scale())
    Multiplymultiplier.scale() + multiplicand.scale()
    Dividedividend.scale() - divisor.scale()
    Square rootradicand.scale()/2
    * diff --git a/jdk/src/java.base/share/classes/java/math/RoundingMode.java b/jdk/src/java.base/share/classes/java/math/RoundingMode.java index 79ecce36e7f..b4c37f66ed8 100644 --- a/jdk/src/java.base/share/classes/java/math/RoundingMode.java +++ b/jdk/src/java.base/share/classes/java/math/RoundingMode.java @@ -51,13 +51,13 @@ package java.math; * proper {@code MathContext}. A summary table showing the results * of these rounding operations for all rounding modes appears below. * - * + *
    * * - * * - * + * * * * @@ -66,18 +66,18 @@ package java.math; * * * - * + * * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * * *
    Summary of Rounding Operations Under Different Rounding Modes
    Result of rounding input to one digit with the given + *
    Input NumberResult of rounding input to one digit with the given * rounding mode
    Input Number {@code UP}{@code UP}{@code DOWN}{@code CEILING}{@code FLOOR}{@code HALF_EVEN}{@code UNNECESSARY}
    5.5 6 5 6 5 6 5 6 throw {@code ArithmeticException}
    2.5 3 2 3 2 3 2 2 throw {@code ArithmeticException}
    1.6 2 1 2 1 2 2 2 throw {@code ArithmeticException}
    1.1 2 1 2 1 1 1 1 throw {@code ArithmeticException}
    1.0 1 1 1 1 1 1 1 1
    -1.0 -1 -1 -1 -1 -1 -1 -1 -1
    -1.1 -2 -1 -1 -2 -1 -1 -1 throw {@code ArithmeticException}
    -1.6 -2 -1 -1 -2 -2 -2 -2 throw {@code ArithmeticException}
    -2.5 -3 -2 -2 -3 -3 -2 -2 throw {@code ArithmeticException}
    -5.5 -6 -5 -5 -6 -6 -5 -6 throw {@code ArithmeticException}
    5.5 6 5 6 5 6 5 6 throw {@code ArithmeticException}
    2.5 3 2 3 2 3 2 2 throw {@code ArithmeticException}
    1.6 2 1 2 1 2 2 2 throw {@code ArithmeticException}
    1.1 2 1 2 1 1 1 1 throw {@code ArithmeticException}
    1.0 1 1 1 1 1 1 1 1
    -1.0 -1 -1 -1 -1 -1 -1 -1 -1
    -1.1 -2 -1 -1 -2 -1 -1 -1 throw {@code ArithmeticException}
    -1.6 -2 -1 -1 -2 -2 -2 -2 throw {@code ArithmeticException}
    -2.5 -3 -2 -2 -3 -3 -2 -2 throw {@code ArithmeticException}
    -5.5 -6 -5 -5 -6 -6 -5 -6 throw {@code ArithmeticException}
    * @@ -104,23 +104,23 @@ public enum RoundingMode { * value. * *

    Example: - * - * + *
    Rounding mode UP Examples
    + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
    Rounding mode UP Examples
    Input NumberInput rounded to one digit
    with {@code UP} rounding + *
    Input NumberInput rounded to one digit
    with {@code UP} rounding *
    5.5 6
    2.5 3
    1.6 2
    1.1 2
    1.0 1
    -1.0 -1
    -1.1 -2
    -1.6 -2
    -2.5 -3
    -5.5 -6
    5.5 6
    2.5 3
    1.6 2
    1.1 2
    1.0 1
    -1.0 -1
    -1.1 -2
    -1.6 -2
    -2.5 -3
    -5.5 -6
    */ @@ -132,23 +132,23 @@ public enum RoundingMode { * rounding mode never increases the magnitude of the calculated value. * *

    Example: - * - * + *
    Rounding mode DOWN Examples
    + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
    Rounding mode DOWN Examples
    Input NumberInput rounded to one digit
    with {@code DOWN} rounding + *
    Input NumberInput rounded to one digit
    with {@code DOWN} rounding *
    5.5 5
    2.5 2
    1.6 1
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -1
    -2.5 -2
    -5.5 -5
    5.5 5
    2.5 2
    1.6 1
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -1
    -2.5 -2
    -5.5 -5
    */ @@ -161,23 +161,23 @@ public enum RoundingMode { * that this rounding mode never decreases the calculated value. * *

    Example: - * - * + *
    Rounding mode CEILING Examples
    + * * * * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
    Rounding mode CEILING Examples
    Input NumberInput rounded to one digit
    with {@code CEILING} rounding *
    5.5 6
    2.5 3
    1.6 2
    1.1 2
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -1
    -2.5 -2
    -5.5 -5
    5.5 6
    2.5 3
    1.6 2
    1.1 2
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -1
    -2.5 -2
    -5.5 -5
    */ @@ -190,23 +190,23 @@ public enum RoundingMode { * this rounding mode never increases the calculated value. * *

    Example: - * - * + *
    Rounding mode FLOOR Examples
    + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
    Rounding mode FLOOR Examples
    Input NumberInput rounded to one digit
    with {@code FLOOR} rounding + *
    Input NumberInput rounded to one digit
    with {@code FLOOR} rounding *
    5.5 5
    2.5 2
    1.6 1
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -2
    -1.6 -2
    -2.5 -3
    -5.5 -6
    5.5 5
    2.5 2
    1.6 1
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -2
    -1.6 -2
    -2.5 -3
    -5.5 -6
    */ @@ -221,23 +221,23 @@ public enum RoundingMode { * mode commonly taught at school. * *

    Example: - * - * + *
    Rounding mode HALF_UP Examples
    + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
    Rounding mode HALF_UP Examples
    Input NumberInput rounded to one digit
    with {@code HALF_UP} rounding + *
    Input NumberInput rounded to one digit
    with {@code HALF_UP} rounding *
    5.5 6
    2.5 3
    1.6 2
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -2
    -2.5 -3
    -5.5 -6
    5.5 6
    2.5 3
    1.6 2
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -2
    -2.5 -3
    -5.5 -6
    */ @@ -251,23 +251,23 @@ public enum RoundingMode { * {@code RoundingMode.DOWN}. * *

    Example: - * - * + *
    Rounding mode HALF_DOWN Examples
    + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
    Rounding mode HALF_DOWN Examples
    Input NumberInput rounded to one digit
    with {@code HALF_DOWN} rounding + *
    Input NumberInput rounded to one digit
    with {@code HALF_DOWN} rounding *
    5.5 5
    2.5 2
    1.6 2
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -2
    -2.5 -2
    -5.5 -5
    5.5 5
    2.5 2
    1.6 2
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -2
    -2.5 -2
    -5.5 -5
    */ @@ -288,23 +288,23 @@ public enum RoundingMode { * arithmetic in Java. * *

    Example: - * - * + *
    Rounding mode HALF_EVEN Examples
    + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
    Rounding mode HALF_EVEN Examples
    Input NumberInput rounded to one digit
    with {@code HALF_EVEN} rounding + *
    Input NumberInput rounded to one digit
    with {@code HALF_EVEN} rounding *
    5.5 6
    2.5 2
    1.6 2
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -2
    -2.5 -2
    -5.5 -6
    5.5 6
    2.5 2
    1.6 2
    1.1 1
    1.0 1
    -1.0 -1
    -1.1 -1
    -1.6 -2
    -2.5 -2
    -5.5 -6
    */ @@ -316,23 +316,23 @@ public enum RoundingMode { * specified on an operation that yields an inexact result, an * {@code ArithmeticException} is thrown. *

    Example: - * - * + *
    Rounding mode UNNECESSARY Examples
    + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
    Rounding mode UNNECESSARY Examples
    Input NumberInput rounded to one digit
    with {@code UNNECESSARY} rounding + *
    Input NumberInput rounded to one digit
    with {@code UNNECESSARY} rounding *
    5.5 throw {@code ArithmeticException}
    2.5 throw {@code ArithmeticException}
    1.6 throw {@code ArithmeticException}
    1.1 throw {@code ArithmeticException}
    1.0 1
    -1.0 -1
    -1.1 throw {@code ArithmeticException}
    -1.6 throw {@code ArithmeticException}
    -2.5 throw {@code ArithmeticException}
    -5.5 throw {@code ArithmeticException}
    5.5 throw {@code ArithmeticException}
    2.5 throw {@code ArithmeticException}
    1.6 throw {@code ArithmeticException}
    1.1 throw {@code ArithmeticException}
    1.0 1
    -1.0 -1
    -1.1 throw {@code ArithmeticException}
    -1.6 throw {@code ArithmeticException}
    -2.5 throw {@code ArithmeticException}
    -5.5 throw {@code ArithmeticException}
    */ diff --git a/jdk/src/java.base/share/classes/java/text/MessageFormat.java b/jdk/src/java.base/share/classes/java/text/MessageFormat.java index b80eb054f51..dfed999a5df 100644 --- a/jdk/src/java.base/share/classes/java/text/MessageFormat.java +++ b/jdk/src/java.base/share/classes/java/text/MessageFormat.java @@ -150,73 +150,73 @@ import java.util.Locale; * Shows how FormatType and FormatStyle values map to Format instances * * - * FormatType - * FormatStyle - * Subformat Created + * FormatType + * FormatStyle + * Subformat Created * * * - * (none) - * (none) - * null + * (none) + * (none) + * {@code null} * - * number - * (none) - * {@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())} + * {@code number} + * (none) + * {@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())} * - * integer - * {@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())} + * {@code integer} + * {@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())} * - * currency - * {@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())} + * {@code currency} + * {@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())} * - * percent - * {@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())} + * {@code percent} + * {@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())} * - * SubformatPattern - * {@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))} + * SubformatPattern + * {@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))} * - * date - * (none) - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} + * {@code date} + * (none) + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * - * short - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} + * {@code short} + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} * - * medium - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} + * {@code medium} + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * - * long - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} + * {@code long} + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} * - * full - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} + * {@code full} + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} * - * SubformatPattern - * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} + * SubformatPattern + * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} * - * time - * (none) - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} + * {@code time} + * (none) + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * - * short - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} + * {@code short} + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} * - * medium - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} + * {@code medium} + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * - * long - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} + * {@code long} + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} * - * full - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} + * {@code full} + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} * - * SubformatPattern - * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} + * SubformatPattern + * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} * - * choice - * SubformatPattern - * {@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)} + * {@code choice} + * SubformatPattern + * {@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)} * * * @@ -776,44 +776,40 @@ public class MessageFormat extends Format { * Examples of subformat,argument,and formatted text * * - * Subformat - * Argument - * Formatted Text + * Subformat + * Argument + * Formatted Text * * * - * any - * unavailable + * any + * unavailable * "{" + argumentIndex + "}" * - * any - * null + * null * "null" * - * instanceof ChoiceFormat - * any + * instanceof ChoiceFormat + * any * subformat.format(argument).indexOf('{') >= 0 ?
    * (new MessageFormat(subformat.format(argument), getLocale())).format(argument) : * subformat.format(argument)
    * - * != null - * any + * != null + * any * subformat.format(argument) * - * null - * instanceof Number + * null + * instanceof Number * NumberFormat.getInstance(getLocale()).format(argument) * - * null - * instanceof Date + * instanceof Date * DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getLocale()).format(argument) * - * null - * instanceof String + * instanceof String * argument * - * null - * any + * any * argument.toString() * * diff --git a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java index 0ec1b591bc2..bc702a44d07 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java @@ -103,19 +103,19 @@ import sun.util.logging.PlatformLogger; * *

    * CLDR and LDML identify variants: - * + *
    * * * - * - * - * - * + * + * + * + * * * * * - * + * * * * @@ -148,38 +148,38 @@ import sun.util.logging.PlatformLogger; *

    * The Hijrah property resource is a set of properties that describe the calendar. * The syntax is defined by {@code java.util.Properties#load(Reader)}. - *

    Variants of Hijrah Calendars
    Chronology IDCalendar TypeLocale extension, see {@link java.util.Locale}DescriptionChronology IDCalendar TypeLocale extension, see {@link java.util.Locale}Description
    Hijrah-umalquraHijrah-umalquraislamic-umalquraca-islamic-umalquraIslamic - Umm Al-Qura calendar of Saudi Arabia
    + *
    * * * - * - * - * + * + * + * * * * * - * + * * * * * - * + * * * * * - * + * * * * * - * + * * * * * - * + * * * "); + file.flush(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassVector.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java similarity index 54% rename from jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassVector.java rename to jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java index f95ef244dce..7a2b98bf98e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassVector.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java @@ -21,26 +21,29 @@ package com.sun.org.apache.bcel.internal.util; -import java.util.ArrayList; -import com.sun.org.apache.bcel.internal.classfile.JavaClass; - /** - * Utility class implementing a (typesafe) collection of JavaClass - * objects. Contains the most important methods of a Vector. + * Used for BCEL comparison strategy * - * @author M. Dahm - * @see ClassQueue -*/ -public class ClassVector implements java.io.Serializable { - protected ArrayList vec = new ArrayList(); + * @version $Id: BCELComparator.java 1747278 2016-06-07 17:28:43Z britter $ + * @since 5.2 + */ +public interface BCELComparator { - public void addElement(JavaClass clazz) { vec.add(clazz); } - public JavaClass elementAt(int index) { return (JavaClass)vec.get(index); } - public void removeElementAt(int index) { vec.remove(index); } + /** + * Compare two objects and return what THIS.equals(THAT) should return + * + * @param THIS + * @param THAT + * @return true if and only if THIS equals THAT + */ + boolean equals( Object THIS, Object THAT ); - public JavaClass[] toArray() { - JavaClass[] classes = new JavaClass[vec.size()]; - vec.toArray(classes); - return classes; - } + + /** + * Return hashcode for THIS.hashCode() + * + * @param THIS + * @return hashcode for THIS.hashCode() + */ + int hashCode( Object THIS ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java index 084fc7bbd7f..929d2832a34 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java @@ -21,304 +21,331 @@ package com.sun.org.apache.bcel.internal.util; -import com.sun.org.apache.bcel.internal.generic.*; -import com.sun.org.apache.bcel.internal.classfile.Utility; -import com.sun.org.apache.bcel.internal.Constants; import java.io.PrintWriter; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Utility; +import com.sun.org.apache.bcel.internal.generic.AllocationInstruction; +import com.sun.org.apache.bcel.internal.generic.ArrayInstruction; +import com.sun.org.apache.bcel.internal.generic.ArrayType; +import com.sun.org.apache.bcel.internal.generic.BranchHandle; +import com.sun.org.apache.bcel.internal.generic.BranchInstruction; +import com.sun.org.apache.bcel.internal.generic.CHECKCAST; +import com.sun.org.apache.bcel.internal.generic.CPInstruction; +import com.sun.org.apache.bcel.internal.generic.CodeExceptionGen; +import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import com.sun.org.apache.bcel.internal.generic.ConstantPushInstruction; +import com.sun.org.apache.bcel.internal.generic.EmptyVisitor; +import com.sun.org.apache.bcel.internal.generic.FieldInstruction; +import com.sun.org.apache.bcel.internal.generic.IINC; +import com.sun.org.apache.bcel.internal.generic.INSTANCEOF; +import com.sun.org.apache.bcel.internal.generic.Instruction; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; +import com.sun.org.apache.bcel.internal.generic.InstructionHandle; +import com.sun.org.apache.bcel.internal.generic.InvokeInstruction; +import com.sun.org.apache.bcel.internal.generic.LDC; +import com.sun.org.apache.bcel.internal.generic.LDC2_W; +import com.sun.org.apache.bcel.internal.generic.LocalVariableInstruction; +import com.sun.org.apache.bcel.internal.generic.MULTIANEWARRAY; +import com.sun.org.apache.bcel.internal.generic.MethodGen; +import com.sun.org.apache.bcel.internal.generic.NEWARRAY; +import com.sun.org.apache.bcel.internal.generic.ObjectType; +import com.sun.org.apache.bcel.internal.generic.RET; +import com.sun.org.apache.bcel.internal.generic.ReturnInstruction; +import com.sun.org.apache.bcel.internal.generic.Select; +import com.sun.org.apache.bcel.internal.generic.Type; /** * Factory creates il.append() statements, and sets instruction targets. * A helper class for BCELifier. * * @see BCELifier - * @author M. Dahm + * @version $Id: BCELFactory.java 1749603 2016-06-21 20:50:19Z ggregory $ */ class BCELFactory extends EmptyVisitor { - private MethodGen _mg; - private PrintWriter _out; - private ConstantPoolGen _cp; - BCELFactory(MethodGen mg, PrintWriter out) { - _mg = mg; - _cp = mg.getConstantPool(); - _out = out; - } + private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+"."; + private final MethodGen _mg; + private final PrintWriter _out; + private final ConstantPoolGen _cp; - private HashMap branch_map = new HashMap(); // Map - public void start() { - if(!_mg.isAbstract() && !_mg.isNative()) { - for(InstructionHandle ih = _mg.getInstructionList().getStart(); - ih != null; ih = ih.getNext()) { - Instruction i = ih.getInstruction(); + BCELFactory(final MethodGen mg, final PrintWriter out) { + _mg = mg; + _cp = mg.getConstantPool(); + _out = out; + } - if(i instanceof BranchInstruction) { - branch_map.put(i, ih); // memorize container + private final Map branch_map = new HashMap<>(); + + + public void start() { + if (!_mg.isAbstract() && !_mg.isNative()) { + for (InstructionHandle ih = _mg.getInstructionList().getStart(); ih != null; ih = ih + .getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { + branch_map.put(i, ih); // memorize container + } + if (ih.hasTargeters()) { + if (i instanceof BranchInstruction) { + _out.println(" InstructionHandle ih_" + ih.getPosition() + ";"); + } else { + _out.print(" InstructionHandle ih_" + ih.getPosition() + " = "); + } + } else { + _out.print(" "); + } + if (!visitInstruction(i)) { + i.accept(this); + } + } + updateBranchTargets(); + updateExceptionHandlers(); } + } - if(ih.hasTargeters()) { - if(i instanceof BranchInstruction) { - _out.println(" InstructionHandle ih_" + ih.getPosition() + ";"); - } else { - _out.print(" InstructionHandle ih_" + ih.getPosition() + " = "); - } + + private boolean visitInstruction( final Instruction i ) { + final short opcode = i.getOpcode(); + if ((InstructionConst.getInstruction(opcode) != null) + && !(i instanceof ConstantPushInstruction) && !(i instanceof ReturnInstruction)) { // Handled below + _out.println("il.append(InstructionConst." + + i.getName().toUpperCase(Locale.ENGLISH) + ");"); + return true; + } + return false; + } + + + @Override + public void visitLocalVariableInstruction( final LocalVariableInstruction i ) { + final short opcode = i.getOpcode(); + final Type type = i.getType(_cp); + if (opcode == Const.IINC) { + _out.println("il.append(new IINC(" + i.getIndex() + ", " + ((IINC) i).getIncrement() + + "));"); } else { - _out.print(" "); + final String kind = (opcode < Const.ISTORE) ? "Load" : "Store"; + _out.println("il.append(_factory.create" + kind + "(" + BCELifier.printType(type) + + ", " + i.getIndex() + "));"); + } + } + + + @Override + public void visitArrayInstruction( final ArrayInstruction i ) { + final short opcode = i.getOpcode(); + final Type type = i.getType(_cp); + final String kind = (opcode < Const.IASTORE) ? "Load" : "Store"; + _out.println("il.append(_factory.createArray" + kind + "(" + BCELifier.printType(type) + + "));"); + } + + + @Override + public void visitFieldInstruction( final FieldInstruction i ) { + final short opcode = i.getOpcode(); + final String class_name = i.getReferenceType(_cp).getSignature(); + final String field_name = i.getFieldName(_cp); + final Type type = i.getFieldType(_cp); + _out.println("il.append(_factory.createFieldAccess(\"" + class_name + "\", \"" + field_name + + "\", " + BCELifier.printType(type) + ", " + CONSTANT_PREFIX + + Const.getOpcodeName(opcode).toUpperCase(Locale.ENGLISH) + "));"); + } + + + @Override + public void visitInvokeInstruction( final InvokeInstruction i ) { + final short opcode = i.getOpcode(); + final String class_name = i.getReferenceType(_cp).getSignature(); + final String method_name = i.getMethodName(_cp); + final Type type = i.getReturnType(_cp); + final Type[] arg_types = i.getArgumentTypes(_cp); + _out.println("il.append(_factory.createInvoke(\"" + class_name + "\", \"" + method_name + + "\", " + BCELifier.printType(type) + ", " + + BCELifier.printArgumentTypes(arg_types) + ", " + CONSTANT_PREFIX + + Const.getOpcodeName(opcode).toUpperCase(Locale.ENGLISH) + "));"); + } + + + @Override + public void visitAllocationInstruction( final AllocationInstruction i ) { + Type type; + if (i instanceof CPInstruction) { + type = ((CPInstruction) i).getType(_cp); + } else { + type = ((NEWARRAY) i).getType(); + } + final short opcode = ((Instruction) i).getOpcode(); + int dim = 1; + switch (opcode) { + case Const.NEW: + _out.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName() + + "\"));"); + break; + case Const.MULTIANEWARRAY: + dim = ((MULTIANEWARRAY) i).getDimensions(); + //$FALL-THROUGH$ + case Const.ANEWARRAY: + case Const.NEWARRAY: + if (type instanceof ArrayType) { + type = ((ArrayType) type).getBasicType(); + } + _out.println("il.append(_factory.createNewArray(" + BCELifier.printType(type) + + ", (short) " + dim + "));"); + break; + default: + throw new RuntimeException("Oops: " + opcode); + } + } + + + private void createConstant( final Object value ) { + String embed = value.toString(); + if (value instanceof String) { + embed = '"' + Utility.convertString(embed) + '"'; + } else if (value instanceof Character) { + embed = "(char)0x" + Integer.toHexString(((Character) value).charValue()); + } else if (value instanceof Float) { + embed += "f"; + } else if (value instanceof Long) { + embed += "L"; + } else if (value instanceof ObjectType) { + final ObjectType ot = (ObjectType) value; + embed = "new ObjectType(\""+ot.getClassName()+"\")"; } - if(!visitInstruction(i)) - i.accept(this); - } - - updateBranchTargets(); - updateExceptionHandlers(); - } - } - - private boolean visitInstruction(Instruction i) { - short opcode = i.getOpcode(); - - if((InstructionConstants.INSTRUCTIONS[opcode] != null) && - !(i instanceof ConstantPushInstruction) && - !(i instanceof ReturnInstruction)) { // Handled below - _out.println("il.append(InstructionConstants." + - i.getName().toUpperCase() + ");"); - return true; + _out.println("il.append(new PUSH(_cp, " + embed + "));"); } - return false; - } - public void visitLocalVariableInstruction(LocalVariableInstruction i) { - short opcode = i.getOpcode(); - Type type = i.getType(_cp); - - if(opcode == Constants.IINC) { - _out.println("il.append(new IINC(" + i.getIndex() + ", " + - ((IINC)i).getIncrement() + "));"); - } else { - String kind = (opcode < Constants.ISTORE)? "Load" : "Store"; - _out.println("il.append(_factory.create" + kind + "(" + - BCELifier.printType(type) + ", " + - i.getIndex() + "));"); - } - } - - public void visitArrayInstruction(ArrayInstruction i) { - short opcode = i.getOpcode(); - Type type = i.getType(_cp); - String kind = (opcode < Constants.IASTORE)? "Load" : "Store"; - - _out.println("il.append(_factory.createArray" + kind + "(" + - BCELifier.printType(type) + "));"); - } - - public void visitFieldInstruction(FieldInstruction i) { - short opcode = i.getOpcode(); - - String class_name = i.getClassName(_cp); - String field_name = i.getFieldName(_cp); - Type type = i.getFieldType(_cp); - - _out.println("il.append(_factory.createFieldAccess(\"" + - class_name + "\", \"" + field_name + "\", " + - BCELifier.printType(type) + ", " + - "Constants." + Constants.OPCODE_NAMES[opcode].toUpperCase() + - "));"); - } - - public void visitInvokeInstruction(InvokeInstruction i) { - short opcode = i.getOpcode(); - String class_name = i.getClassName(_cp); - String method_name = i.getMethodName(_cp); - Type type = i.getReturnType(_cp); - Type[] arg_types = i.getArgumentTypes(_cp); - - _out.println("il.append(_factory.createInvoke(\"" + - class_name + "\", \"" + method_name + "\", " + - BCELifier.printType(type) + ", " + - BCELifier.printArgumentTypes(arg_types) + ", " + - "Constants." + Constants.OPCODE_NAMES[opcode].toUpperCase() + - "));"); - } - - public void visitAllocationInstruction(AllocationInstruction i) { - Type type; - - if(i instanceof CPInstruction) { - type = ((CPInstruction)i).getType(_cp); - } else { - type = ((NEWARRAY)i).getType(); + @Override + public void visitLDC( final LDC i ) { + createConstant(i.getValue(_cp)); } - short opcode = ((Instruction)i).getOpcode(); - int dim = 1; - switch(opcode) { - case Constants.NEW: - _out.println("il.append(_factory.createNew(\"" + - ((ObjectType)type).getClassName() + "\"));"); - break; - - case Constants.MULTIANEWARRAY: - dim = ((MULTIANEWARRAY)i).getDimensions(); - - case Constants.ANEWARRAY: - case Constants.NEWARRAY: - _out.println("il.append(_factory.createNewArray(" + - BCELifier.printType(type) + ", (short) " + dim + "));"); - break; - - default: - throw new RuntimeException("Oops: " + opcode); - } - } - - private void createConstant(Object value) { - String embed = value.toString(); - - if(value instanceof String) - embed = '"' + Utility.convertString(value.toString()) + '"'; - else if(value instanceof Character) - embed = "(char)0x" + Integer.toHexString(((Character)value).charValue()); - - _out.println("il.append(new PUSH(_cp, " + embed + "));"); - } - - public void visitLDC(LDC i) { - createConstant(i.getValue(_cp)); - } - - public void visitLDC2_W(LDC2_W i) { - createConstant(i.getValue(_cp)); - } - - public void visitConstantPushInstruction(ConstantPushInstruction i) { - createConstant(i.getValue()); - } - - public void visitINSTANCEOF(INSTANCEOF i) { - Type type = i.getType(_cp); - - _out.println("il.append(new INSTANCEOF(_cp.addClass(" + - BCELifier.printType(type) + ")));"); - } - - public void visitCHECKCAST(CHECKCAST i) { - Type type = i.getType(_cp); - - _out.println("il.append(_factory.createCheckCast(" + - BCELifier.printType(type) + "));"); - } - - public void visitReturnInstruction(ReturnInstruction i) { - Type type = i.getType(_cp); - - _out.println("il.append(_factory.createReturn(" + - BCELifier.printType(type) + "));"); - } - - // Memorize BranchInstructions that need an update - private ArrayList branches = new ArrayList(); - - public void visitBranchInstruction(BranchInstruction bi) { - BranchHandle bh = (BranchHandle)branch_map.get(bi); - int pos = bh.getPosition(); - String name = bi.getName() + "_" + pos; - - if(bi instanceof Select) { - Select s = (Select)bi; - branches.add(bi); - - StringBuffer args = new StringBuffer("new int[] { "); - int[] matchs = s.getMatchs(); - - for(int i=0; i < matchs.length; i++) { - args.append(matchs[i]); - - if(i < matchs.length - 1) - args.append(", "); - } - - args.append(" }"); - - _out.print(" Select " + name + " = new " + - bi.getName().toUpperCase() + "(" + args + - ", new InstructionHandle[] { "); - - for(int i=0; i < matchs.length; i++) { - _out.print("null"); - - if(i < matchs.length - 1) - _out.print(", "); - } - - _out.println(");"); - } else { - int t_pos = bh.getTarget().getPosition(); - String target; - - if(pos > t_pos) { - target = "ih_" + t_pos; - } else { - branches.add(bi); - target = "null"; - } - - _out.println(" BranchInstruction " + name + - " = _factory.createBranchInstruction(" + - "Constants." + bi.getName().toUpperCase() + ", " + - target + ");"); + @Override + public void visitLDC2_W( final LDC2_W i ) { + createConstant(i.getValue(_cp)); } - if(bh.hasTargeters()) - _out.println(" ih_" + pos + " = il.append(" + name + ");"); - else - _out.println(" il.append(" + name + ");"); - } - public void visitRET(RET i) { - _out.println("il.append(new RET(" + i.getIndex() + ")));"); - } + @Override + public void visitConstantPushInstruction( final ConstantPushInstruction i ) { + createConstant(i.getValue()); + } - private void updateBranchTargets() { - for(Iterator i = branches.iterator(); i.hasNext(); ) { - BranchInstruction bi = (BranchInstruction)i.next(); - BranchHandle bh = (BranchHandle)branch_map.get(bi); - int pos = bh.getPosition(); - String name = bi.getName() + "_" + pos; - int t_pos = bh.getTarget().getPosition(); - _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); + @Override + public void visitINSTANCEOF( final INSTANCEOF i ) { + final Type type = i.getType(_cp); + _out.println("il.append(new INSTANCEOF(_cp.addClass(" + BCELifier.printType(type) + ")));"); + } - if(bi instanceof Select) { - InstructionHandle[] ihs = ((Select)bi).getTargets(); - for(int j = 0; j < ihs.length; j++) { - t_pos = ihs[j].getPosition(); + @Override + public void visitCHECKCAST( final CHECKCAST i ) { + final Type type = i.getType(_cp); + _out.println("il.append(_factory.createCheckCast(" + BCELifier.printType(type) + "));"); + } - _out.println(" " + name + ".setTarget(" + j + - ", ih_" + t_pos + ");"); + + @Override + public void visitReturnInstruction( final ReturnInstruction i ) { + final Type type = i.getType(_cp); + _out.println("il.append(_factory.createReturn(" + BCELifier.printType(type) + "));"); + } + + // Memorize BranchInstructions that need an update + private final List branches = new ArrayList<>(); + + + @Override + public void visitBranchInstruction( final BranchInstruction bi ) { + final BranchHandle bh = (BranchHandle) branch_map.get(bi); + final int pos = bh.getPosition(); + final String name = bi.getName() + "_" + pos; + if (bi instanceof Select) { + final Select s = (Select) bi; + branches.add(bi); + final StringBuilder args = new StringBuilder("new int[] { "); + final int[] matchs = s.getMatchs(); + for (int i = 0; i < matchs.length; i++) { + args.append(matchs[i]); + if (i < matchs.length - 1) { + args.append(", "); + } + } + args.append(" }"); + _out.print("Select " + name + " = new " + bi.getName().toUpperCase(Locale.ENGLISH) + + "(" + args + ", new InstructionHandle[] { "); + for (int i = 0; i < matchs.length; i++) { + _out.print("null"); + if (i < matchs.length - 1) { + _out.print(", "); + } + } + _out.println(" }, null);"); + } else { + final int t_pos = bh.getTarget().getPosition(); + String target; + if (pos > t_pos) { + target = "ih_" + t_pos; + } else { + branches.add(bi); + target = "null"; + } + _out.println(" BranchInstruction " + name + " = _factory.createBranchInstruction(" + + CONSTANT_PREFIX + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target + + ");"); + } + if (bh.hasTargeters()) { + _out.println(" ih_" + pos + " = il.append(" + name + ");"); + } else { + _out.println(" il.append(" + name + ");"); } - } } - } - private void updateExceptionHandlers() { - CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); - for(int i=0; i < handlers.length; i++) { - CodeExceptionGen h = handlers[i]; - String type = (h.getCatchType() == null)? - "null" : BCELifier.printType(h.getCatchType()); - - _out.println(" method.addExceptionHandler(" + - "ih_" + h.getStartPC().getPosition() + ", " + - "ih_" + h.getEndPC().getPosition() + ", " + - "ih_" + h.getHandlerPC().getPosition() + ", " + - type + ");"); + @Override + public void visitRET( final RET i ) { + _out.println("il.append(new RET(" + i.getIndex() + ")));"); + } + + + private void updateBranchTargets() { + for (final BranchInstruction bi : branches) { + final BranchHandle bh = (BranchHandle) branch_map.get(bi); + final int pos = bh.getPosition(); + final String name = bi.getName() + "_" + pos; + int t_pos = bh.getTarget().getPosition(); + _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); + if (bi instanceof Select) { + final InstructionHandle[] ihs = ((Select) bi).getTargets(); + for (int j = 0; j < ihs.length; j++) { + t_pos = ihs[j].getPosition(); + _out.println(" " + name + ".setTarget(" + j + ", ih_" + t_pos + ");"); + } + } + } + } + + + private void updateExceptionHandlers() { + final CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); + for (final CodeExceptionGen h : handlers) { + final String type = (h.getCatchType() == null) ? "null" : BCELifier.printType(h + .getCatchType()); + _out.println(" method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition() + + ", " + "ih_" + h.getEndPC().getPosition() + ", " + "ih_" + + h.getHandlerPC().getPosition() + ", " + type + ");"); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java index de157f0d345..4092e59b263 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java @@ -21,11 +21,23 @@ package com.sun.org.apache.bcel.internal.util; -import com.sun.org.apache.bcel.internal.classfile.*; -import com.sun.org.apache.bcel.internal.generic.*; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Locale; + +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.Repository; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.classfile.ClassParser; +import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; +import com.sun.org.apache.bcel.internal.generic.ArrayType; +import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import com.sun.org.apache.bcel.internal.generic.MethodGen; +import com.sun.org.apache.bcel.internal.generic.Type; /** * This class takes a given JavaClass object and converts it to a @@ -34,238 +46,262 @@ import java.io.*; * are done with BCEL. It does not cover all features of BCEL, * but tries to mimic hand-written code as close as possible. * - * @author M. Dahm + * @version $Id: BCELifier.java 1750228 2016-06-25 21:47:44Z ggregory $ */ public class BCELifier extends com.sun.org.apache.bcel.internal.classfile.EmptyVisitor { - private JavaClass _clazz; - private PrintWriter _out; - private ConstantPoolGen _cp; - /** @param clazz Java class to "decompile" - * @param out where to output Java program - */ - public BCELifier(JavaClass clazz, OutputStream out) { - _clazz = clazz; - _out = new PrintWriter(out); - _cp = new ConstantPoolGen(_clazz.getConstantPool()); - } - - /** Start Java code generation - */ - public void start() { - visitJavaClass(_clazz); - _out.flush(); - } - - public void visitJavaClass(JavaClass clazz) { - String class_name = clazz.getClassName(); - String super_name = clazz.getSuperclassName(); - String package_name = clazz.getPackageName(); - String inter = Utility.printArray(clazz.getInterfaceNames(), - false, true); - if(!"".equals(package_name)) { - class_name = class_name.substring(package_name.length() + 1); - _out.println("package " + package_name + ";\n"); - } - - _out.println("import com.sun.org.apache.bcel.internal.generic.*;"); - _out.println("import com.sun.org.apache.bcel.internal.classfile.*;"); - _out.println("import com.sun.org.apache.bcel.internal.*;"); - _out.println("import java.io.*;\n"); - - _out.println("public class " + class_name + "Creator implements Constants {"); - _out.println(" private InstructionFactory _factory;"); - _out.println(" private ConstantPoolGen _cp;"); - _out.println(" private ClassGen _cg;\n"); - - _out.println(" public " + class_name + "Creator() {"); - _out.println(" _cg = new ClassGen(\"" + - (("".equals(package_name))? class_name : - package_name + "." + class_name) + - "\", \"" + super_name + "\", " + - "\"" + clazz.getSourceFileName() + "\", " + - printFlags(clazz.getAccessFlags(), true) + ", " + - "new String[] { " + inter + " });\n"); - - _out.println(" _cp = _cg.getConstantPool();"); - _out.println(" _factory = new InstructionFactory(_cg, _cp);"); - _out.println(" }\n"); - - printCreate(); - - Field[] fields = clazz.getFields(); - - if(fields.length > 0) { - _out.println(" private void createFields() {"); - _out.println(" FieldGen field;"); - - for(int i=0; i < fields.length; i++) { - fields[i].accept(this); - } - - _out.println(" }\n"); + /** + * Enum corresponding to flag source. + */ + public enum FLAGS { + UNKNOWN, + CLASS, + METHOD, } - Method[] methods = clazz.getMethods(); + // The base package name for imports; assumes Const is at the top level + // N.B we use the class so renames will be detected by the compiler/IDE + private static final String BASE_PACKAGE = Const.class.getPackage().getName(); + private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+"."; - for(int i=0; i < methods.length; i++) { - _out.println(" private void createMethod_" + i + "() {"); + private final JavaClass _clazz; + private final PrintWriter _out; + private final ConstantPoolGen _cp; - methods[i].accept(this); - _out.println(" }\n"); + /** @param clazz Java class to "decompile" + * @param out where to output Java program + */ + public BCELifier(final JavaClass clazz, final OutputStream out) { + _clazz = clazz; + _out = new PrintWriter(out); + _cp = new ConstantPoolGen(_clazz.getConstantPool()); } - printMain(); - _out.println("}"); - } - private void printCreate() { - _out.println(" public void create(OutputStream out) throws IOException {"); - - Field[] fields = _clazz.getFields(); - if(fields.length > 0) { - _out.println(" createFields();"); + /** Start Java code generation + */ + public void start() { + visitJavaClass(_clazz); + _out.flush(); } - Method[] methods = _clazz.getMethods(); - for(int i=0; i < methods.length; i++) { - _out.println(" createMethod_" + i + "();"); + + @Override + public void visitJavaClass( final JavaClass clazz ) { + String class_name = clazz.getClassName(); + final String super_name = clazz.getSuperclassName(); + final String package_name = clazz.getPackageName(); + final String inter = Utility.printArray(clazz.getInterfaceNames(), false, true); + if (!"".equals(package_name)) { + class_name = class_name.substring(package_name.length() + 1); + _out.println("package " + package_name + ";"); + _out.println(); + } + _out.println("import " + BASE_PACKAGE + ".generic.*;"); + _out.println("import " + BASE_PACKAGE + ".classfile.*;"); + _out.println("import " + BASE_PACKAGE + ".*;"); + _out.println("import java.io.*;"); + _out.println(); + _out.println("public class " + class_name + "Creator {"); + _out.println(" private InstructionFactory _factory;"); + _out.println(" private ConstantPoolGen _cp;"); + _out.println(" private ClassGen _cg;"); + _out.println(); + _out.println(" public " + class_name + "Creator() {"); + _out.println(" _cg = new ClassGen(\"" + + (("".equals(package_name)) ? class_name : package_name + "." + class_name) + + "\", \"" + super_name + "\", " + "\"" + clazz.getSourceFileName() + "\", " + + printFlags(clazz.getAccessFlags(), FLAGS.CLASS) + ", " + + "new String[] { " + inter + " });"); + _out.println(); + _out.println(" _cp = _cg.getConstantPool();"); + _out.println(" _factory = new InstructionFactory(_cg, _cp);"); + _out.println(" }"); + _out.println(); + printCreate(); + final Field[] fields = clazz.getFields(); + if (fields.length > 0) { + _out.println(" private void createFields() {"); + _out.println(" FieldGen field;"); + for (final Field field : fields) { + field.accept(this); + } + _out.println(" }"); + _out.println(); + } + final Method[] methods = clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + _out.println(" private void createMethod_" + i + "() {"); + methods[i].accept(this); + _out.println(" }"); + _out.println(); + } + printMain(); + _out.println("}"); } - _out.println(" _cg.getJavaClass().dump(out);"); - _out.println(" }\n"); - } - - private void printMain() { - String class_name = _clazz.getClassName(); - - _out.println(" public static void _main(String[] args) throws Exception {"); - _out.println(" " + class_name + "Creator creator = new " + - class_name + "Creator();"); - _out.println(" creator.create(new FileOutputStream(\"" + class_name + - ".class\"));"); - _out.println(" }"); - } - - public void visitField(Field field) { - _out.println("\n field = new FieldGen(" + - printFlags(field.getAccessFlags()) + - ", " + printType(field.getSignature()) + ", \"" + - field.getName() + "\", _cp);"); - - ConstantValue cv = field.getConstantValue(); - - if(cv != null) { - String value = cv.toString(); - _out.println(" field.setInitValue(" + value + ")"); + private void printCreate() { + _out.println(" public void create(OutputStream out) throws IOException {"); + final Field[] fields = _clazz.getFields(); + if (fields.length > 0) { + _out.println(" createFields();"); + } + final Method[] methods = _clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + _out.println(" createMethod_" + i + "();"); + } + _out.println(" _cg.getJavaClass().dump(out);"); + _out.println(" }"); + _out.println(); } - _out.println(" _cg.addField(field.getField());"); - } - public void visitMethod(Method method) { - MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); - - Type result_type = mg.getReturnType(); - Type[] arg_types = mg.getArgumentTypes(); - - _out.println(" InstructionList il = new InstructionList();"); - _out.println(" MethodGen method = new MethodGen(" + - printFlags(method.getAccessFlags()) + - ", " + printType(result_type) + - ", " + printArgumentTypes(arg_types) + ", " + - "new String[] { " + - Utility.printArray(mg.getArgumentNames(), false, true) + - " }, \"" + method.getName() + "\", \"" + - _clazz.getClassName() + "\", il, _cp);\n"); - - BCELFactory factory = new BCELFactory(mg, _out); - factory.start(); - - _out.println(" method.setMaxStack();"); - _out.println(" method.setMaxLocals();"); - _out.println(" _cg.addMethod(method.getMethod());"); - _out.println(" il.dispose();"); - } - - static String printFlags(int flags) { - return printFlags(flags, false); - } - - static String printFlags(int flags, boolean for_class) { - if(flags == 0) - return "0"; - - StringBuffer buf = new StringBuffer(); - for(int i=0, pow=1; i <= Constants.MAX_ACC_FLAG; i++) { - if((flags & pow) != 0) { - if((pow == Constants.ACC_SYNCHRONIZED) && for_class) - buf.append("ACC_SUPER | "); - else - buf.append("ACC_" + Constants.ACCESS_NAMES[i].toUpperCase() + " | "); - } - - pow <<= 1; + private void printMain() { + final String class_name = _clazz.getClassName(); + _out.println(" public static void main(String[] args) throws Exception {"); + _out.println(" " + class_name + "Creator creator = new " + class_name + "Creator();"); + _out.println(" creator.create(new FileOutputStream(\"" + class_name + ".class\"));"); + _out.println(" }"); } - String str = buf.toString(); - return str.substring(0, str.length() - 3); - } - static String printArgumentTypes(Type[] arg_types) { - if(arg_types.length == 0) - return "Type.NO_ARGS"; - - StringBuffer args = new StringBuffer(); - - for(int i=0; i < arg_types.length; i++) { - args.append(printType(arg_types[i])); - - if(i < arg_types.length - 1) - args.append(", "); + @Override + public void visitField( final Field field ) { + _out.println(); + _out.println(" field = new FieldGen(" + printFlags(field.getAccessFlags()) + ", " + + printType(field.getSignature()) + ", \"" + field.getName() + "\", _cp);"); + final ConstantValue cv = field.getConstantValue(); + if (cv != null) { + final String value = cv.toString(); + _out.println(" field.setInitValue(" + value + ")"); + } + _out.println(" _cg.addField(field.getField());"); } - return "new Type[] { " + args.toString() + " }"; - } - static String printType(Type type) { - return printType(type.getSignature()); - } - - static String printType(String signature) { - Type type = Type.getType(signature); - byte t = type.getType(); - - if(t <= Constants.T_VOID) { - return "Type." + Constants.TYPE_NAMES[t].toUpperCase(); - } else if(type.toString().equals("java.lang.String")) { - return "Type.STRING"; - } else if(type.toString().equals("java.lang.Object")) { - return "Type.OBJECT"; - } else if(type.toString().equals("java.lang.StringBuffer")) { - return "Type.STRINGBUFFER"; - } else if(type instanceof ArrayType) { - ArrayType at = (ArrayType)type; - - return "new ArrayType(" + printType(at.getBasicType()) + - ", " + at.getDimensions() + ")"; - } else { - return "new ObjectType(\"" + Utility.signatureToString(signature, false) + - "\")"; + @Override + public void visitMethod( final Method method ) { + final MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); + _out.println(" InstructionList il = new InstructionList();"); + _out.println(" MethodGen method = new MethodGen(" + + printFlags(method.getAccessFlags(), FLAGS.METHOD) + ", " + + printType(mg.getReturnType()) + ", " + + printArgumentTypes(mg.getArgumentTypes()) + ", " + + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true) + + " }, \"" + method.getName() + "\", \"" + _clazz.getClassName() + "\", il, _cp);"); + _out.println(); + final BCELFactory factory = new BCELFactory(mg, _out); + factory.start(); + _out.println(" method.setMaxStack();"); + _out.println(" method.setMaxLocals();"); + _out.println(" _cg.addMethod(method.getMethod());"); + _out.println(" il.dispose();"); } - } - /** Default _main method - */ - public static void _main(String[] argv) throws Exception { - JavaClass java_class; - String name = argv[0]; - if((java_class = Repository.lookupClass(name)) == null) - java_class = new ClassParser(name).parse(); // May throw IOException + static String printFlags( final int flags ) { + return printFlags(flags, FLAGS.UNKNOWN); + } - BCELifier bcelifier = new BCELifier(java_class, System.out); - bcelifier.start(); - } + /** + * Return a string with the flag settings + * @param flags the flags field to interpret + * @param location the item type + * @return the formatted string + * @since 6.0 made public + */ + public static String printFlags( final int flags, final FLAGS location ) { + if (flags == 0) { + return "0"; + } + final StringBuilder buf = new StringBuilder(); + for (int i = 0, pow = 1; pow <= Const.MAX_ACC_FLAG; i++) { + if ((flags & pow) != 0) { + if ((pow == Const.ACC_SYNCHRONIZED) && (location == FLAGS.CLASS)) { + buf.append(CONSTANT_PREFIX+"ACC_SUPER | "); + } else if ((pow == Const.ACC_VOLATILE) && (location == FLAGS.METHOD)) { + buf.append(CONSTANT_PREFIX+"ACC_BRIDGE | "); + } else if ((pow == Const.ACC_TRANSIENT) && (location == FLAGS.METHOD)) { + buf.append(CONSTANT_PREFIX+"ACC_VARARGS | "); + } else { + if (i < Const.ACCESS_NAMES_LENGTH) { + buf.append(CONSTANT_PREFIX+"ACC_") + .append(Const.getAccessName(i).toUpperCase(Locale.ENGLISH)) + .append( " | "); + } else { + buf.append(String.format (CONSTANT_PREFIX+"ACC_BIT %x | ", pow)); + } + } + } + pow <<= 1; + } + final String str = buf.toString(); + return str.substring(0, str.length() - 3); + } + + + static String printArgumentTypes( final Type[] arg_types ) { + if (arg_types.length == 0) { + return "Type.NO_ARGS"; + } + final StringBuilder args = new StringBuilder(); + for (int i = 0; i < arg_types.length; i++) { + args.append(printType(arg_types[i])); + if (i < arg_types.length - 1) { + args.append(", "); + } + } + return "new Type[] { " + args.toString() + " }"; + } + + + static String printType( final Type type ) { + return printType(type.getSignature()); + } + + + static String printType( final String signature ) { + final Type type = Type.getType(signature); + final byte t = type.getType(); + if (t <= Const.T_VOID) { + return "Type." + Const.getTypeName(t).toUpperCase(Locale.ENGLISH); + } else if (type.toString().equals("java.lang.String")) { + return "Type.STRING"; + } else if (type.toString().equals("java.lang.Object")) { + return "Type.OBJECT"; + } else if (type.toString().equals("java.lang.StringBuffer")) { + return "Type.STRINGBUFFER"; + } else if (type instanceof ArrayType) { + final ArrayType at = (ArrayType) type; + return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions() + + ")"; + } else { + return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")"; + } + } + + + /** Default main method + */ + public static void _main( final String[] argv ) throws Exception { + if (argv.length != 1) { + System.out.println("Usage: BCELifier classname"); + System.out.println("\tThe class must exist on the classpath"); + return; + } + final JavaClass java_class = getJavaClass(argv[0]); + final BCELifier bcelifier = new BCELifier(java_class, System.out); + bcelifier.start(); + } + + + // Needs to be accessible from unit test code + static JavaClass getJavaClass(final String name) throws ClassNotFoundException, IOException { + JavaClass java_class; + if ((java_class = Repository.lookupClass(name)) == null) { + java_class = new ClassParser(name).parse(); // May throw IOException + } + return java_class; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java index f1ea3f9c108..9a458bc3dd2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java @@ -21,29 +21,51 @@ package com.sun.org.apache.bcel.internal.util; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; /** * Utility class that implements a sequence of bytes which can be read * via the `readByte()' method. This is used to implement a wrapper for the * Java byte code stream to gain some more readability. * - * @author M. Dahm + * @version $Id: ByteSequence.java 1747278 2016-06-07 17:28:43Z britter $ */ public final class ByteSequence extends DataInputStream { - private ByteArrayStream byte_stream; - public ByteSequence(byte[] bytes) { - super(new ByteArrayStream(bytes)); - byte_stream = (ByteArrayStream)in; - } + private final ByteArrayStream byteStream; - public final int getIndex() { return byte_stream.getPosition(); } - final void unreadByte() { byte_stream.unreadByte(); } - private static final class ByteArrayStream extends ByteArrayInputStream { - ByteArrayStream(byte[] bytes) { super(bytes); } - final int getPosition() { return pos; } // is protected in ByteArrayInputStream - final void unreadByte() { if(pos > 0) pos--; } - } + public ByteSequence(final byte[] bytes) { + super(new ByteArrayStream(bytes)); + byteStream = (ByteArrayStream) in; + } + + + public final int getIndex() { + return byteStream.getPosition(); + } + + + final void unreadByte() { + byteStream.unreadByte(); + } + + private static final class ByteArrayStream extends ByteArrayInputStream { + + ByteArrayStream(final byte[] bytes) { + super(bytes); + } + + final int getPosition() { + // pos is protected in ByteArrayInputStream + return pos; + } + + final void unreadByte() { + if (pos > 0) { + pos--; + } + } + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java index 1ecbb71d632..87cbcf25ba7 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,212 +17,220 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.util; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashSet; +import java.util.Set; -import java.io.*; -import java.util.BitSet; -import com.sun.org.apache.bcel.internal.classfile.*; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.ClassParser; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Read class file(s) and convert them into HTML files. * - * Given a JavaClass object "class" that is in package "package" five files - * will be created in the specified directory. + * Given a JavaClass object "class" that is in package "package" five files will + * be created in the specified directory. * *
      - *
    1. "package"."class".html as the main file which defines the frames for - * the following subfiles. - *
    2. "package"."class"_attributes.html contains all (known) attributes found in the file - *
    3. "package"."class"_cp.html contains the constant pool - *
    4. "package"."class"_code.html contains the byte code - *
    5. "package"."class"_methods.html contains references to all methods and fields of the class + *
    6. "package"."class".html as the main file which defines the frames for the + * following subfiles. + *
    7. "package"."class"_attributes.html contains all (known) attributes found + * in the file + *
    8. "package"."class"_cp.html contains the constant pool + *
    9. "package"."class"_code.html contains the byte code + *
    10. "package"."class"_methods.html contains references to all methods and + * fields of the class *
    * - * All subfiles reference each other appropiately, e.g. clicking on a - * method in the Method's frame will jump to the appropiate method in - * the Code frame. + * All subfiles reference each other appropriately, e.g. clicking on a method in + * the Method's frame will jump to the appropriate method in the Code frame. * - * @author M. Dahm -*/ -public class Class2HTML implements Constants -{ - private JavaClass java_class; // current class object - private String dir; + * @version $Id: Class2HTML.java 1749603 2016-06-21 20:50:19Z ggregory $ + */ +public class Class2HTML { - private static String class_package; // name of package, unclean to make it static, but ... - private static String class_name; // name of current class, dito - private static ConstantPool constant_pool; + private final JavaClass java_class; // current class object + private final String dir; + private static String class_package; // name of package, unclean to make it static, but ... + private static String class_name; // name of current class, dito + private static ConstantPool constant_pool; + private static final Set basic_types = new HashSet<>(); - /** - * Write contents of the given JavaClass into HTML files. - * - * @param java_class The class to write - * @param dir The directory to put the files in - */ - public Class2HTML(JavaClass java_class, String dir) throws IOException { - Method[] methods = java_class.getMethods(); - - this.java_class = java_class; - this.dir = dir; - class_name = java_class.getClassName(); // Remember full name - constant_pool = java_class.getConstantPool(); - - // Get package name by tacking off everything after the last `.' - int index = class_name.lastIndexOf('.'); - if(index > -1) - class_package = class_name.substring(0, index); - else - class_package = ""; // default package - - ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods, - constant_pool); - - /* Attributes can't be written in one step, so we just open a file - * which will be written consequently. - */ - AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool, constant_html); - - MethodHTML method_html = new MethodHTML(dir, class_name, methods, java_class.getFields(), - constant_html, attribute_html); - // Write main file (with frames, yuk) - writeMainHTML(attribute_html); - new CodeHTML(dir, class_name, methods, constant_pool, constant_html); - attribute_html.close(); - } - - public static void _main(String argv[]) - { - String[] file_name = new String[argv.length]; - int files=0; - ClassParser parser=null; - JavaClass java_class=null; - String zip_file = null; - char sep = SecuritySupport.getSystemProperty("file.separator").toCharArray()[0]; - String dir = "." + sep; // Where to store HTML files - - try { - /* Parse command line arguments. - */ - for(int i=0; i < argv.length; i++) { - if(argv[i].charAt(0) == '-') { // command line switch - if(argv[i].equals("-d")) { // Specify target directory, default '.' - dir = argv[++i]; - - if(!dir.endsWith("" + sep)) - dir = dir + sep; - - new File(dir).mkdirs(); // Create target directory if necessary - } - else if(argv[i].equals("-zip")) - zip_file = argv[++i]; - else - System.out.println("Unknown option " + argv[i]); - } - else // add file name to list */ - file_name[files++] = argv[i]; - } - - if(files == 0) - System.err.println("Class2HTML: No input files specified."); - else { // Loop through files ... - for(int i=0; i < files; i++) { - System.out.print("Processing " + file_name[i] + "..."); - if(zip_file == null) - parser = new ClassParser(file_name[i]); // Create parser object from file - else - parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file - - java_class = parser.parse(); - new Class2HTML(java_class, dir); - System.out.println("Done."); - } - } - } catch(Exception e) { - System.out.println(e); - e.printStackTrace(System.out); + static { + basic_types.add("int"); + basic_types.add("short"); + basic_types.add("boolean"); + basic_types.add("void"); + basic_types.add("char"); + basic_types.add("byte"); + basic_types.add("long"); + basic_types.add("double"); + basic_types.add("float"); } - } - /** - * Utility method that converts a class reference in the constant pool, - * i.e., an index to a string. - */ - static String referenceClass(int index) { - String str = constant_pool.getConstantString(index, CONSTANT_Class); - str = Utility.compactClassName(str); - str = Utility.compactClassName(str, class_package + ".", true); - - return "" + str + ""; - } - - static final String referenceType(String type) { - String short_type = Utility.compactClassName(type); - short_type = Utility.compactClassName(short_type, class_package + ".", true); - - int index = type.indexOf('['); // Type is an array? - if(index > -1) - type = type.substring(0, index); // Tack of the `[' - - // test for basic type - if(type.equals("int") || type.equals("short") || type.equals("boolean") || type.equals("void") || - type.equals("char") || type.equals("byte") || type.equals("long") || type.equals("double") || - type.equals("float")) - return "" + type + ""; - else - return "" + short_type + ""; - } - - static String toHTML(String str) { - StringBuffer buf = new StringBuffer(); - - try { // Filter any characters HTML doesn't like such as < and > in particular - for(int i=0; i < str.length(); i++) { - char ch; - - switch(ch=str.charAt(i)) { - case '<': buf.append("<"); break; - case '>': buf.append(">"); break; - case '\n': buf.append("\\n"); break; - case '\r': buf.append("\\r"); break; - default: buf.append(ch); + /** + * Write contents of the given JavaClass into HTML files. + * + * @param java_class The class to write + * @param dir The directory to put the files in + */ + public Class2HTML(final JavaClass java_class, final String dir) throws IOException { + final Method[] methods = java_class.getMethods(); + this.java_class = java_class; + this.dir = dir; + class_name = java_class.getClassName(); // Remember full name + constant_pool = java_class.getConstantPool(); + // Get package name by tacking off everything after the last `.' + final int index = class_name.lastIndexOf('.'); + if (index > -1) { + class_package = class_name.substring(0, index); + } else { + class_package = ""; // default package } - } - } catch(StringIndexOutOfBoundsException e) {} // Never occurs + final ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods, + constant_pool); + /* Attributes can't be written in one step, so we just open a file + * which will be written consequently. + */ + final AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool, + constant_html); + new MethodHTML(dir, class_name, methods, java_class.getFields(), + constant_html, attribute_html); + // Write main file (with frames, yuk) + writeMainHTML(attribute_html); + new CodeHTML(dir, class_name, methods, constant_pool, constant_html); + attribute_html.close(); + } - return buf.toString(); - } + public static void _main(final String[] argv) throws IOException { + final String[] file_name = new String[argv.length]; + int files = 0; + ClassParser parser = null; + JavaClass java_class = null; + String zip_file = null; + final char sep = File.separatorChar; + String dir = "." + sep; // Where to store HTML files + /* Parse command line arguments. + */ + for (int i = 0; i < argv.length; i++) { + if (argv[i].charAt(0) == '-') { // command line switch + if (argv[i].equals("-d")) { // Specify target directory, default '.' + dir = argv[++i]; + if (!dir.endsWith("" + sep)) { + dir = dir + sep; + } + final File store = new File(dir); - private void writeMainHTML(AttributeHTML attribute_html) throws IOException { - PrintWriter file = new PrintWriter(new FileOutputStream(dir + class_name + ".html")); - Attribute[] attributes = java_class.getAttributes(); + if (!store.isDirectory()) { + final boolean created = store.mkdirs(); // Create target directory if necessary + if (!created) { + if (!store.isDirectory()) { + System.out.println("Tried to create the directory " + dir + " but failed"); + } + } + } + } else if (argv[i].equals("-zip")) { + zip_file = argv[++i]; + } else { + System.out.println("Unknown option " + argv[i]); + } + } else { + file_name[files++] = argv[i]; + } + } + if (files == 0) { + System.err.println("Class2HTML: No input files specified."); + } else { // Loop through files ... + for (int i = 0; i < files; i++) { + System.out.print("Processing " + file_name[i] + "..."); + if (zip_file == null) { + parser = new ClassParser(file_name[i]); // Create parser object from file + } else { + parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file + } + java_class = parser.parse(); + new Class2HTML(java_class, dir); + System.out.println("Done."); + } + } + } - file.println("\n" + "Documentation for " + class_name + "" + - "\n" + - "\n" + - "\n" + + /** + * Utility method that converts a class reference in the constant pool, + * i.e., an index to a string. + */ + static String referenceClass(final int index) { + String str = constant_pool.getConstantString(index, Const.CONSTANT_Class); + str = Utility.compactClassName(str); + str = Utility.compactClassName(str, class_package + ".", true); + return "" + str + + ""; + } - "\n" + - "\n" + - "\n" + + static String referenceType(final String type) { + String short_type = Utility.compactClassName(type); + short_type = Utility.compactClassName(short_type, class_package + ".", true); + final int index = type.indexOf('['); // Type is an array? + String base_type = type; + if (index > -1) { + base_type = type.substring(0, index); // Tack of the `[' + } + // test for basic type + if (basic_types.contains(base_type)) { + return "" + type + ""; + } + return "" + short_type + ""; + } - "\n" + - "\n" + - "\n" + - "" - ); + static String toHTML(final String str) { + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < str.length(); i++) { + char ch; + switch (ch = str.charAt(i)) { + case '<': + buf.append("<"); + break; + case '>': + buf.append(">"); + break; + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + default: + buf.append(ch); + } + } + return buf.toString(); + } - file.close(); - - for(int i=0; i < attributes.length; i++) - attribute_html.writeAttribute(attributes[i], "class" + i); - } + private void writeMainHTML(final AttributeHTML attribute_html) throws IOException { + try (PrintWriter file = new PrintWriter(new FileOutputStream(dir + class_name + ".html"))) { + file.println("\n" + "Documentation for " + class_name + "" + "\n" + + "\n" + "\n" + + "\n" + "\n" + "\n" + + "\n" + "\n" + + "\n" + ""); + } + final Attribute[] attributes = java_class.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + attribute_html.writeAttribute(attributes[i], "class" + i); + } + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoader.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoader.java deleted file mode 100644 index 12708ad89f3..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoader.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal.util; - - -import java.util.Hashtable; -import java.io.*; -import com.sun.org.apache.bcel.internal.*; -import com.sun.org.apache.bcel.internal.classfile.*; - -/** - *

    Drop in replacement for the standard class loader of the JVM. You can use it - * in conjunction with the JavaWrapper to dynamically modify/create classes - * as they're requested.

    - * - *

    This class loader recognizes special requests in a distinct - * format, i.e., when the name of the requested class contains with - * "$$BCEL$$" it calls the createClass() method with that name - * (everything bevor the $$BCEL$$ is considered to be the package - * name. You can subclass the class loader and override that - * method. "Normal" classes class can be modified by overriding the - * modifyClass() method which is called just before defineClass().

    - * - *

    There may be a number of packages where you have to use the default - * class loader (which may also be faster). You can define the set of packages - * where to use the system class loader in the constructor. The default value contains - * "java.", "sun.", "javax."

    - * - * @author M. Dahm - * @see JavaWrapper - * @see ClassPath - */ -public class ClassLoader extends java.lang.ClassLoader { - private Hashtable classes = new Hashtable(); // Hashtable is synchronized thus thread-safe - private String[] ignored_packages = { - "java.", "javax.", "sun." - }; - private Repository repository = SyntheticRepository.getInstance(); - private java.lang.ClassLoader deferTo = ClassLoader.getSystemClassLoader(); - - public ClassLoader() { - } - - public ClassLoader(java.lang.ClassLoader deferTo) { - this.deferTo = deferTo; - this.repository = new ClassLoaderRepository(deferTo); - } - - /** @param ignored_packages classes contained in these packages will be loaded - * with the system class loader - */ - public ClassLoader(String[] ignored_packages) { - addIgnoredPkgs(ignored_packages); - } - - public ClassLoader(java.lang.ClassLoader deferTo, String [] ignored_packages) { - this.deferTo = deferTo; - this.repository = new ClassLoaderRepository(deferTo); - - addIgnoredPkgs(ignored_packages); - } - - private void addIgnoredPkgs(String[] ignored_packages) { - String[] new_p = new String[ignored_packages.length + this.ignored_packages.length]; - - System.arraycopy(this.ignored_packages, 0, new_p, 0, this.ignored_packages.length); - System.arraycopy(ignored_packages, 0, new_p, this.ignored_packages.length, - ignored_packages.length); - - this.ignored_packages = new_p; - } - - protected Class loadClass(String class_name, boolean resolve) - throws ClassNotFoundException - { - Class cl = null; - - /* First try: lookup hash table. - */ - if((cl=(Class)classes.get(class_name)) == null) { - /* Second try: Load system class using system class loader. You better - * don't mess around with them. - */ - for(int i=0; i < ignored_packages.length; i++) { - if(class_name.startsWith(ignored_packages[i])) { - cl = deferTo.loadClass(class_name); - break; - } - } - - if(cl == null) { - JavaClass clazz = null; - - /* Third try: Special request? - */ - if(class_name.indexOf("$$BCEL$$") >= 0) - clazz = createClass(class_name); - else { // Fourth try: Load classes via repository - if ((clazz = repository.loadClass(class_name)) != null) { - clazz = modifyClass(clazz); - } - else - throw new ClassNotFoundException(class_name); - } - - if(clazz != null) { - byte[] bytes = clazz.getBytes(); - cl = defineClass(class_name, bytes, 0, bytes.length); - } else // Fourth try: Use default class loader - cl = Class.forName(class_name); - } - - if(resolve) - resolveClass(cl); - } - - classes.put(class_name, cl); - - return cl; - } - - /** Override this method if you want to alter a class before it gets actually - * loaded. Does nothing by default. - */ - protected JavaClass modifyClass(JavaClass clazz) { - return clazz; - } - - /** - * Override this method to create you own classes on the fly. The - * name contains the special token $$BCEL$$. Everything before that - * token is consddered to be a package name. You can encode you own - * arguments into the subsequent string. You must regard however not - * to use any "illegal" characters, i.e., characters that may not - * appear in a Java class name too
    - * - * The default implementation interprets the string as a encoded compressed - * Java class, unpacks and decodes it with the Utility.decode() method, and - * parses the resulting byte array and returns the resulting JavaClass object. - * - * @param class_name compressed byte code with "$$BCEL$$" in it - */ - protected JavaClass createClass(String class_name) { - int index = class_name.indexOf("$$BCEL$$"); - String real_name = class_name.substring(index + 8); - - JavaClass clazz = null; - try { - byte[] bytes = Utility.decode(real_name, true); - ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), "foo"); - - clazz = parser.parse(); - } catch(Throwable e) { - e.printStackTrace(); - return null; - } - - // Adapt the class name to the passed value - ConstantPool cp = clazz.getConstantPool(); - - ConstantClass cl = (ConstantClass)cp.getConstant(clazz.getClassNameIndex(), - Constants.CONSTANT_Class); - ConstantUtf8 name = (ConstantUtf8)cp.getConstant(cl.getNameIndex(), - Constants.CONSTANT_Utf8); - name.setBytes(class_name.replace('.', '/')); - - return clazz; - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoaderRepository.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoaderRepository.java deleted file mode 100644 index 80e844216d6..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoaderRepository.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal.util; - - -import java.io.*; - -import java.util.Map; -import java.util.HashMap; - -import com.sun.org.apache.bcel.internal.classfile.*; - -/** - * The repository maintains information about which classes have - * been loaded. - * - * It loads its data from the ClassLoader implementation - * passed into its constructor. - * - * @see com.sun.org.apache.bcel.internal.Repository - * - * @author M. Dahm - * @author David Dixon-Peugh - */ -public class ClassLoaderRepository - implements Repository -{ - private java.lang.ClassLoader loader; - private HashMap loadedClasses = - new HashMap(); // CLASSNAME X JAVACLASS - - public ClassLoaderRepository( java.lang.ClassLoader loader ) { - this.loader = loader; - } - - /** - * Store a new JavaClass into this Repository. - */ - public void storeClass( JavaClass clazz ) { - loadedClasses.put( clazz.getClassName(), - clazz ); - clazz.setRepository( this ); - } - - /** - * Remove class from repository - */ - public void removeClass(JavaClass clazz) { - loadedClasses.remove(clazz.getClassName()); - } - - /** - * Find an already defined JavaClass. - */ - public JavaClass findClass( String className ) { - if ( loadedClasses.containsKey( className )) { - return (JavaClass) loadedClasses.get( className ); - } else { - return null; - } - } - - /** - * Lookup a JavaClass object from the Class Name provided. - */ - public JavaClass loadClass( String className ) - throws ClassNotFoundException - { - String classFile = className.replace('.', '/'); - - JavaClass RC = findClass( className ); - if (RC != null) { return RC; } - - try { - InputStream is = - loader.getResourceAsStream( classFile + ".class" ); - - if(is == null) { - throw new ClassNotFoundException(className + " not found."); - } - - ClassParser parser = new ClassParser( is, className ); - RC = parser.parse(); - - storeClass( RC ); - - return RC; - } catch (IOException e) { - throw new ClassNotFoundException( e.toString() ); - } - } - - public JavaClass loadClass(Class clazz) throws ClassNotFoundException { - return loadClass(clazz.getName()); - } - - /** Clear all entries from cache. - */ - public void clear() { - loadedClasses.clear(); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java index a4dda645d10..5aa4d430953 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,31 +17,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.util; import java.util.LinkedList; + import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** - * Utility class implementing a (typesafe) queue of JavaClass - * objects. + * Utility class implementing a (typesafe) queue of JavaClass objects. * - * @author M. Dahm - * @see ClassVector -*/ -public class ClassQueue implements java.io.Serializable { - protected LinkedList vec = new LinkedList(); + * @version $Id: ClassQueue.java 1747278 2016-06-07 17:28:43Z britter $ + */ +public class ClassQueue { - public void enqueue(JavaClass clazz) { vec.addLast(clazz); } + private final LinkedList vec = new LinkedList<>(); - public JavaClass dequeue() { - return (JavaClass)vec.removeFirst(); - } + public void enqueue(final JavaClass clazz) { + vec.addLast(clazz); + } - public boolean empty() { return vec.isEmpty(); } + public JavaClass dequeue() { + return vec.removeFirst(); + } - public String toString() { - return vec.toString(); - } + public boolean empty() { + return vec.isEmpty(); + } + + @Override + public String toString() { + return vec.toString(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java index 27dd9b7ce82..f35a712b663 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java @@ -21,8 +21,10 @@ package com.sun.org.apache.bcel.internal.util; -import java.util.HashMap; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** @@ -30,34 +32,43 @@ import com.sun.org.apache.bcel.internal.classfile.JavaClass; * Since JavaClass has no equals() method, the name of the class is * used for comparison. * - * @author M. Dahm + * @version $Id: ClassSet.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see ClassStack -*/ -public class ClassSet implements java.io.Serializable { - private HashMap _map = new HashMap(); + */ +public class ClassSet { - public boolean add(JavaClass clazz) { - boolean result = false; + private final Map map = new HashMap<>(); - if(!_map.containsKey(clazz.getClassName())) { - result = true; - _map.put(clazz.getClassName(), clazz); + + public boolean add( final JavaClass clazz ) { + boolean result = false; + if (!map.containsKey(clazz.getClassName())) { + result = true; + map.put(clazz.getClassName(), clazz); + } + return result; } - return result; - } - public void remove(JavaClass clazz) { _map.remove(clazz.getClassName()); } - public boolean empty() { return _map.isEmpty(); } + public void remove( final JavaClass clazz ) { + map.remove(clazz.getClassName()); + } - public JavaClass[] toArray() { - Collection values = _map.values(); - JavaClass[] classes = new JavaClass[values.size()]; - values.toArray(classes); - return classes; - } - public String[] getClassNames() { - return (String[])_map.keySet().toArray(new String[_map.keySet().size()]); - } + public boolean empty() { + return map.isEmpty(); + } + + + public JavaClass[] toArray() { + final Collection values = map.values(); + final JavaClass[] classes = new JavaClass[values.size()]; + values.toArray(classes); + return classes; + } + + + public String[] getClassNames() { + return map.keySet().toArray(new String[map.size()]); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java index 52275dda1f1..0ee2767428d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java @@ -27,14 +27,30 @@ import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** * Utility class implementing a (typesafe) stack of JavaClass objects. * - * @author M. Dahm + * @version $Id: ClassStack.java 1747278 2016-06-07 17:28:43Z britter $ * @see Stack -*/ -public class ClassStack implements java.io.Serializable { - private Stack stack = new Stack(); + */ +public class ClassStack { - public void push(JavaClass clazz) { stack.push(clazz); } - public JavaClass pop() { return (JavaClass)stack.pop(); } - public JavaClass top() { return (JavaClass)stack.peek(); } - public boolean empty() { return stack.empty(); } + private final Stack stack = new Stack<>(); + + + public void push( final JavaClass clazz ) { + stack.push(clazz); + } + + + public JavaClass pop() { + return stack.pop(); + } + + + public JavaClass top() { + return stack.peek(); + } + + + public boolean empty() { + return stack.empty(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java index eb9d4bf65ec..d1e792b1511 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java @@ -21,565 +21,569 @@ package com.sun.org.apache.bcel.internal.util; - -import com.sun.org.apache.bcel.internal.classfile.*; -import java.io.*; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; import java.util.BitSet; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Code; +import com.sun.org.apache.bcel.internal.classfile.CodeException; +import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref; +import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic; +import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.LocalVariable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; + /** * Convert code into HTML file. * - * @author M. Dahm + * @version $Id: CodeHTML.java 1749603 2016-06-21 20:50:19Z ggregory $ * */ -final class CodeHTML implements com.sun.org.apache.bcel.internal.Constants { - private String class_name; // name of current class - private Method[] methods; // Methods to print - private PrintWriter file; // file to write to - private BitSet goto_set; - private ConstantPool constant_pool; - private ConstantHTML constant_html; - private static boolean wide=false; +final class CodeHTML { - CodeHTML(String dir, String class_name, - Method[] methods, ConstantPool constant_pool, - ConstantHTML constant_html) throws IOException - { - this.class_name = class_name; - this.methods = methods; - this.constant_pool = constant_pool; - this.constant_html = constant_html; + private final String class_name; // name of current class +// private Method[] methods; // Methods to print + private final PrintWriter file; // file to write to + private BitSet goto_set; + private final ConstantPool constant_pool; + private final ConstantHTML constant_html; + private static boolean wide = false; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html")); - file.println(""); - for(int i=0; i < methods.length; i++) - writeMethod(methods[i], i); + CodeHTML(final String dir, final String class_name, final Method[] methods, final ConstantPool constant_pool, + final ConstantHTML constant_html) throws IOException { + this.class_name = class_name; +// this.methods = methods; + this.constant_pool = constant_pool; + this.constant_html = constant_html; + file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html")); + file.println(""); + for (int i = 0; i < methods.length; i++) { + writeMethod(methods[i], i); + } + file.println(""); + file.close(); + } - file.println(""); - file.close(); - } - /** - * Disassemble a stream of byte codes and return the - * string representation. - * - * @param stream data input stream - * @return String representation of byte code - */ - private final String codeToHTML(ByteSequence bytes, int method_number) - throws IOException - { - short opcode = (short)bytes.readUnsignedByte(); - StringBuffer buf; - String name, signature; - int default_offset=0, low, high; - int index, class_index, vindex, constant; - int[] jump_table; - int no_pad_bytes=0, offset; - - buf = new StringBuffer("" + OPCODE_NAMES[opcode] + "
    "); - return buf.toString(); - } - - /** - * Find all target addresses in code, so that they can be marked - * with <A NAME = ...>. Target addresses are kept in an BitSet object. - */ - private final void findGotos(ByteSequence bytes, Method method, Code code) - throws IOException - { - int index; - goto_set = new BitSet(bytes.available()); - int opcode; - - /* First get Code attribute from method and the exceptions handled - * (try .. catch) in this method. We only need the line number here. - */ - - if(code != null) { - CodeException[] ce = code.getExceptionTable(); - int len = ce.length; - - for(int i=0; i < len; i++) { - goto_set.set(ce[i].getStartPC()); - goto_set.set(ce[i].getEndPC()); - goto_set.set(ce[i].getHandlerPC()); - } - - // Look for local variables and their range - Attribute[] attributes = code.getAttributes(); - for(int i=0; i < attributes.length; i++) { - if(attributes[i].getTag() == ATTR_LOCAL_VARIABLE_TABLE) { - LocalVariable[] vars = ((LocalVariableTable)attributes[i]).getLocalVariableTable(); - - for(int j=0; j < vars.length; j++) { - int start = vars[j].getStartPC(); - int end = (int)(start + vars[j].getLength()); - goto_set.set(start); - goto_set.set(end); - } - break; - } - } - } - - // Get target addresses from GOTO, JSR, TABLESWITCH, etc. - for(int i=0; bytes.available() > 0; i++) { - opcode = bytes.readUnsignedByte(); - //System.out.println(OPCODE_NAMES[opcode]); - switch(opcode) { - case TABLESWITCH: case LOOKUPSWITCH: - //bytes.readByte(); // Skip already read byte - - int remainder = bytes.getIndex() % 4; - int no_pad_bytes = (remainder == 0)? 0 : 4 - remainder; - int default_offset, offset; - - for(int j=0; j < no_pad_bytes; j++) - bytes.readByte(); - - // Both cases have a field default_offset in common - default_offset = bytes.readInt(); - - if(opcode == TABLESWITCH) { - int low = bytes.readInt(); - int high = bytes.readInt(); - - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - goto_set.set(default_offset); - - for(int j=0; j < (high - low + 1); j++) { - index = offset + bytes.readInt(); - goto_set.set(index); - } - } - else { // LOOKUPSWITCH - int npairs = bytes.readInt(); - - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - default_offset += offset; - goto_set.set(default_offset); - - for(int j=0; j < npairs; j++) { - int match = bytes.readInt(); - - index = offset + bytes.readInt(); - goto_set.set(index); - } - } - break; - - case GOTO: case IFEQ: case IFGE: case IFGT: - case IFLE: case IFLT: - case IFNE: case IFNONNULL: case IFNULL: case IF_ACMPEQ: - case IF_ACMPNE: case IF_ICMPEQ: case IF_ICMPGE: case IF_ICMPGT: - case IF_ICMPLE: case IF_ICMPLT: case IF_ICMPNE: case JSR: - //bytes.readByte(); // Skip already read byte - index = bytes.getIndex() + bytes.readShort() - 1; - - goto_set.set(index); - break; - - case GOTO_W: case JSR_W: - //bytes.readByte(); // Skip already read byte - index = bytes.getIndex() + bytes.readInt() - 1; - goto_set.set(index); - break; - - default: - bytes.unreadByte(); - codeToHTML(bytes, 0); // Ignore output - } - } - } - - /** - * Write a single method with the byte code associated with it. - */ - private void writeMethod(Method method, int method_number) - throws IOException - { - // Get raw signature - String signature = method.getSignature(); - // Get array of strings containing the argument types - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - // Get return type string - String type = Utility.methodSignatureReturnType(signature, false); - // Get method name - String name = method.getName(); - String html_name = Class2HTML.toHTML(name); - // Get method's access flags - String access = Utility.accessToString(method.getAccessFlags()); - access = Utility.replace(access, " ", " "); - // Get the method's attributes, the Code Attribute in particular - Attribute[] attributes= method.getAttributes(); - - file.print("

    " + access + " " + - "" + Class2HTML.referenceType(type) + - " " + html_name + "("); - - for(int i=0; i < args.length; i++) { - file.print(Class2HTML.referenceType(args[i])); - if(i < args.length - 1) - file.print(", "); - } - - file.println(")

    "); - - Code c=null; - byte[] code=null; - - if(attributes.length > 0) { - file.print("

    Attributes

      \n"); - for(int i=0; i < attributes.length; i++) { - byte tag = attributes[i].getTag(); - - if(tag != ATTR_UNKNOWN) - file.print("
    • " + ATTRIBUTE_NAMES[tag] + "
    • \n"); - else - file.print("
    • " + attributes[i] + "
    • "); - - if(tag == ATTR_CODE) { - c = (Code)attributes[i]; - Attribute[] attributes2 = c.getAttributes(); - code = c.getCode(); - - file.print("
        "); - for(int j=0; j < attributes2.length; j++) { - tag = attributes2[j].getTag(); - file.print("
      • " + - ATTRIBUTE_NAMES[tag] + "
      • \n"); - - } - file.print("
      "); - } - } - file.println("
    "); - } - - if(code != null) { // No code, an abstract method, e.g. - //System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1)); - - // Print the byte code - ByteSequence stream = new ByteSequence(code); - stream.mark(stream.available()); - findGotos(stream, method, c); - stream.reset(); - - file.println("
    Configuration of Hijrah Calendar
    Property Name Property value Description Property NameProperty valueDescription
    ididChronology Id, for example, "Hijrah-umalqura"The Id of the calendar in common usage
    typetypeCalendar type, for example, "islamic-umalqura"LDML defines the calendar types
    versionversionVersion, for example: "1.8.0_1"The version of the Hijrah variant data
    iso-startiso-startISO start date, formatted as {@code yyyy-MM-dd}, for example: "1900-04-30"The ISO date of the first day of the minimum Hijrah year.
    yyyy - a numeric 4 digit year, for example "1434"yyyy - a numeric 4 digit year, for example "1434"The value is a sequence of 12 month lengths, * for example: "29 30 29 30 29 30 30 30 29 30 29 29"The lengths of the 12 months of the year separated by whitespace. diff --git a/jdk/src/java.base/share/classes/java/time/chrono/IsoEra.java b/jdk/src/java.base/share/classes/java/time/chrono/IsoEra.java index 702fabdf920..887d76f72b6 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/IsoEra.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/IsoEra.java @@ -70,27 +70,27 @@ import java.time.DateTimeException; * A definition has therefore been created with two eras - 'Current era' (CE) for * years on or after 0001-01-01 (ISO), and 'Before current era' (BCE) for years before that. * - * + *
    * * * - * - * - * + * + * + * * * * * - * + * * * - * + * * * - * + * * * - * + * * * *
    ISO years and eras
    year-of-eraeraproleptic-yearyear-of-eraeraproleptic-year
    2CE22CE2
    1CE11CE1
    1BCE01BCE0
    2BCE-12BCE-1
    diff --git a/jdk/src/java.base/share/classes/java/time/chrono/MinguoEra.java b/jdk/src/java.base/share/classes/java/time/chrono/MinguoEra.java index edac0ec02e7..9c227884994 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/MinguoEra.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/MinguoEra.java @@ -71,28 +71,28 @@ import java.time.DateTimeException; * All previous years, zero or earlier in the proleptic count or one and greater * in the year-of-era count, are part of the 'Before Republic of China' era. * - * + *
    * * * - * - * - * - * + * + * + * + * * * * * - * + * * * - * + * * * - * + * * * - * + * * * *
    Minguo years and eras
    year-of-eraeraproleptic-yearISO proleptic-yearyear-of-eraeraproleptic-yearISO proleptic-year
    2ROC219132ROC21913
    1ROC119121ROC11912
    1BEFORE_ROC019111BEFORE_ROC01911
    2BEFORE_ROC-119102BEFORE_ROC-11910
    diff --git a/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistEra.java b/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistEra.java index 53cb5d870be..46c0f112bd5 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistEra.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistEra.java @@ -71,28 +71,28 @@ import java.time.DateTimeException; * All previous years, zero or earlier in the proleptic count or one and greater * in the year-of-era count, are part of the 'Before Buddhist' era. * - * + *
    * * * - * - * - * - * + * + * + * + * * * * * - * + * * * - * + * * * - * + * * * - * + * * * *
    Buddhist years and eras
    year-of-eraeraproleptic-yearISO proleptic-yearyear-of-eraeraproleptic-yearISO proleptic-year
    2BE2-5422BE2-542
    1BE1-5431BE1-543
    1BEFORE_BE0-5441BEFORE_BE0-544
    2BEFORE_BE-1-5452BEFORE_BE-1-545
    diff --git a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java index 7315a9a3544..79d2f061508 100644 --- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java +++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java @@ -150,13 +150,13 @@ import java.util.Set; * implementation of {@code java.text.Format}. * *

    Predefined Formatters

    - * + *
    * * * - * - * - * + * + * + * * * * @@ -276,56 +276,60 @@ import java.util.Set; *

    * All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The * following pattern letters are defined: - *

    - *  Symbol  Meaning                     Presentation      Examples
    - *  ------  -------                     ------------      -------
    - *   G       era                         text              AD; Anno Domini; A
    - *   u       year                        year              2004; 04
    - *   y       year-of-era                 year              2004; 04
    - *   D       day-of-year                 number            189
    - *   M/L     month-of-year               number/text       7; 07; Jul; July; J
    - *   d       day-of-month                number            10
    - *   g       modified-julian-day         number            2451334
    + * 
    Predefined Formatters
    FormatterDescriptionExampleFormatterDescriptionExample
    + * + * + * + * + * + * + * + * + * + * + * + * * - * Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter - * Y week-based-year year 1996; 96 - * w week-of-week-based-year number 27 - * W week-of-month number 4 - * E day-of-week text Tue; Tuesday; T - * e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T - * F day-of-week-in-month number 3 + * + * + * + * + * + * + * * - * a am-pm-of-day text PM - * h clock-hour-of-am-pm (1-12) number 12 - * K hour-of-am-pm (0-11) number 0 - * k clock-hour-of-day (1-24) number 24 + * + * + * + * * - * H hour-of-day (0-23) number 0 - * m minute-of-hour number 30 - * s second-of-minute number 55 - * S fraction-of-second fraction 978 - * A milli-of-day number 1234 - * n nano-of-second number 987654321 - * N nano-of-day number 1234000000 + * + * + * + * + * + * + * * - * V time-zone ID zone-id America/Los_Angeles; Z; -08:30 - * v generic time-zone name zone-name Pacific Time; PT - * z time-zone name zone-name Pacific Standard Time; PST - * O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00 - * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15 - * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15 - * Z zone-offset offset-Z +0000; -0800; -08:00 + * + * + * + * + * + * + * * - * p pad next pad modifier 1 + * * - * ' escape for text delimiter - * '' single quote literal ' - * [ optional section start - * ] optional section end - * # reserved for future use - * { reserved for future use - * } reserved for future use - * + * + * + * + * + * + * + * + * + *
    Pattern Letters and Symbols
    Symbol Meaning Presentation Examples
    G era text AD; Anno Domini; A
    u year year 2004; 04
    y year-of-era year 2004; 04
    D day-of-year number 189
    M/L month-of-year number/text 7; 07; Jul; July; J
    d day-of-month number 10
    g modified-julian-day number 2451334
    Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
    Y week-based-year year 1996; 96
    w week-of-week-based-year number 27
    W week-of-month number 4
    E day-of-week text Tue; Tuesday; T
    e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
    F day-of-week-in-month number 3
    a am-pm-of-day text PM
    h clock-hour-of-am-pm (1-12) number 12
    K hour-of-am-pm (0-11) number 0
    k clock-hour-of-day (1-24) number 24
    H hour-of-day (0-23) number 0
    m minute-of-hour number 30
    s second-of-minute number 55
    S fraction-of-second fraction 978
    A milli-of-day number 1234
    n nano-of-second number 987654321
    N nano-of-day number 1234000000
    V time-zone ID zone-id America/Los_Angeles; Z; -08:30
    v generic time-zone name zone-name Pacific Time; PT
    z time-zone name zone-name Pacific Standard Time; PST
    O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00
    X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15
    x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15
    Z zone-offset offset-Z +0000; -0800; -08:00
    p pad next pad modifier 1
    ' escape for text delimiter
    '' single quote literal '
    [ optional section start
    ] optional section end
    # reserved for future use
    { reserved for future use
    } reserved for future use
    *

    * The count of pattern letters determines the format. *

    diff --git a/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java b/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java index 9740a9defc0..0b910830126 100644 --- a/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java +++ b/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java @@ -136,18 +136,18 @@ import sun.util.locale.provider.LocaleResources; *

    * For example: * - * + *
    * * - * + * * * - * - * - * - * - * - * + * + * + * + * + * + * * *
    Examples of Week based Years
    DateDay-of-weekField values
    DateDay-of-weekField values
    2008-12-28SundayWeek 52 of week-based-year 2008
    2008-12-29MondayWeek 1 of week-based-year 2009
    2008-12-31WednesdayWeek 1 of week-based-year 2009
    2009-01-01ThursdayWeek 1 of week-based-year 2009
    2009-01-04SundayWeek 1 of week-based-year 2009
    2009-01-05MondayWeek 2 of week-based-year 2009
    2008-12-28SundayWeek 52 of week-based-year 2008
    2008-12-29MondayWeek 1 of week-based-year 2009
    2008-12-31WednesdayWeek 1 of week-based-year 2009
    2009-01-01ThursdayWeek 1 of week-based-year 2009
    2009-01-04SundayWeek 1 of week-based-year 2009
    2009-01-05MondayWeek 2 of week-based-year 2009
    * diff --git a/jdk/src/java.base/share/classes/java/time/temporal/WeekFields.java b/jdk/src/java.base/share/classes/java/time/temporal/WeekFields.java index 2f13368d28f..60478772d9f 100644 --- a/jdk/src/java.base/share/classes/java/time/temporal/WeekFields.java +++ b/jdk/src/java.base/share/classes/java/time/temporal/WeekFields.java @@ -130,17 +130,17 @@ import sun.util.locale.provider.LocaleResources; * * * - * - * + * + * * * - * + * * - * + * * - * + * * - * + * * * *
    Examples of WeekFields
    DateDay-of-weekFirst day: Monday
    Minimal days: 4
    First day: Monday
    Minimal days: 5
    DateDay-of-weekFirst day: Monday
    Minimal days: 4
    First day: Monday
    Minimal days: 5
    2008-12-31Wednesday
    2008-12-31WednesdayWeek 5 of December 2008Week 5 of December 2008
    2009-01-01Thursday
    2009-01-01ThursdayWeek 1 of January 2009Week 0 of January 2009
    2009-01-04Sunday
    2009-01-04SundayWeek 1 of January 2009Week 0 of January 2009
    2009-01-05Monday
    2009-01-05MondayWeek 2 of January 2009Week 1 of January 2009
    @@ -164,17 +164,17 @@ import sun.util.locale.provider.LocaleResources; * * * - * - * + * + * * * - * + * * - * + * * - * + * * - * + * * * *
    Examples of WeekFields for week-based-year
    DateDay-of-weekFirst day: Monday
    Minimal days: 4
    First day: Monday
    Minimal days: 5
    DateDay-of-weekFirst day: Monday
    Minimal days: 4
    First day: Monday
    Minimal days: 5
    2008-12-31Wednesday
    2008-12-31WednesdayWeek 1 of 2009Week 53 of 2008
    2009-01-01Thursday
    2009-01-01ThursdayWeek 1 of 2009Week 53 of 2008
    2009-01-04Sunday
    2009-01-04SundayWeek 1 of 2009Week 53 of 2008
    2009-01-05Monday
    2009-01-05MondayWeek 2 of 2009Week 1 of 2009
    From 577dc3fca285ea8086098d236b4159f0d4e9a739 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 11 Aug 2017 15:44:44 -0700 Subject: [PATCH 18/42] 8186157: (scanner) Modify java/util/Scanner/ScanTest.java to fail if Engilsh Locale unavailable Fail if the English locale is not available on the system Reviewed-by: lancea --- jdk/test/java/util/Scanner/ScanTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/jdk/test/java/util/Scanner/ScanTest.java b/jdk/test/java/util/Scanner/ScanTest.java index 0f1abcbd8b5..44ee2b0b463 100644 --- a/jdk/test/java/util/Scanner/ScanTest.java +++ b/jdk/test/java/util/Scanner/ScanTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,14 @@ public class ScanTest { !"ja".equals(lang)) { //Before we have resource to improve the test to be ready for //arbitrary locale, force the default locale to be "English" - //for now. + //for now. First we check whether the "English" locale is + //available on the system as it could be absent due to varying + //configurations. + if (!Arrays.asList(Locale.getAvailableLocales()) + .contains(Locale.ENGLISH)) { + throw new RuntimeException + ("The \"English\" Locale is unavailable on this system"); + } Locale.setDefault(Locale.ENGLISH); } skipTest(); From 34afeced211cd7115e2529b043c1e57dfa1291fe Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 28 Jul 2017 14:06:28 +0200 Subject: [PATCH 19/42] 8185500: [TESTBUG] Add keywords headful/printer in java/awt and javax tests Add new keyword 'printer'. Some minor test fixes to show headless exception. Add some @requires windows. Reviewed-by: serb, mbaesken --- jdk/test/TEST.ROOT | 6 ++-- .../DefaultMenuBar/DefaultMenuBarTest.java | 5 ++-- .../ScreenMenu/ScreenMenuMemoryLeakTest.java | 7 +++-- .../awt/Choice/ChoiceHiDpi/ChoiceTest.java | 5 ++-- .../DesktopGtkLoadTest.java | 6 ++-- .../Dialog/CloseDialog/CloseDialogTest.java | 4 ++- .../Modal/NestedModalDialogTest.java | 24 ++++++++------- .../Modeless/NestedModelessDialogTest.java | 24 ++++++++------- .../DisplayChangedTest.java | 30 ++++++++----------- .../EmbeddedFrameGrabTest.java | 27 ++++++++--------- .../LoopRobustness/LoopRobustness.html | 3 +- .../awt/EventQueue/6980209/bug6980209.java | 14 +++++---- .../FileDialogIconTest.java | 10 ++++--- .../FocusEmbeddedFrameTest.java | 29 +++++++++--------- .../ButtonGroupLayoutTraversalTest.java | 16 +++++----- .../RequestFocusByCauseTest.java | 20 +++++++------ .../java/awt/FontClass/HelvLtOblTest.java | 5 ++-- .../FontClass/SurrogateTest/SuppCharTest.java | 5 ++-- .../awt/Frame/8158918/SetExtendedState.java | 6 ++-- .../DecoratedFrameInsetsTest.java | 5 ++-- .../ExceptionOnSetExtendedStateTest.java | 16 +++++----- .../MaximizedByPlatform.java | 10 ++++--- .../NormalToIconifiedTest.java | 5 ++-- .../MaximizedMovedWindow.java | 6 ++-- .../SetMaximizedBounds.java | 6 ++-- .../Frame/WindowDragTest/WindowDragTest.java | 21 ++++++------- .../CurrentDisplayModeTest.java | 3 +- .../DisplayModes/CompareToXrandrTest.java | 3 +- .../DefaultPolicyChange_Swing.java | 17 ++++++----- .../java/awt/MenuBar/8007006/bug8007006.java | 5 ++-- .../FullscreenEnterEventTest.java | 6 ++-- .../HiDPIMouseClick/HiDPIRobotMouseClick.java | 7 +++-- .../HiDPIRobotScreenCaptureTest.java | 7 +++-- .../ScrollbarMouseWheelTest.java | 4 ++- .../FullScreenAfterSplash.java | 4 ++- .../unix/UnixMultiResolutionSplashTest.java | 4 ++- .../AutoScrollOnSelectAndAppend.java | 15 +++++----- .../OverScrollTest/OverScrollTest.java | 15 +++++----- .../OverScrollTest/OverScrollTest.java | 15 +++++----- .../GetScreenLocationTest.java | 3 +- .../SetWindowLocationByPlatformTest.java | 7 +++-- .../IOExceptionIfEncodedURLTest.java | 21 ++++++------- .../IOExceptionIfEncodedURLTest.sh | 1 + .../MultiResolutionDragImageTest.java | 3 +- .../HTMLDataFlavors/HTMLDataFlavorTest.java | 26 ++++++++-------- .../event/KeyEvent/8020209/bug8020209.java | 5 ++-- .../DeadKey/DeadKeyMacOSXInputText.java | 6 ++-- .../event/KeyEvent/DeadKey/deadKeyMacOSX.java | 5 ++-- .../awt/font/TextLayout/TestSinhalaChar.java | 4 ++- .../HiDPIPropertiesWindowsTest.java | 6 ++-- .../java/awt/im/6396526/IMLookAndFeel.java | 11 +++---- jdk/test/java/awt/im/8041990/bug8041990.java | 17 ++++++----- .../awt/image/MultiResolutionImageTest.java | 4 ++- .../multiresolution/Corrupted2XImageTest.java | 5 ++-- .../MultiResolutionToolkitImageTest.java | 4 ++- .../awt/keyboard/AllKeyCode/AllKeyCode.java | 15 +++++----- .../AltPlusNumberKeyCombinationsTest.java | 19 ++++++------ .../awt/print/PrinterJob/CheckPrivilege.java | 3 +- .../awt/print/PrinterJob/ExceptionTest.java | 1 + .../ImagePrinting/NullClipARGB.java | 3 +- .../java/awt/print/PrinterJob/Margins.java | 3 +- .../java/awt/print/PrinterJob/PaintText.java | 3 +- .../awt/print/PrinterJob/PrintCrashTest.java | 3 +- .../awt/print/PrinterJob/PrintTextPane.java | 15 +++++----- .../awt/print/PrinterJob/PrtException.java | 16 +++++----- jdk/test/javax/print/CheckDupFlavor.java | 6 ++-- jdk/test/javax/print/PrintSE/PrintSE.sh | 7 +++-- .../javax/print/attribute/AttributeTest.java | 6 ++-- .../print/attribute/GetCopiesSupported.java | 16 +++++----- .../print/attribute/SidesPageRangesTest.java | 9 ++++-- .../attribute/SupportedPrintableAreas.java | 5 ++-- .../JButton/8151303/PressedIconTest.java | 4 ++- .../6567433/UpdateUIRecursionTest.java | 6 ++-- .../swing/JComboBox/8019180/Test8019180.java | 5 ++-- .../8041909/ActionListenerExceptionTest.java | 14 +++++---- .../WindowsComboBoxSizeTest.java | 3 +- .../swing/JComponent/4337267/bug4337267.java | 5 ++-- .../swing/JComponent/8043610/bug8043610.java | 19 ++++++------ .../swing/JDialog/6639507/bug6639507.java | 15 ++++++---- .../JFileChooser/6713352/bug6713352.java | 18 ++++++----- .../JFileChooser/6817933/Test6817933.java | 6 ++-- .../JFileChooser/8010718/bug8010718.java | 4 ++- .../JFileChooser/8013442/Test8013442.java | 5 ++-- .../8152677/SelectAllFilesFilterTest.java | 5 ++-- .../swing/JFrame/8016356/bug8016356.java | 21 +++++++------ .../NSTexturedJFrame/NSTexturedJFrame.java | 4 ++- .../6288609/TestJInternalFrameDispose.java | 6 ++-- .../JInternalFrame/8075314/bug8075314.java | 21 ++++++------- .../8145060/TestJInternalFrameMinimize.java | 4 ++- .../8160248/JInternalFrameDraggingTest.java | 4 ++- .../DockIconRepaint/DockIconRepaint.java | 4 ++- .../swing/JInternalFrame/Test6325652.java | 5 ++-- .../JList/6567433/UpdateUIRecursionTest.java | 6 ++-- .../javax/swing/JList/8161483/Bug8161483.java | 9 +++--- .../javax/swing/JMenu/6538132/bug6538132.java | 22 ++++++++------ .../javax/swing/JMenu/8067346/bug8067346.java | 15 ++++++---- .../8139169/ScreenMenuBarInputTwice.java | 7 +++-- .../JMenuItem/8152981/MenuItemIconTest.java | 6 ++-- .../CloseOnMouseClickPropertyTest.java | 9 ++++-- .../ActionListenerCalledTwiceTest.java | 4 ++- .../ClickMenuTestManual.java | 7 +++-- .../swing/JOptionPane/8081019/bug8081019.java | 3 +- .../swing/JPopupMenu/6217905/bug6217905.java | 23 +++++++------- .../swing/JPopupMenu/7154841/bug7154841.java | 19 ++++++------ .../swing/JTabbedPane/7170310/bug7170310.java | 6 ++-- .../JTable/6567433/UpdateUIRecursionTest.java | 6 ++-- .../6567433/UpdateUIRecursionTest.java | 6 ++-- .../swing/JTextArea/6940863/bug6940863.java | 7 +++-- .../ScrollbarFlicker/ScrollFlickerTest.java | 6 ++-- .../JTree/6567433/UpdateUIRecursionTest.java | 6 ++-- .../ProgressMonitorEscapeKeyPress.java | 6 ++-- .../swing/Security/6938813/bug6938813.java | 3 +- .../ToolTipManager/7123767/bug7123767.java | 5 ++-- .../UnninstallUIMemoryLeaks.java | 5 ++-- .../plaf/aqua/CustomComboBoxFocusTest.java | 20 +++++++------ .../swing/plaf/basic/6866751/bug6866751.java | 17 ++++++----- .../BasicComboPopup/8154069/Bug8154069.java | 5 ++-- .../basic/BasicHTML/4960629/bug4960629.java | 18 ++++++----- .../plaf/basic/BasicLabelUI/bug7172652.java | 21 +++++++------ .../8041642/ScrollBarThumbVisibleTest.java | 16 +++++----- .../plaf/windows/6921687/bug6921687.java | 8 +++-- .../WrongAltProcessing.java | 15 ++++++---- .../swing/system/6799345/TestShutdown.java | 20 +++++++------ .../javax/swing/text/FlowView/LayoutTest.java | 18 ++++++----- .../GlyphPainter2/6427244/bug6427244.java | 20 +++++++------ .../8142966/SwingFontMetricsTest.java | 3 +- .../swing/text/View/8015853/bug8015853.java | 5 ++-- .../javax/swing/text/html/Test4783068.java | 12 ++++---- .../ImageConsumerUnregisterTest.java | 6 ++-- .../IAEforEmptyFrameTest.java | 6 ++-- .../sun/java2d/xrender/HugeGradientTest.java | 4 ++- 131 files changed, 735 insertions(+), 521 deletions(-) diff --git a/jdk/test/TEST.ROOT b/jdk/test/TEST.ROOT index 41cb9e82c8d..ccf4c295d14 100644 --- a/jdk/test/TEST.ROOT +++ b/jdk/test/TEST.ROOT @@ -10,9 +10,11 @@ # randomness tests. # # A "headful" test requires a graphical environment to meaningfully -# run. Tests that are not headful are "headless." +# run. Tests that are not headful are "headless". +# A test flagged with key "printer" requires a printer to succeed, else +# throws a PrinterException or the like. -keys=2d dnd i18n intermittent randomness headful +keys=2d dnd headful i18n intermittent printer randomness # Tests that must run in othervm mode othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/print javax/management com/sun/awt sun/awt sun/java2d sun/pisces javax/xml/jaxp/testng/validation java/lang/ProcessHandle diff --git a/jdk/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java b/jdk/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java index b5257e60957..9f87d7c5572 100644 --- a/jdk/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java +++ b/jdk/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,8 +21,9 @@ * questions. */ -/* +/** * @test + * @key headful * @bug 8007267 * @summary [macosx] com.apple.eawt.Application.setDefaultMenuBar is not working * @requires (os.family == "mac") diff --git a/jdk/test/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java b/jdk/test/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java index 26071d4bb7b..9971967bbb6 100644 --- a/jdk/test/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java +++ b/jdk/test/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,16 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -/* + +/** * @test + * @key headful * @bug 8158325 * @summary Memory leak in com.apple.laf.ScreenMenu: removed JMenuItems are still referenced * @requires (os.family == "mac") * @run main/timeout=300/othervm -Xmx16m ScreenMenuMemoryLeakTest */ + import java.awt.EventQueue; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; diff --git a/jdk/test/java/awt/Choice/ChoiceHiDpi/ChoiceTest.java b/jdk/test/java/awt/Choice/ChoiceHiDpi/ChoiceTest.java index fd23b478ca0..09e7e08dd8f 100644 --- a/jdk/test/java/awt/Choice/ChoiceHiDpi/ChoiceTest.java +++ b/jdk/test/java/awt/Choice/ChoiceHiDpi/ChoiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,8 +21,9 @@ * questions. */ -/* +/** * @test + * @key headful * @bug 8144594 * @summary HiDPI: awt.Choice looks improperly (Win 8) * @run main ChoiceTest diff --git a/jdk/test/java/awt/Desktop/DesktopGtkLoadTest/DesktopGtkLoadTest.java b/jdk/test/java/awt/Desktop/DesktopGtkLoadTest/DesktopGtkLoadTest.java index 5769f88938f..4b86476e7a0 100644 --- a/jdk/test/java/awt/Desktop/DesktopGtkLoadTest/DesktopGtkLoadTest.java +++ b/jdk/test/java/awt/Desktop/DesktopGtkLoadTest/DesktopGtkLoadTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,9 @@ * questions. */ -/* @test +/** + * @test + * @key headful * @bug 8157827 * @summary AWT_Desktop/Automated/Exceptions/BasicTest loads incorrect GTK * version when jdk.gtk.version=3 diff --git a/jdk/test/java/awt/Dialog/CloseDialog/CloseDialogTest.java b/jdk/test/java/awt/Dialog/CloseDialog/CloseDialogTest.java index 3053d793043..4db2d52e4ea 100644 --- a/jdk/test/java/awt/Dialog/CloseDialog/CloseDialogTest.java +++ b/jdk/test/java/awt/Dialog/CloseDialog/CloseDialogTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,11 +30,13 @@ import java.util.concurrent.atomic.AtomicReference; /** * @test + * @key headful * @bug 8043705 * @summary Can't exit color chooser dialog when running as an applet * @modules java.desktop/sun.awt * @run main CloseDialogTest */ + public class CloseDialogTest { private static volatile Frame frame; diff --git a/jdk/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java b/jdk/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java index 80c0dbb2f6c..7d32c5dd3d3 100644 --- a/jdk/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java +++ b/jdk/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,17 +21,19 @@ * questions. */ - /* - @test 8155740 - @summary See : Events: actionPerformed() method not - called when it is button is clicked (system load related) - @summary com.apple.junit.java.awt.Frame - @library ../../../regtesthelpers - @build VisibilityValidator - @build Util - @build Waypoint - @run main NestedModalDialogTest +/** + * @test 8155740 + * @key headful + * @summary See : Events: actionPerformed() method not + * called when it is button is clicked (system load related) + * @summary com.apple.junit.java.awt.Frame + * @library ../../../regtesthelpers + * @build VisibilityValidator + * @build Util + * @build Waypoint + * @run main NestedModalDialogTest */ + ////////////////////////////////////////////////////////////////////////////// // NestedModalDialogTest.java // The test launches a parent frame. From this parent frame it launches a modal diff --git a/jdk/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java b/jdk/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java index 853ff02e615..d41079d1f79 100644 --- a/jdk/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java +++ b/jdk/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,17 +21,19 @@ * questions. */ - /* - @test 8155740 - @summary See : Events: actionPerformed() method not - called when it is button is clicked (system load related) - @summary com.apple.junit.java.awt.Frame - @library ../../../regtesthelpers - @build VisibilityValidator - @build Util - @build Waypoint - @run main NestedModelessDialogTest +/** + * @test 8155740 + * @key headful + * @summary See : Events: actionPerformed() method not + * called when it is button is clicked (system load related) + * @summary com.apple.junit.java.awt.Frame + * @library ../../../regtesthelpers + * @build VisibilityValidator + * @build Util + * @build Waypoint + * @run main NestedModelessDialogTest -Xlog:exception */ + ///////////////////////////////////////////////////////////////////////////// // NestedModelessDialogTest.java // The test launches a parent frame. From this parent frame it launches a modal diff --git a/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java b/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java index 082681bd69b..daf9d29fbb4 100644 --- a/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java +++ b/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,24 +21,20 @@ * questions. */ -/* - @test - @bug 4980592 8171363 - @summary switching user in XP causes an NPE in - sun.awt.windows.WWindowPeer.displayChanged - @requires (os.family == "windows") - @modules java.desktop/java.awt.peer - @modules java.desktop/sun.awt.windows:open - @modules java.desktop/sun.awt - @author son@sparc.spb.su: area=embedded - @run main DisplayChangedTest - */ /** - * DisplayChangedTest.java - * - * summary: switching user in XP causes an NPE in - * sun.awt.windows.WWindowPeer.displayChanged + * @test + * @key headful + * @bug 4980592 8171363 + * @summary switching user in XP causes an NPE in + * sun.awt.windows.WWindowPeer.displayChanged + * @requires (os.family == "windows") + * @modules java.desktop/java.awt.peer + * @modules java.desktop/sun.awt.windows:open + * @modules java.desktop/sun.awt + * @author son@sparc.spb.su: area=embedded + * @run main DisplayChangedTest */ + import java.awt.Frame; import java.awt.Dialog; import java.awt.TextArea; diff --git a/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java b/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java index 5249dca3b14..e7fb0b8c6a0 100644 --- a/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java +++ b/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,22 +21,19 @@ * questions. */ -/* - @test - @bug 6345003 8171363 - @summary grab problems with EmbeddedFrame - @requires (os.family == "windows") - @modules java.desktop/java.awt.peer - @modules java.desktop/sun.awt - @modules java.desktop/sun.awt.windows:open - @author Oleg.Semenov@sun.com area=EmbeddedFrame - @run main EmbeddedFrameGrabTest - */ /** - * EmbeddedFrameGrabTest.java - * - * summary: grab problems with EmbeddedFrame + * @test + * @key headful + * @bug 6345003 8171363 + * @summary grab problems with EmbeddedFrame + * @requires (os.family == "windows") + * @modules java.desktop/java.awt.peer + * @modules java.desktop/sun.awt + * @modules java.desktop/sun.awt.windows:open + * @author Oleg.Semenov@sun.com area=EmbeddedFrame + * @run main EmbeddedFrameGrabTest */ + import java.awt.Frame; import java.awt.peer.FramePeer; import javax.swing.JComboBox; diff --git a/jdk/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html b/jdk/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html index 8f5e722fb68..1a1808de681 100644 --- a/jdk/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html +++ b/jdk/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html @@ -1,5 +1,5 @@ diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java index fe68c2fecfb..a1357bbfa33 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * AALOAD - Load reference from array *

    Stack: ..., arrayref, index -> value
    * - * @author M. Dahm + * @version $Id: AALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class AALOAD extends ArrayInstruction implements StackProducer { - /** Load reference from array - */ - public AALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.AALOAD); - } + + /** Load reference from array + */ + public AALOAD() { + super(com.sun.org.apache.bcel.internal.Const.AALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitAALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitAALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java index e68c8b853fc..9cdc13fe4a9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * AASTORE - Store into reference array *
    Stack: ..., arrayref, index, value -> ...
    * - * @author M. Dahm + * @version $Id: AASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class AASTORE extends ArrayInstruction implements StackConsumer { - /** Store into reference array - */ - public AASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.AASTORE); - } + + /** Store into reference array + */ + public AASTORE() { + super(com.sun.org.apache.bcel.internal.Const.AASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitAASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitAASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java index 777580befe6..2aa9bf6f7f8 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java @@ -21,41 +21,43 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ACONST_NULL - Push null reference *
    Stack: ... -> ..., null
    * - * @author M. Dahm + * @version $Id: ACONST_NULL.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class ACONST_NULL extends Instruction - implements PushInstruction, TypedInstruction { - /** - * Push null reference - */ - public ACONST_NULL() { - super(com.sun.org.apache.bcel.internal.Constants.ACONST_NULL, (short)1); - } +public class ACONST_NULL extends Instruction implements PushInstruction, TypedInstruction { - /** @return Type.NULL - */ - public Type getType(ConstantPoolGen cp) { - return Type.NULL; - } + /** + * Push null reference + */ + public ACONST_NULL() { + super(com.sun.org.apache.bcel.internal.Const.ACONST_NULL, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitACONST_NULL(this); - } + /** @return Type.NULL + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.NULL; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitACONST_NULL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java index 2b9d3d2ee3c..97892b0f88a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.Const; /** * ALOAD - Load reference from local variable *
    Stack: ... -> ..., objectref
    * - * @author M. Dahm + * @version $Id: ALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ALOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.ALOAD, com.sun.org.apache.bcel.internal.Constants.ALOAD_0); - } - /** Load reference from local variable - * @param n index of local variable - */ - public ALOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.ALOAD, com.sun.org.apache.bcel.internal.Constants.ALOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ALOAD() { + super(Const.ALOAD, Const.ALOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitALOAD(this); - } + /** Load reference from local variable + * @param n index of local variable + */ + public ALOAD(final int n) { + super(Const.ALOAD, Const.ALOAD_0, n); + } + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java index 71571a1bb19..93b2979257c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java @@ -21,61 +21,63 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * ANEWARRAY - Create new array of references *
    Stack: ..., count -> ..., arrayref
    * - * @author M. Dahm + * @version $Id: ANEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class ANEWARRAY extends CPInstruction - implements LoadClass, AllocationInstruction, ExceptionThrower, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ANEWARRAY() {} +public class ANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, + ExceptionThrower, StackConsumer, StackProducer { - public ANEWARRAY(int index) { - super(com.sun.org.apache.bcel.internal.Constants.ANEWARRAY, index); - } - - public Class[] getExceptions(){ - Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = - ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; - return cs; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitANEWARRAY(this); - } - - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - Type t = getType(cpg); - - if (t instanceof ArrayType){ - t = ((ArrayType) t).getBasicType(); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ANEWARRAY() { } - return (t instanceof ObjectType)? (ObjectType) t : null; - } + + public ANEWARRAY(final int index) { + super(com.sun.org.apache.bcel.internal.Const.ANEWARRAY, index); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, + ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitANEWARRAY(this); + } + + + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java index ec37dae4d3d..44119d3c84e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ARETURN - Return reference from method *
    Stack: ..., objectref -> <empty>
    * - * @author M. Dahm + * @version $Id: ARETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ARETURN extends ReturnInstruction { - /** - * Return reference from method - */ - public ARETURN() { - super(com.sun.org.apache.bcel.internal.Constants.ARETURN); - } + + /** + * Return reference from method + */ + public ARETURN() { + super(com.sun.org.apache.bcel.internal.Const.ARETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitARETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitARETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java index fdd575e2ea3..f2ea6fbb8e7 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java @@ -21,39 +21,46 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * ARRAYLENGTH - Get length of array *
    Stack: ..., arrayref -> ..., length
    * - * @author M. Dahm + * @version $Id: ARRAYLENGTH.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ARRAYLENGTH extends Instruction - implements ExceptionThrower, StackProducer { - /** Get length of array - */ - public ARRAYLENGTH() { - super(com.sun.org.apache.bcel.internal.Constants.ARRAYLENGTH, (short)1); - } + implements ExceptionThrower, StackProducer, StackConsumer /* since 6.0 */ { - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.NULL_POINTER_EXCEPTION }; - } + /** Get length of array + */ + public ARRAYLENGTH() { + super(com.sun.org.apache.bcel.internal.Const.ARRAYLENGTH, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitARRAYLENGTH(this); - } + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.NULL_POINTER_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitARRAYLENGTH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java index d2cc7f5e18d..f84d9e4f109 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java @@ -18,42 +18,46 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.Const; /** * ASTORE - Store reference into local variable *
    Stack ..., objectref -> ... 
    * - * @author M. Dahm + * @version $Id: ASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ASTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.ASTORE, com.sun.org.apache.bcel.internal.Constants.ASTORE_0); - } - /** Store reference into local variable - * @param n index of local variable - */ - public ASTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.ASTORE, com.sun.org.apache.bcel.internal.Constants.ASTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ASTORE() { + super(Const.ASTORE, Const.ASTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitASTORE(this); - } + /** + * Store reference into local variable + * + * @param n index of local variable + */ + public ASTORE(final int n) { + super(Const.ASTORE, Const.ASTORE_0, n); + } + + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + super.accept(v); + v.visitASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java index 226bf2c6ec9..695ed0d308c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java @@ -21,39 +21,46 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * ATHROW - Throw exception *
    Stack: ..., objectref -> objectref
    * - * @author M. Dahm + * @version $Id: ATHROW.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ATHROW extends Instruction implements UnconditionalBranch, ExceptionThrower { - /** - * Throw exception - */ - public ATHROW() { - super(com.sun.org.apache.bcel.internal.Constants.ATHROW, (short)1); - } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.THROWABLE }; - } + /** + * Throw exception + */ + public ATHROW() { + super(com.sun.org.apache.bcel.internal.Const.ATHROW, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitUnconditionalBranch(this); - v.visitExceptionThrower(this); - v.visitATHROW(this); - } + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.THROWABLE + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitUnconditionalBranch(this); + v.visitExceptionThrower(this); + v.visitATHROW(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java index 4944d892cdb..00effb7abdf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java @@ -21,10 +21,10 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote family of instructions that allocates space in the heap. * - * @author M. Dahm + * @version $Id: AllocationInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public interface AllocationInstruction {} +public interface AllocationInstruction { +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java new file mode 100644 index 00000000000..61c08bbe894 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java @@ -0,0 +1,90 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.AnnotationElementValue; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; + +/** + * @since 6.0 + */ +public class AnnotationElementValueGen extends ElementValueGen +{ + // For annotation element values, this is the annotation + private final AnnotationEntryGen a; + + public AnnotationElementValueGen(final AnnotationEntryGen a, final ConstantPoolGen cpool) + { + super(ANNOTATION, cpool); + this.a = a; + } + + public AnnotationElementValueGen(final int type, final AnnotationEntryGen annotation, + final ConstantPoolGen cpool) + { + super(type, cpool); + if (type != ANNOTATION) { + throw new RuntimeException( + "Only element values of type annotation can be built with this ctor - type specified: " + type); + } + this.a = annotation; + } + + public AnnotationElementValueGen(final AnnotationElementValue value, + final ConstantPoolGen cpool, final boolean copyPoolEntries) + { + super(ANNOTATION, cpool); + a = new AnnotationEntryGen(value.getAnnotationEntry(), cpool, copyPoolEntries); + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 type of value (ANNOTATION == '@') + a.dump(dos); + } + + @Override + public String stringifyValue() + { + throw new RuntimeException("Not implemented yet"); + } + + /** + * Return immutable variant of this AnnotationElementValueGen + */ + @Override + public ElementValue getElementValue() + { + return new AnnotationElementValue(super.getElementValueType(), + a.getAnnotation(), + getConstantPool().getConstantPool()); + } + + public AnnotationEntryGen getAnnotation() + { + return a; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java new file mode 100644 index 00000000000..2cc540efd22 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java @@ -0,0 +1,362 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValuePair; +import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleParameterAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleParameterAnnotations; + +/** + * @since 6.0 + */ +public class AnnotationEntryGen { + private int typeIndex; + + private List evs; + + private final ConstantPoolGen cpool; + + private boolean isRuntimeVisible = false; + + /** + * Here we are taking a fixed annotation of type Annotation and building a + * modifiable AnnotationGen object. If the pool passed in is for a different + * class file, then copyPoolEntries should have been passed as true as that + * will force us to do a deep copy of the annotation and move the cpool + * entries across. We need to copy the type and the element name value pairs + * and the visibility. + */ + public AnnotationEntryGen(final AnnotationEntry a, final ConstantPoolGen cpool, + final boolean copyPoolEntries) { + this.cpool = cpool; + if (copyPoolEntries) { + typeIndex = cpool.addUtf8(a.getAnnotationType()); + } else { + typeIndex = a.getAnnotationTypeIndex(); + } + isRuntimeVisible = a.isRuntimeVisible(); + evs = copyValues(a.getElementValuePairs(), cpool, copyPoolEntries); + } + + private List copyValues(final ElementValuePair[] in, final ConstantPoolGen cpool, + final boolean copyPoolEntries) { + final List out = new ArrayList<>(); + for (final ElementValuePair nvp : in) { + out.add(new ElementValuePairGen(nvp, cpool, copyPoolEntries)); + } + return out; + } + + private AnnotationEntryGen(final ConstantPoolGen cpool) { + this.cpool = cpool; + } + + /** + * Retrieve an immutable version of this AnnotationGen + */ + public AnnotationEntry getAnnotation() { + final AnnotationEntry a = new AnnotationEntry(typeIndex, cpool.getConstantPool(), + isRuntimeVisible); + for (final ElementValuePairGen element : evs) { + a.addElementNameValuePair(element.getElementNameValuePair()); + } + return a; + } + + public AnnotationEntryGen(final ObjectType type, + final List elements, final boolean vis, + final ConstantPoolGen cpool) { + this.cpool = cpool; + this.typeIndex = cpool.addUtf8(type.getSignature()); + evs = elements; + isRuntimeVisible = vis; + } + + public static AnnotationEntryGen read(final DataInput dis, + final ConstantPoolGen cpool, final boolean b) throws IOException { + final AnnotationEntryGen a = new AnnotationEntryGen(cpool); + a.typeIndex = dis.readUnsignedShort(); + final int elemValuePairCount = dis.readUnsignedShort(); + for (int i = 0; i < elemValuePairCount; i++) { + final int nidx = dis.readUnsignedShort(); + a.addElementNameValuePair(new ElementValuePairGen(nidx, + ElementValueGen.readElementValue(dis, cpool), cpool)); + } + a.isRuntimeVisible(b); + return a; + } + + public void dump(final DataOutputStream dos) throws IOException { + dos.writeShort(typeIndex); // u2 index of type name in cpool + dos.writeShort(evs.size()); // u2 element_value pair count + for (final ElementValuePairGen envp : evs) { + envp.dump(dos); + } + } + + public void addElementNameValuePair(final ElementValuePairGen evp) { + if (evs == null) { + evs = new ArrayList<>(); + } + evs.add(evp); + } + + public int getTypeIndex() { + return typeIndex; + } + + public final String getTypeSignature() { + // ConstantClass c = (ConstantClass)cpool.getConstant(typeIndex); + final ConstantUtf8 utf8 = (ConstantUtf8) cpool + .getConstant(typeIndex/* c.getNameIndex() */); + return utf8.getBytes(); + } + + public final String getTypeName() { + return getTypeSignature();// BCELBUG: Should I use this instead? + // Utility.signatureToString(getTypeSignature()); + } + + /** + * Returns list of ElementNameValuePair objects + */ + public List getValues() { + return evs; + } + + @Override + public String toString() { + final StringBuilder s = new StringBuilder(32); // CHECKSTYLE IGNORE MagicNumber + s.append("AnnotationGen:[").append(getTypeName()).append(" #").append(evs.size()).append(" {"); + for (int i = 0; i < evs.size(); i++) { + s.append(evs.get(i)); + if (i + 1 < evs.size()) { + s.append(","); + } + } + s.append("}]"); + return s.toString(); + } + + public String toShortString() { + final StringBuilder s = new StringBuilder(); + s.append("@").append(getTypeName()).append("("); + for (int i = 0; i < evs.size(); i++) { + s.append(evs.get(i)); + if (i + 1 < evs.size()) { + s.append(","); + } + } + s.append(")"); + return s.toString(); + } + + private void isRuntimeVisible(final boolean b) { + isRuntimeVisible = b; + } + + public boolean isRuntimeVisible() { + return isRuntimeVisible; + } + + + /** + * Converts a list of AnnotationGen objects into a set of attributes + * that can be attached to the class file. + * + * @param cp The constant pool gen where we can create the necessary name refs + * @param annotationEntryGens An array of AnnotationGen objects + */ + static Attribute[] getAnnotationAttributes(final ConstantPoolGen cp, final AnnotationEntryGen[] annotationEntryGens) { + if (annotationEntryGens.length == 0) { + return new Attribute[0]; + } + + try { + int countVisible = 0; + int countInvisible = 0; + + // put the annotations in the right output stream + for (final AnnotationEntryGen a : annotationEntryGens) { + if (a.isRuntimeVisible()) { + countVisible++; + } else { + countInvisible++; + } + } + + final ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); + final ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); + try (DataOutputStream rvaDos = new DataOutputStream(rvaBytes); + DataOutputStream riaDos = new DataOutputStream(riaBytes)) { + + rvaDos.writeShort(countVisible); + riaDos.writeShort(countInvisible); + + // put the annotations in the right output stream + for (final AnnotationEntryGen a : annotationEntryGens) { + if (a.isRuntimeVisible()) { + a.dump(rvaDos); + } else { + a.dump(riaDos); + } + } + } + + final byte[] rvaData = rvaBytes.toByteArray(); + final byte[] riaData = riaBytes.toByteArray(); + + int rvaIndex = -1; + int riaIndex = -1; + + if (rvaData.length > 2) { + rvaIndex = cp.addUtf8("RuntimeVisibleAnnotations"); + } + if (riaData.length > 2) { + riaIndex = cp.addUtf8("RuntimeInvisibleAnnotations"); + } + + final List newAttributes = new ArrayList<>(); + if (rvaData.length > 2) { + newAttributes.add( + new RuntimeVisibleAnnotations(rvaIndex, rvaData.length, + new DataInputStream(new ByteArrayInputStream(rvaData)), cp.getConstantPool())); + } + if (riaData.length > 2) { + newAttributes.add( + new RuntimeInvisibleAnnotations(riaIndex, riaData.length, + new DataInputStream(new ByteArrayInputStream(riaData)), cp.getConstantPool())); + } + + return newAttributes.toArray(new Attribute[newAttributes.size()]); + } catch (final IOException e) { + System.err.println("IOException whilst processing annotations. " + + e.getMessage()); + } + return null; + } + + + /** + * Annotations against a class are stored in one of four attribute kinds: + * - RuntimeVisibleParameterAnnotations + * - RuntimeInvisibleParameterAnnotations + */ + static Attribute[] getParameterAnnotationAttributes( + final ConstantPoolGen cp, + final List[] /*Array of lists, array size depends on #params */vec) { + final int[] visCount = new int[vec.length]; + int totalVisCount = 0; + final int[] invisCount = new int[vec.length]; + int totalInvisCount = 0; + try { + for (int i = 0; i < vec.length; i++) { + if (vec[i] != null) { + for (final AnnotationEntryGen element : vec[i]) { + if (element.isRuntimeVisible()) { + visCount[i]++; + totalVisCount++; + } else { + invisCount[i]++; + totalInvisCount++; + } + } + } + } + // Lets do the visible ones + final ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); + try (DataOutputStream rvaDos = new DataOutputStream(rvaBytes)) { + rvaDos.writeByte(vec.length); // First goes number of parameters + for (int i = 0; i < vec.length; i++) { + rvaDos.writeShort(visCount[i]); + if (visCount[i] > 0) { + for (final AnnotationEntryGen element : vec[i]) { + if (element.isRuntimeVisible()) { + element.dump(rvaDos); + } + } + } + } + } + // Lets do the invisible ones + final ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); + try (DataOutputStream riaDos = new DataOutputStream(riaBytes)) { + riaDos.writeByte(vec.length); // First goes number of parameters + for (int i = 0; i < vec.length; i++) { + riaDos.writeShort(invisCount[i]); + if (invisCount[i] > 0) { + for (final AnnotationEntryGen element : vec[i]) { + if (!element.isRuntimeVisible()) { + element.dump(riaDos); + } + } + } + } + } + final byte[] rvaData = rvaBytes.toByteArray(); + final byte[] riaData = riaBytes.toByteArray(); + int rvaIndex = -1; + int riaIndex = -1; + if (totalVisCount > 0) { + rvaIndex = cp.addUtf8("RuntimeVisibleParameterAnnotations"); + } + if (totalInvisCount > 0) { + riaIndex = cp.addUtf8("RuntimeInvisibleParameterAnnotations"); + } + final List newAttributes = new ArrayList<>(); + if (totalVisCount > 0) { + newAttributes + .add(new RuntimeVisibleParameterAnnotations(rvaIndex, + rvaData.length, + new DataInputStream(new ByteArrayInputStream(rvaData)), + cp.getConstantPool())); + } + if (totalInvisCount > 0) { + newAttributes + .add(new RuntimeInvisibleParameterAnnotations(riaIndex, + riaData.length, + new DataInputStream(new ByteArrayInputStream(riaData)), + cp.getConstantPool())); + } + return newAttributes.toArray(new Attribute[newAttributes.size()]); + } catch (final IOException e) { + System.err.println("IOException whilst processing parameter annotations." + + e.getMessage()); + } + return null; + } + +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java index becf27342d0..e44e49c1839 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java @@ -21,53 +21,80 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; + /** * Super class for the family of arithmetic instructions. * - * @author M. Dahm + * @version $Id: ArithmeticInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class ArithmeticInstruction extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ArithmeticInstruction() {} +public abstract class ArithmeticInstruction extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - /** - * @param opcode of instruction - */ - protected ArithmeticInstruction(short opcode) { - super(opcode, (short)1); - } - - /** @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - switch(opcode) { - case Constants.DADD: case Constants.DDIV: case Constants.DMUL: - case Constants.DNEG: case Constants.DREM: case Constants.DSUB: - return Type.DOUBLE; - - case Constants.FADD: case Constants.FDIV: case Constants.FMUL: - case Constants.FNEG: case Constants.FREM: case Constants.FSUB: - return Type.FLOAT; - - case Constants.IADD: case Constants.IAND: case Constants.IDIV: - case Constants.IMUL: case Constants.INEG: case Constants.IOR: case Constants.IREM: - case Constants.ISHL: case Constants.ISHR: case Constants.ISUB: - case Constants.IUSHR: case Constants.IXOR: - return Type.INT; - - case Constants.LADD: case Constants.LAND: case Constants.LDIV: - case Constants.LMUL: case Constants.LNEG: case Constants.LOR: case Constants.LREM: - case Constants.LSHL: case Constants.LSHR: case Constants.LSUB: - case Constants.LUSHR: case Constants.LXOR: - return Type.LONG; - - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ArithmeticInstruction() { + } + + + /** + * @param opcode of instruction + */ + protected ArithmeticInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + /** @return type associated with the instruction + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + final short _opcode = super.getOpcode(); + switch (_opcode) { + case Const.DADD: + case Const.DDIV: + case Const.DMUL: + case Const.DNEG: + case Const.DREM: + case Const.DSUB: + return Type.DOUBLE; + case Const.FADD: + case Const.FDIV: + case Const.FMUL: + case Const.FNEG: + case Const.FREM: + case Const.FSUB: + return Type.FLOAT; + case Const.IADD: + case Const.IAND: + case Const.IDIV: + case Const.IMUL: + case Const.INEG: + case Const.IOR: + case Const.IREM: + case Const.ISHL: + case Const.ISHR: + case Const.ISUB: + case Const.IUSHR: + case Const.IXOR: + return Type.INT; + case Const.LADD: + case Const.LAND: + case Const.LDIV: + case Const.LMUL: + case Const.LNEG: + case Const.LOR: + case Const.LREM: + case Const.LSHL: + case Const.LSHR: + case Const.LSUB: + case Const.LUSHR: + case Const.LXOR: + return Type.LONG; + default: // Never reached + throw new ClassGenException("Unknown type " + _opcode); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java new file mode 100644 index 00000000000..699b6560cb6 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java @@ -0,0 +1,131 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.sun.org.apache.bcel.internal.classfile.ArrayElementValue; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; + +/** + * @since 6.0 + */ +public class ArrayElementValueGen extends ElementValueGen +{ + // J5TODO: Should we make this an array or a list? A list would be easier to + // modify ... + private final List evalues; + + public ArrayElementValueGen(final ConstantPoolGen cp) + { + super(ARRAY, cp); + evalues = new ArrayList<>(); + } + + public ArrayElementValueGen(final int type, final ElementValue[] datums, + final ConstantPoolGen cpool) + { + super(type, cpool); + if (type != ARRAY) { + throw new RuntimeException( + "Only element values of type array can be built with this ctor - type specified: " + type); + } + this.evalues = new ArrayList<>(); + for (final ElementValue datum : datums) { + evalues.add(ElementValueGen.copy(datum, cpool, true)); + } + } + + /** + * Return immutable variant of this ArrayElementValueGen + */ + @Override + public ElementValue getElementValue() + { + final ElementValue[] immutableData = new ElementValue[evalues.size()]; + int i = 0; + for (final ElementValueGen element : evalues) { + immutableData[i++] = element.getElementValue(); + } + return new ArrayElementValue(super.getElementValueType(), + immutableData, + getConstantPool().getConstantPool()); + } + + /** + * @param value + * @param cpool + */ + public ArrayElementValueGen(final ArrayElementValue value, final ConstantPoolGen cpool, + final boolean copyPoolEntries) + { + super(ARRAY, cpool); + evalues = new ArrayList<>(); + final ElementValue[] in = value.getElementValuesArray(); + for (final ElementValue element : in) { + evalues.add(ElementValueGen.copy(element, cpool, copyPoolEntries)); + } + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 type of value (ARRAY == '[') + dos.writeShort(evalues.size()); + for (final ElementValueGen element : evalues) { + element.dump(dos); + } + } + + @Override + public String stringifyValue() + { + final StringBuilder sb = new StringBuilder(); + sb.append("["); + String comma = ""; + for (final ElementValueGen element : evalues) { + sb.append(comma); + comma = ","; + sb.append(element.stringifyValue()); + } + sb.append("]"); + return sb.toString(); + } + + public List getElementValues() + { + return evalues; + } + + public int getElementValuesSize() + { + return evalues.size(); + } + + public void addElement(final ElementValueGen gen) + { + evalues.add(gen); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java index 62e90a44b01..c43a3592533 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java @@ -21,53 +21,70 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * Super class for instructions dealing with array access such as IALOAD. * - * @author M. Dahm + * @version $Id: ArrayInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class ArrayInstruction extends Instruction - implements ExceptionThrower, TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ArrayInstruction() {} +public abstract class ArrayInstruction extends Instruction implements ExceptionThrower, + TypedInstruction { - /** - * @param opcode of instruction - */ - protected ArrayInstruction(short opcode) { - super(opcode, (short)1); - } - - public Class[] getExceptions() { - return com.sun.org.apache.bcel.internal.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - } - - /** @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - switch(opcode) { - case com.sun.org.apache.bcel.internal.Constants.IALOAD: case com.sun.org.apache.bcel.internal.Constants.IASTORE: - return Type.INT; - case com.sun.org.apache.bcel.internal.Constants.CALOAD: case com.sun.org.apache.bcel.internal.Constants.CASTORE: - return Type.CHAR; - case com.sun.org.apache.bcel.internal.Constants.BALOAD: case com.sun.org.apache.bcel.internal.Constants.BASTORE: - return Type.BYTE; - case com.sun.org.apache.bcel.internal.Constants.SALOAD: case com.sun.org.apache.bcel.internal.Constants.SASTORE: - return Type.SHORT; - case com.sun.org.apache.bcel.internal.Constants.LALOAD: case com.sun.org.apache.bcel.internal.Constants.LASTORE: - return Type.LONG; - case com.sun.org.apache.bcel.internal.Constants.DALOAD: case com.sun.org.apache.bcel.internal.Constants.DASTORE: - return Type.DOUBLE; - case com.sun.org.apache.bcel.internal.Constants.FALOAD: case com.sun.org.apache.bcel.internal.Constants.FASTORE: - return Type.FLOAT; - case com.sun.org.apache.bcel.internal.Constants.AALOAD: case com.sun.org.apache.bcel.internal.Constants.AASTORE: - return Type.OBJECT; - - default: throw new ClassGenException("Oops: unknown case in switch" + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ArrayInstruction() { + } + + + /** + * @param opcode of instruction + */ + protected ArrayInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_ARRAY_EXCEPTION); + } + + + /** @return type associated with the instruction + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + final short _opcode = super.getOpcode(); + switch (_opcode) { + case com.sun.org.apache.bcel.internal.Const.IALOAD: + case com.sun.org.apache.bcel.internal.Const.IASTORE: + return Type.INT; + case com.sun.org.apache.bcel.internal.Const.CALOAD: + case com.sun.org.apache.bcel.internal.Const.CASTORE: + return Type.CHAR; + case com.sun.org.apache.bcel.internal.Const.BALOAD: + case com.sun.org.apache.bcel.internal.Const.BASTORE: + return Type.BYTE; + case com.sun.org.apache.bcel.internal.Const.SALOAD: + case com.sun.org.apache.bcel.internal.Const.SASTORE: + return Type.SHORT; + case com.sun.org.apache.bcel.internal.Const.LALOAD: + case com.sun.org.apache.bcel.internal.Const.LASTORE: + return Type.LONG; + case com.sun.org.apache.bcel.internal.Const.DALOAD: + case com.sun.org.apache.bcel.internal.Const.DASTORE: + return Type.DOUBLE; + case com.sun.org.apache.bcel.internal.Const.FALOAD: + case com.sun.org.apache.bcel.internal.Const.FASTORE: + return Type.FLOAT; + case com.sun.org.apache.bcel.internal.Const.AALOAD: + case com.sun.org.apache.bcel.internal.Const.AASTORE: + return Type.OBJECT; + default: + throw new ClassGenException("Oops: unknown case in switch" + _opcode); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java index 035602d8351..8d7b57ebdbc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java @@ -18,106 +18,111 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; /** * Denotes array type, such as int[][] * - * @author M. Dahm + * @version $Id: ArrayType.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public final class ArrayType extends ReferenceType { - private int dimensions; - private Type basic_type; - /** - * Convenience constructor for array type, e.g. int[] - * - * @param type array type, e.g. T_INT - */ - public ArrayType(byte type, int dimensions) { - this(BasicType.getType(type), dimensions); - } + private int dimensions; + private Type basic_type; - /** - * Convenience constructor for reference array type, e.g. Object[] - * - * @param class_name complete name of class (java.lang.String, e.g.) - */ - public ArrayType(String class_name, int dimensions) { - this(new ObjectType(class_name), dimensions); - } - - /** - * Constructor for array of given type - * - * @param type type of array (may be an array itself) - */ - public ArrayType(Type type, int dimensions) { - super(Constants.T_ARRAY, ""); - - if((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) - throw new ClassGenException("Invalid number of dimensions: " + dimensions); - - switch(type.getType()) { - case Constants.T_ARRAY: - ArrayType array = (ArrayType)type; - this.dimensions = dimensions + array.dimensions; - basic_type = array.basic_type; - break; - - case Constants.T_VOID: - throw new ClassGenException("Invalid type: void[]"); - - default: // Basic type or reference - this.dimensions = dimensions; - basic_type = type; - break; + /** + * Convenience constructor for array type, e.g. int[] + * + * @param type array type, e.g. T_INT + */ + public ArrayType(final byte type, final int dimensions) { + this(BasicType.getType(type), dimensions); } - StringBuffer buf = new StringBuffer(); - for(int i=0; i < this.dimensions; i++) - buf.append('['); + /** + * Convenience constructor for reference array type, e.g. Object[] + * + * @param class_name complete name of class (java.lang.String, e.g.) + */ + public ArrayType(final String class_name, final int dimensions) { + this(ObjectType.getInstance(class_name), dimensions); + } - buf.append(basic_type.getSignature()); + /** + * Constructor for array of given type + * + * @param type type of array (may be an array itself) + */ + public ArrayType(final Type type, final int dimensions) { + super(Const.T_ARRAY, ""); + if ((dimensions < 1) || (dimensions > Const.MAX_BYTE)) { + throw new ClassGenException("Invalid number of dimensions: " + dimensions); + } + switch (type.getType()) { + case Const.T_ARRAY: + final ArrayType array = (ArrayType) type; + this.dimensions = dimensions + array.dimensions; + basic_type = array.basic_type; + break; + case Const.T_VOID: + throw new ClassGenException("Invalid type: void[]"); + default: // Basic type or reference + this.dimensions = dimensions; + basic_type = type; + break; + } + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < this.dimensions; i++) { + buf.append('['); + } + buf.append(basic_type.getSignature()); + super.setSignature(buf.toString()); + } - signature = buf.toString(); - } + /** + * @return basic type of array, i.e., for int[][][] the basic type is int + */ + public Type getBasicType() { + return basic_type; + } - /** - * @return basic type of array, i.e., for int[][][] the basic type is int - */ - public Type getBasicType() { - return basic_type; - } + /** + * @return element type of array, i.e., for int[][][] the element type is + * int[][] + */ + public Type getElementType() { + if (dimensions == 1) { + return basic_type; + } + return new ArrayType(basic_type, dimensions - 1); + } - /** - * @return element type of array, i.e., for int[][][] the element type is int[][] - */ - public Type getElementType() { - if(dimensions == 1) - return basic_type; - else - return new ArrayType(basic_type, dimensions - 1); - } + /** + * @return number of dimensions of array + */ + public int getDimensions() { + return dimensions; + } - /** @return number of dimensions of array - */ - public int getDimensions() { return dimensions; } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return basic_type.hashCode() ^ dimensions; + } - /** @return a hash code value for the object. - */ - public int hashCode() { return basic_type.hashCode() ^ dimensions; } - - /** @return true if both type objects refer to the same array type. - */ - public boolean equals(Object type) { - if(type instanceof ArrayType) { - ArrayType array = (ArrayType)type; - return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); - } else - return false; - } + /** + * @return true if both type objects refer to the same array type. + */ + @Override + public boolean equals(final Object _type) { + if (_type instanceof ArrayType) { + final ArrayType array = (ArrayType) _type; + return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); + } + return false; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java index b198401b455..14f0115f9ae 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java @@ -18,37 +18,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** * BALOAD - Load byte or boolean from array *
    Stack: ..., arrayref, index -> ..., value
    * - * @author M. Dahm + * @version $Id: BALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class BALOAD extends ArrayInstruction implements StackProducer { - /** Load byte or boolean from array - */ - public BALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.BALOAD); - } + /** + * Load byte or boolean from array + */ + public BALOAD() { + super(com.sun.org.apache.bcel.internal.Const.BALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitBALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitBALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java index 67a5fab11a3..cd1bb9f3a7b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java @@ -18,37 +18,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** - * BASTORE - Store into byte or boolean array + * BASTORE - Store into byte or boolean array *
    Stack: ..., arrayref, index, value -> ...
    * - * @author M. Dahm + * @version $Id: BASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class BASTORE extends ArrayInstruction implements StackConsumer { - /** Store byte or boolean into array - */ - public BASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.BASTORE); - } + /** + * Store byte or boolean into array + */ + public BASTORE() { + super(com.sun.org.apache.bcel.internal.Const.BASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitBASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitBASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java index bb4e12f858a..c55abd5d900 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java @@ -17,11 +17,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import java.io.DataOutputStream; +import java.io.IOException; -import java.io.*; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -29,69 +29,80 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; * *
    Stack: ... -> ..., value
    * - * @author M. Dahm + * @version $Id: BIPUSH.java 1747278 2016-06-07 17:28:43Z britter $ */ public class BIPUSH extends Instruction implements ConstantPushInstruction { - private byte b; - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - BIPUSH() {} + private byte b; - /** Push byte on stack - */ - public BIPUSH(byte b) { - super(com.sun.org.apache.bcel.internal.Constants.BIPUSH, (short)2); - this.b = b; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + BIPUSH() { + } - /** - * Dump instruction as byte code to stream out. - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - out.writeByte(b); - } + /** + * Push byte on stack + */ + public BIPUSH(final byte b) { + super(com.sun.org.apache.bcel.internal.Const.BIPUSH, (short) 2); + this.b = b; + } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + b; - } + /** + * Dump instruction as byte code to stream out. + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + super.dump(out); + out.writeByte(b); + } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - length = 2; - b = bytes.readByte(); - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + b; + } - public Number getValue() { return Integer.valueOf(b); } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.setLength(2); + b = bytes.readByte(); + } - /** @return Type.BYTE - */ - public Type getType(ConstantPoolGen cp) { - return Type.BYTE; - } + @Override + public Number getValue() { + return Integer.valueOf(b); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitBIPUSH(this); - } + /** + * @return Type.BYTE + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.BYTE; + } + + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitBIPUSH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java index 9715ea5324e..be1ac7afb7f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java @@ -18,29 +18,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** * BREAKPOINT, JVM dependent, ignored by default * - * @author M. Dahm + * @version $Id: BREAKPOINT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class BREAKPOINT extends Instruction { - public BREAKPOINT() { - super(com.sun.org.apache.bcel.internal.Constants.BREAKPOINT, (short)1); - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitBREAKPOINT(this); - } + public BREAKPOINT() { + super(com.sun.org.apache.bcel.internal.Const.BREAKPOINT, (short) 1); + } + + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitBREAKPOINT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java index 00a5def2646..ab432a82f61 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java @@ -18,57 +18,69 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; /** * Denotes basic type such as int. * - * @author M. Dahm + * @version $Id: BasicType.java 1747278 2016-06-07 17:28:43Z britter $ */ public final class BasicType extends Type { - /** - * Constructor for basic types such as int, long, `void' - * - * @param type one of T_INT, T_BOOLEAN, ..., T_VOID - * @see com.sun.org.apache.bcel.internal.Constants - */ - BasicType(byte type) { - super(type, Constants.SHORT_TYPE_NAMES[type]); - if((type < Constants.T_BOOLEAN) || (type > Constants.T_VOID)) - throw new ClassGenException("Invalid type: " + type); - } - - public static final BasicType getType(byte type) { - switch(type) { - case Constants.T_VOID: return VOID; - case Constants.T_BOOLEAN: return BOOLEAN; - case Constants.T_BYTE: return BYTE; - case Constants.T_SHORT: return SHORT; - case Constants.T_CHAR: return CHAR; - case Constants.T_INT: return INT; - case Constants.T_LONG: return LONG; - case Constants.T_DOUBLE: return DOUBLE; - case Constants.T_FLOAT: return FLOAT; - - default: - throw new ClassGenException("Invalid type: " + type); + /** + * Constructor for basic types such as int, long, `void' + * + * @param type one of T_INT, T_BOOLEAN, ..., T_VOID + * @see Const + */ + BasicType(final byte type) { + super(type, Const.getShortTypeName(type)); + if ((type < Const.T_BOOLEAN) || (type > Const.T_VOID)) { + throw new ClassGenException("Invalid type: " + type); + } } - } - /** @return true if both type objects refer to the same type - */ - @Override - public boolean equals(Object type) { - return (type instanceof BasicType)? - ((BasicType)type).type == this.type : false; - } + // @since 6.0 no longer final + public static BasicType getType(final byte type) { + switch (type) { + case Const.T_VOID: + return VOID; + case Const.T_BOOLEAN: + return BOOLEAN; + case Const.T_BYTE: + return BYTE; + case Const.T_SHORT: + return SHORT; + case Const.T_CHAR: + return CHAR; + case Const.T_INT: + return INT; + case Const.T_LONG: + return LONG; + case Const.T_DOUBLE: + return DOUBLE; + case Const.T_FLOAT: + return FLOAT; + default: + throw new ClassGenException("Invalid type: " + type); + } + } - @Override - public int hashCode() { - return type; - } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return super.getType(); + } + + /** + * @return true if both type objects refer to the same type + */ + @Override + public boolean equals(final Object _type) { + return (_type instanceof BasicType) ? ((BasicType) _type).getType() == this.getType() : false; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java index 3ab01f5d821..ebf32b0d47d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java @@ -18,100 +18,110 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** * BranchHandle is returned by specialized InstructionList.append() whenever a * BranchInstruction is appended. This is useful when the target of this - * instruction is not known at time of creation and must be set later - * via setTarget(). + * instruction is not known at time of creation and must be set later via + * setTarget(). * * @see InstructionHandle * @see Instruction * @see InstructionList - * @author M. Dahm + * @version $Id: BranchHandle.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public final class BranchHandle extends InstructionHandle { - private BranchInstruction bi; // An alias in fact, but saves lots of casts - private BranchHandle(BranchInstruction i) { - super(i); - bi = i; - } + // This is also a cache in case the InstructionHandle#swapInstruction() method is used + // See BCEL-273 + private BranchInstruction bi; // An alias in fact, but saves lots of casts - /** Factory methods. - */ - private static BranchHandle bh_list = null; // List of reusable handles - - static final BranchHandle getBranchHandle(BranchInstruction i) { - if(bh_list == null) - return new BranchHandle(i); - else { - BranchHandle bh = bh_list; - bh_list = (BranchHandle)bh.next; - - bh.setInstruction(i); - - return bh; + private BranchHandle(final BranchInstruction i) { + super(i); + bi = i; } - } - /** Handle adds itself to the list of resuable handles. - */ - protected void addHandle() { - next = bh_list; - bh_list = this; - } + /** + * Factory methods. + */ + private static BranchHandle bh_list = null; // List of reusable handles - /* Override InstructionHandle methods: delegate to branch instruction. - * Through this overriding all access to the private i_position field should - * be prevented. - */ - public int getPosition() { return bi.position; } + static BranchHandle getBranchHandle(final BranchInstruction i) { + if (bh_list == null) { + return new BranchHandle(i); + } + final BranchHandle bh = bh_list; + bh_list = (BranchHandle) bh.getNext(); + bh.setInstruction(i); + return bh; + } - void setPosition(int pos) { - i_position = bi.position = pos; - } + /** + * Handle adds itself to the list of resuable handles. + */ + @Override + protected void addHandle() { + super.setNext(bh_list); + bh_list = this; + } - protected int updatePosition(int offset, int max_offset) { - int x = bi.updatePosition(offset, max_offset); - i_position = bi.position; - return x; - } - /** - * Pass new target to instruction. - */ - public void setTarget(InstructionHandle ih) { - bi.setTarget(ih); - } + /* Override InstructionHandle methods: delegate to branch instruction. + * Through this overriding all access to the private i_position field should + * be prevented. + */ + @Override + public int getPosition() { + return bi.getPosition(); + } - /** - * Update target of instruction. - */ - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - bi.updateTarget(old_ih, new_ih); - } + @Override + void setPosition(final int pos) { + // Original code: i_position = bi.position = pos; + bi.setPosition(pos); + super.setPosition(pos); + } - /** - * @return target of instruction. - */ - public InstructionHandle getTarget() { - return bi.getTarget(); - } + @Override + protected int updatePosition(final int offset, final int max_offset) { + final int x = bi.updatePosition(offset, max_offset); + super.setPosition(bi.getPosition()); + return x; + } - /** - * Set new contents. Old instruction is disposed and may not be used anymore. - */ - public void setInstruction(Instruction i) { - super.setInstruction(i); + /** + * Pass new target to instruction. + */ + public void setTarget(final InstructionHandle ih) { + bi.setTarget(ih); + } - if(!(i instanceof BranchInstruction)) - throw new ClassGenException("Assigning " + i + - " to branch handle which is not a branch instruction"); + /** + * Update target of instruction. + */ + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + bi.updateTarget(old_ih, new_ih); + } - bi = (BranchInstruction)i; - } + /** + * @return target of instruction. + */ + public InstructionHandle getTarget() { + return bi.getTarget(); + } + + /** + * Set new contents. Old instruction is disposed and may not be used + * anymore. + */ + @Override // This is only done in order to apply the additional type check; could be merged with super impl. + public void setInstruction(final Instruction i) { // TODO could be package-protected? + super.setInstruction(i); + if (!(i instanceof BranchInstruction)) { + throw new ClassGenException("Assigning " + i + + " to branch handle which is not a branch instruction"); + } + bi = (BranchInstruction) i; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java index 77f5a86af57..c1d92d38f68 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java @@ -18,216 +18,246 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import java.io.DataOutputStream; +import java.io.IOException; -import java.io.*; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** - * Abstract super class for branching instructions like GOTO, IFEQ, etc.. - * Branch instructions may have a variable length, namely GOTO, JSR, - * LOOKUPSWITCH and TABLESWITCH. + * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch + * instructions may have a variable length, namely GOTO, JSR, LOOKUPSWITCH and + * TABLESWITCH. * * @see InstructionList - * @author M. Dahm + * @version $Id: BranchInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public abstract class BranchInstruction extends Instruction implements InstructionTargeter { - protected int index; // Branch target relative to this instruction - protected InstructionHandle target; // Target object in instruction list - protected int position; // Byte code offset - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - BranchInstruction() {} + private int index; // Branch target relative to this instruction + private InstructionHandle target; // Target object in instruction list + private int position; // Byte code offset - /** Common super constructor - * @param opcodee Instruction opcode - * @param target instruction to branch to - */ - protected BranchInstruction(short opcode, InstructionHandle target) { - super(opcode, (short)3); - setTarget(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + BranchInstruction() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); + /** + * Common super constructor + * + * @param opcode Instruction opcode + * @param target instruction to branch to + */ + protected BranchInstruction(final short opcode, final InstructionHandle target) { + super(opcode, (short) 3); + setTarget(target); + } - index = getTargetOffset(); - - if(Math.abs(index) >= 32767) // too large for short - throw new ClassGenException("Branch target offset too large for short"); - - out.writeShort(index); // May be negative, i.e., point backwards - } - - /** - * @param target branch target - * @return the offset to `target' relative to this instruction - */ - protected int getTargetOffset(InstructionHandle target) { - if(target == null) - throw new ClassGenException("Target of " + super.toString(true) + - " is invalid null handle"); - - int t = target.getPosition(); - - if(t < 0) - throw new ClassGenException("Invalid branch target position offset for " + - super.toString(true) + ":" + t + ":" + target); - - return t - position; - } - - /** - * @return the offset to this instruction's target - */ - protected int getTargetOffset() { return getTargetOffset(target); } - - /** - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition(int offset, int max_offset) { - position += offset; - return 0; - } - - /** - * Long output format: - * - * <position in byte code> - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" - * "<"<target instruction>">" "@"<branch target offset> - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - @Override - public String toString(boolean verbose) { - String s = super.toString(verbose); - String t = "null"; - - if(verbose) { - if(target != null) { - if(target.getInstruction() == this) - t = ""; - else if(target.getInstruction() == null) - t = ""; - else - t = target.getInstruction().toString(false); // Avoid circles - } - } else { - if(target != null) { + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); index = getTargetOffset(); - t = "" + (index + position); - } + if (!isValidShort(index)) { + throw new ClassGenException("Branch target offset too large for short: " + index); + } + out.writeShort(index); // May be negative, i.e., point backwards } - return s + " -> " + t; - } - - /** - * Read needed data (e.g. index) from file. Conversion to a InstructionHandle - * is done in InstructionList(byte[]). - * - * @param bytes input stream - * @param wide wide prefix? - * @see InstructionList - */ - @Override - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - length = 3; - index = bytes.readShort(); - } - - /** - * @return target offset in byte code - */ - public final int getIndex() { return index; } - - /** - * @return target of branch instruction - */ - public InstructionHandle getTarget() { return target; } - - /** - * Set branch target - * @param target branch target - */ - public final void setTarget(InstructionHandle target) { - notifyTargetChanging(this.target, this); - this.target = target; - notifyTargetChanged(this.target, this); - } - - /** - * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen. - * Must be called before the target is actually changed in the - * InstructionTargeter. - */ - static void notifyTargetChanging(InstructionHandle old_ih, - InstructionTargeter t) { - if(old_ih != null) { - old_ih.removeTargeter(t); + /** + * @param _target branch target + * @return the offset to `target' relative to this instruction + */ + protected int getTargetOffset(final InstructionHandle _target) { + if (_target == null) { + throw new ClassGenException("Target of " + super.toString(true) + + " is invalid null handle"); + } + final int t = _target.getPosition(); + if (t < 0) { + throw new ClassGenException("Invalid branch target position offset for " + + super.toString(true) + ":" + t + ":" + _target); + } + return t - position; } - } - /** - * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen. - * Must be called after the target is actually changed in the - * InstructionTargeter. - */ - static void notifyTargetChanged(InstructionHandle new_ih, - InstructionTargeter t) { - if(new_ih != null) { - new_ih.addTargeter(t); + /** + * @return the offset to this instruction's target + */ + protected int getTargetOffset() { + return getTargetOffset(target); } - } - /** - * @param old_ih old target - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - if(target == old_ih) - setTarget(new_ih); - else - throw new ClassGenException("Not targeting " + old_ih + ", but " + target); - } + /** + * Called by InstructionList.setPositions when setting the position for + * every instruction. In the presence of variable length instructions + * `setPositions' performs multiple passes over the instruction list to + * calculate the correct (byte) positions and offsets by calling this + * function. + * + * @param offset additional offset caused by preceding (variable length) + * instructions + * @param max_offset the maximum offset that may be caused by these + * instructions + * @return additional offset caused by possible change of this instruction's + * length + */ + protected int updatePosition(final int offset, final int max_offset) { + position += offset; + return 0; + } - /** - * @return true, if ih is target of this instruction - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - return (target == ih); - } + /** + * Long output format: + * + * <position in byte code> <name of opcode> "["<opcode + * number>"]" "("<length of instruction>")" "<"<target + * instruction>">" "@"<branch target offset> + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + final String s = super.toString(verbose); + String t = "null"; + if (verbose) { + if (target != null) { + if (target.getInstruction() == this) { + t = ""; + } else if (target.getInstruction() == null) { + t = ""; + } else { + // I'm more interested in the address of the target then + // the instruction located there. + //t = target.getInstruction().toString(false); // Avoid circles + t = "" + target.getPosition(); + } + } + } else { + if (target != null) { + index = target.getPosition(); + // index = getTargetOffset(); crashes if positions haven't been set + // t = "" + (index + position); + t = "" + index; + } + } + return s + " -> " + t; + } + + /** + * Read needed data (e.g. index) from file. Conversion to a + * InstructionHandle is done in InstructionList(byte[]). + * + * @param bytes input stream + * @param wide wide prefix? + * @see InstructionList + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.setLength(3); + index = bytes.readShort(); + } + + /** + * @return target offset in byte code + */ + public final int getIndex() { + return index; + } + + /** + * @return target of branch instruction + */ + public InstructionHandle getTarget() { + return target; + } + + /** + * Set branch target + * + * @param target branch target + */ + public void setTarget(final InstructionHandle target) { + notifyTarget(this.target, target, this); + this.target = target; + } + + /** + * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen, + * LineNumberGen + */ + static void notifyTarget(final InstructionHandle old_ih, final InstructionHandle new_ih, + final InstructionTargeter t) { + if (old_ih != null) { + old_ih.removeTargeter(t); + } + if (new_ih != null) { + new_ih.addTargeter(t); + } + } + + /** + * @param old_ih old target + * @param new_ih new target + */ + @Override + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + if (target == old_ih) { + setTarget(new_ih); + } else { + throw new ClassGenException("Not targeting " + old_ih + ", but " + target); + } + } + + /** + * @return true, if ih is target of this instruction + */ + @Override + public boolean containsTarget(final InstructionHandle ih) { + return target == ih; + } + + /** + * Inform target that it's not targeted anymore. + */ + @Override + void dispose() { + setTarget(null); + index = -1; + position = -1; + } + + /** + * @return the position + * @since 6.0 + */ + protected int getPosition() { + return position; + } + + /** + * @param position the position to set + * @since 6.0 + */ + protected void setPosition(final int position) { + this.position = position; + } + + /** + * @param index the index to set + * @since 6.0 + */ + protected void setIndex(final int index) { + this.index = index; + } - /** - * Inform target that it's not targeted anymore. - */ - @Override - void dispose() { - setTarget(null); - index=-1; - position=-1; - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java index e0cd6aac454..76c5d00cdd1 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * CALOAD - Load char from array *
    Stack: ..., arrayref, index -> ..., value
    * - * @author M. Dahm + * @version $Id: CALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class CALOAD extends ArrayInstruction implements StackProducer { - /** Load char from array - */ - public CALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.CALOAD); - } + + /** Load char from array + */ + public CALOAD() { + super(com.sun.org.apache.bcel.internal.Const.CALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitCALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitCALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java index 2bb7678b3bb..93ae7a7acbc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * CASTORE - Store into char array *
    Stack: ..., arrayref, index, value -> ...
    * - * @author M. Dahm + * @version $Id: CASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class CASTORE extends ArrayInstruction implements StackConsumer { - /** Store char into array - */ - public CASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.CASTORE); - } + + /** Store char into array + */ + public CASTORE() { + super(com.sun.org.apache.bcel.internal.Const.CASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitCASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitCASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java index 02ebaf3a20f..71612c85cda 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java @@ -21,64 +21,68 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.ExceptionConst; + /** * CHECKCAST - Check whether object is of given type *
    Stack: ..., objectref -> ..., objectref
    * - * @author M. Dahm + * @version $Id: CHECKCAST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class CHECKCAST extends CPInstruction - implements LoadClass, ExceptionThrower, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - CHECKCAST() {} +public class CHECKCAST extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer, + StackConsumer { - /** Check whether object is of given type - * @param n index to class in constant pool - */ - public CHECKCAST(int index) { - super(com.sun.org.apache.bcel.internal.Constants.CHECKCAST, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + CHECKCAST() { + } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = - ExceptionConstants.CLASS_CAST_EXCEPTION; - return cs; - } + /** Check whether object is of given type + * @param index index to class in constant pool + */ + public CHECKCAST(final int index) { + super(com.sun.org.apache.bcel.internal.Const.CHECKCAST, index); + } - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - Type t = getType(cpg); - if(t instanceof ArrayType) - t = ((ArrayType) t).getBasicType(); + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, + ExceptionConst.CLASS_CAST_EXCEPTION); + } - return (t instanceof ObjectType)? (ObjectType) t : null; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitCHECKCAST(this); - } + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitCHECKCAST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java index 84ac4ef0de1..022dd1ff7f4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java @@ -18,116 +18,127 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import java.io.DataOutputStream; +import java.io.IOException; -import java.io.*; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantClass; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; import com.sun.org.apache.bcel.internal.util.ByteSequence; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; /** - * Abstract super class for instructions that use an index into the - * constant pool such as LDC, INVOKEVIRTUAL, etc. + * Abstract super class for instructions that use an index into the constant + * pool such as LDC, INVOKEVIRTUAL, etc. * * @see ConstantPoolGen * @see LDC * @see INVOKEVIRTUAL * - * @author M. Dahm + * @version $Id: CPInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public abstract class CPInstruction extends Instruction - implements TypedInstruction, IndexedInstruction -{ - protected int index; // index to constant pool +public abstract class CPInstruction extends Instruction implements TypedInstruction, + IndexedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - CPInstruction() {} + private int index; // index to constant pool - /** - * @param index to constant pool - */ - protected CPInstruction(short opcode, int index) { - super(opcode, (short)3); - setIndex(index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + CPInstruction() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - } + /** + * @param index to constant pool + */ + protected CPInstruction(final short opcode, final int index) { + super(opcode, (short) 3); + setIndex(index); + } - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" "<"< constant pool index>">" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + index; - } + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(index); + } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - Constant c = cp.getConstant(index); - String str = cp.constantToString(c); + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" "<"< constant pool index>">" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + index; + } - if(c instanceof ConstantClass) - str = str.replace('.', '/'); + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString(final ConstantPool cp) { + final Constant c = cp.getConstant(index); + String str = cp.constantToString(c); + if (c instanceof ConstantClass) { + str = str.replace('.', '/'); + } + return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " + str; + } - return com.sun.org.apache.bcel.internal.Constants.OPCODE_NAMES[opcode] + " " + str; - } + /** + * Read needed data (i.e., index) from file. + * + * @param bytes input stream + * @param wide wide prefix? + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + setIndex(bytes.readUnsignedShort()); + super.setLength(3); + } - /** - * Read needed data (i.e., index) from file. - * @param bytes input stream - * @param wide wide prefix? - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - setIndex(bytes.readUnsignedShort()); - length = 3; - } + /** + * @return index in constant pool referred by this instruction. + */ + @Override + public final int getIndex() { + return index; + } - /** - * @return index in constant pool referred by this instruction. - */ - public final int getIndex() { return index; } + /** + * Set the index to constant pool. + * + * @param index in constant pool. + */ + @Override + public void setIndex(final int index) { // TODO could be package-protected? + if (index < 0) { + throw new ClassGenException("Negative index value: " + index); + } + this.index = index; + } - /** - * Set the index to constant pool. - * @param index in constant pool. - */ - public void setIndex(int index) { - if(index < 0) - throw new ClassGenException("Negative index value: " + index); - - this.index = index; - } - - /** @return type related with this instruction. - */ - public Type getType(ConstantPoolGen cpg) { - ConstantPool cp = cpg.getConstantPool(); - String name = cp.getConstantString(index, com.sun.org.apache.bcel.internal.Constants.CONSTANT_Class); - - if(!name.startsWith("[")) - name = "L" + name + ";"; - - return Type.getType(name); - } + /** + * @return type related with this instruction. + */ + @Override + public Type getType(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + String name = cp.getConstantString(index, com.sun.org.apache.bcel.internal.Const.CONSTANT_Class); + if (!name.startsWith("[")) { + name = "L" + name + ";"; + } + return Type.getType(name); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java new file mode 100644 index 00000000000..249618f6122 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java @@ -0,0 +1,107 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.ClassElementValue; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; + +/** + * @since 6.0 + */ +public class ClassElementValueGen extends ElementValueGen +{ + // For primitive types and string type, this points to the value entry in + // the cpool + // For 'class' this points to the class entry in the cpool + private int idx; + + protected ClassElementValueGen(final int typeIdx, final ConstantPoolGen cpool) + { + super(ElementValueGen.CLASS, cpool); + this.idx = typeIdx; + } + + public ClassElementValueGen(final ObjectType t, final ConstantPoolGen cpool) + { + super(ElementValueGen.CLASS, cpool); + // this.idx = cpool.addClass(t); + idx = cpool.addUtf8(t.getSignature()); + } + + /** + * Return immutable variant of this ClassElementValueGen + */ + @Override + public ElementValue getElementValue() + { + return new ClassElementValue(super.getElementValueType(), + idx, + getConstantPool().getConstantPool()); + } + + public ClassElementValueGen(final ClassElementValue value, final ConstantPoolGen cpool, + final boolean copyPoolEntries) + { + super(CLASS, cpool); + if (copyPoolEntries) + { + // idx = cpool.addClass(value.getClassString()); + idx = cpool.addUtf8(value.getClassString()); + } + else + { + idx = value.getIndex(); + } + } + + public int getIndex() + { + return idx; + } + + public String getClassString() + { + final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); + return cu8.getBytes(); + // ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx); + // ConstantUtf8 utf8 = + // (ConstantUtf8)getConstantPool().getConstant(c.getNameIndex()); + // return utf8.getBytes(); + } + + @Override + public String stringifyValue() + { + return getClassString(); + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 kind of value + dos.writeShort(idx); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java index 2e1b4d37e73..435b0704f01 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java @@ -18,401 +18,562 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.ArrayList; -import java.util.Iterator; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.AccessFlags; +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.Annotations; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleAnnotations; +import com.sun.org.apache.bcel.internal.classfile.SourceFile; +import com.sun.org.apache.bcel.internal.util.BCELComparator; /** * Template class for building up a java class. May be initialized with an * existing java class (file). * * @see JavaClass - * @author M. Dahm + * @version $Id: ClassGen.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class ClassGen extends AccessFlags implements Cloneable { - /* Corresponds to the fields found in a JavaClass object. - */ - private String class_name, super_class_name, file_name; - private int class_name_index = -1, superclass_name_index = -1; - private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1; - private ConstantPoolGen cp; // Template for building up constant pool + /* Corresponds to the fields found in a JavaClass object. + */ + private String class_name; + private String super_class_name; + private final String file_name; + private int class_name_index = -1; + private int superclass_name_index = -1; + private int major = Const.MAJOR; + private int minor = Const.MINOR; + private ConstantPoolGen cp; // Template for building up constant pool + // ArrayLists instead of arrays to gather fields, methods, etc. + private final List field_vec = new ArrayList<>(); + private final List method_vec = new ArrayList<>(); + private final List attribute_vec = new ArrayList<>(); + private final List interface_vec = new ArrayList<>(); + private final List annotation_vec = new ArrayList<>(); - // ArrayLists instead of arrays to gather fields, methods, etc. - private ArrayList field_vec = new ArrayList(); - private ArrayList method_vec = new ArrayList(); - private ArrayList attribute_vec = new ArrayList(); - private ArrayList interface_vec = new ArrayList(); + private static BCELComparator _cmp = new BCELComparator() { - /** Convenience constructor to set up some important values initially. - * - * @param class_name fully qualified class name - * @param super_class_name fully qualified superclass name - * @param file_name source file name - * @param access_flags access qualifiers - * @param interfaces implemented interfaces - * @param cp constant pool to use - */ - public ClassGen(String class_name, String super_class_name, String file_name, - int access_flags, String[] interfaces, ConstantPoolGen cp) { - this.class_name = class_name; - this.super_class_name = super_class_name; - this.file_name = file_name; - this.access_flags = access_flags; - this.cp = cp; + @Override + public boolean equals(final Object o1, final Object o2) { + final ClassGen THIS = (ClassGen) o1; + final ClassGen THAT = (ClassGen) o2; + return THIS.getClassName().equals(THAT.getClassName()); + } - // Put everything needed by default into the constant pool and the vectors - if(file_name != null) - addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, - cp.addUtf8(file_name), cp.getConstantPool())); + @Override + public int hashCode(final Object o) { + final ClassGen THIS = (ClassGen) o; + return THIS.getClassName().hashCode(); + } + }; - class_name_index = cp.addClass(class_name); - superclass_name_index = cp.addClass(super_class_name); - - if(interfaces != null) - for(int i=0; i < interfaces.length; i++) - addInterface(interfaces[i]); - } - - /** Convenience constructor to set up some important values initially. - * - * @param class_name fully qualified class name - * @param super_class_name fully qualified superclass name - * @param file_name source file name - * @param access_flags access qualifiers - * @param interfaces implemented interfaces - */ - public ClassGen(String class_name, String super_class_name, String file_name, - int access_flags, String[] interfaces) { - this(class_name, super_class_name, file_name, access_flags, interfaces, - new ConstantPoolGen()); - } - - /** - * Initialize with existing class. - * @param clazz JavaClass object (e.g. read from file) - */ - public ClassGen(JavaClass clazz) { - class_name_index = clazz.getClassNameIndex(); - superclass_name_index = clazz.getSuperclassNameIndex(); - class_name = clazz.getClassName(); - super_class_name = clazz.getSuperclassName(); - file_name = clazz.getSourceFileName(); - access_flags = clazz.getAccessFlags(); - cp = new ConstantPoolGen(clazz.getConstantPool()); - major = clazz.getMajor(); - minor = clazz.getMinor(); - - Attribute[] attributes = clazz.getAttributes(); - Method[] methods = clazz.getMethods(); - Field[] fields = clazz.getFields(); - String[] interfaces = clazz.getInterfaceNames(); - - for(int i=0; i < interfaces.length; i++) - addInterface(interfaces[i]); - - for(int i=0; i < attributes.length; i++) - addAttribute(attributes[i]); - - for(int i=0; i < methods.length; i++) - addMethod(methods[i]); - - for(int i=0; i < fields.length; i++) - addField(fields[i]); - } - - /** - * @return the (finally) built up Java class object. - */ - public JavaClass getJavaClass() { - int[] interfaces = getInterfaces(); - Field[] fields = getFields(); - Method[] methods = getMethods(); - Attribute[] attributes = getAttributes(); - - // Must be last since the above calls may still add something to it - ConstantPool cp = this.cp.getFinalConstantPool(); - - return new JavaClass(class_name_index, superclass_name_index, - file_name, major, minor, access_flags, - cp, interfaces, fields, methods, attributes); - } - - /** - * Add an interface to this class, i.e., this class has to implement it. - * @param name interface to implement (fully qualified class name) - */ - public void addInterface(String name) { - interface_vec.add(name); - } - - /** - * Remove an interface from this class. - * @param name interface to remove (fully qualified name) - */ - public void removeInterface(String name) { - interface_vec.remove(name); - } - - /** - * @return major version number of class file - */ - public int getMajor() { return major; } - - /** Set major version number of class file, default value is 45 (JDK 1.1) - * @param major major version number - */ - public void setMajor(int major) { - this.major = major; - } - - /** Set minor version number of class file, default value is 3 (JDK 1.1) - * @param minor minor version number - */ - public void setMinor(int minor) { - this.minor = minor; - } - - /** - * @return minor version number of class file - */ - public int getMinor() { return minor; } - - /** - * Add an attribute to this class. - * @param a attribute to add - */ - public void addAttribute(Attribute a) { attribute_vec.add(a); } - - /** - * Add a method to this class. - * @param m method to add - */ - public void addMethod(Method m) { method_vec.add(m); } - - /** - * Convenience method. - * - * Add an empty constructor to this class that does nothing but calling super(). - * @param access rights for constructor - */ - public void addEmptyConstructor(int access_flags) { - InstructionList il = new InstructionList(); - il.append(InstructionConstants.THIS); // Push `this' - il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, - "", "()V"))); - il.append(InstructionConstants.RETURN); - - MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, - "", class_name, il, cp); - mg.setMaxStack(1); - addMethod(mg.getMethod()); - } - - /** - * Add a field to this class. - * @param f field to add - */ - public void addField(Field f) { field_vec.add(f); } - - public boolean containsField(Field f) { return field_vec.contains(f); } - - /** @return field object with given name, or null - */ - public Field containsField(String name) { - for(Iterator e=field_vec.iterator(); e.hasNext(); ) { - Field f = (Field)e.next(); - if(f.getName().equals(name)) - return f; + /** + * Convenience constructor to set up some important values initially. + * + * @param class_name fully qualified class name + * @param super_class_name fully qualified superclass name + * @param file_name source file name + * @param access_flags access qualifiers + * @param interfaces implemented interfaces + * @param cp constant pool to use + */ + public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags, + final String[] interfaces, final ConstantPoolGen cp) { + super(access_flags); + this.class_name = class_name; + this.super_class_name = super_class_name; + this.file_name = file_name; + this.cp = cp; + // Put everything needed by default into the constant pool and the vectors + if (file_name != null) { + addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp + .getConstantPool())); + } + class_name_index = cp.addClass(class_name); + superclass_name_index = cp.addClass(super_class_name); + if (interfaces != null) { + for (final String interface1 : interfaces) { + addInterface(interface1); + } + } } - return null; - } - - /** @return method object with given name and signature, or null - */ - public Method containsMethod(String name, String signature) { - for(Iterator e=method_vec.iterator(); e.hasNext();) { - Method m = (Method)e.next(); - if(m.getName().equals(name) && m.getSignature().equals(signature)) - return m; + /** + * Convenience constructor to set up some important values initially. + * + * @param class_name fully qualified class name + * @param super_class_name fully qualified superclass name + * @param file_name source file name + * @param access_flags access qualifiers + * @param interfaces implemented interfaces + */ + public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags, + final String[] interfaces) { + this(class_name, super_class_name, file_name, access_flags, interfaces, + new ConstantPoolGen()); } - return null; - } - - /** - * Remove an attribute from this class. - * @param a attribute to remove - */ - public void removeAttribute(Attribute a) { attribute_vec.remove(a); } - - /** - * Remove a method from this class. - * @param m method to remove - */ - public void removeMethod(Method m) { method_vec.remove(m); } - - /** Replace given method with new one. If the old one does not exist - * add the new_ method to the class anyway. - */ - public void replaceMethod(Method old, Method new_) { - if(new_ == null) - throw new ClassGenException("Replacement method must not be null"); - - int i = method_vec.indexOf(old); - - if(i < 0) - method_vec.add(new_); - else - method_vec.set(i, new_); - } - - /** Replace given field with new one. If the old one does not exist - * add the new_ field to the class anyway. - */ - public void replaceField(Field old, Field new_) { - if(new_ == null) - throw new ClassGenException("Replacement method must not be null"); - - int i = field_vec.indexOf(old); - - if(i < 0) - field_vec.add(new_); - else - field_vec.set(i, new_); - } - - /** - * Remove a field to this class. - * @param f field to remove - */ - public void removeField(Field f) { field_vec.remove(f); } - - public String getClassName() { return class_name; } - public String getSuperclassName() { return super_class_name; } - public String getFileName() { return file_name; } - - public void setClassName(String name) { - class_name = name.replace('/', '.'); - class_name_index = cp.addClass(name); - } - - public void setSuperclassName(String name) { - super_class_name = name.replace('/', '.'); - superclass_name_index = cp.addClass(name); - } - - public Method[] getMethods() { - Method[] methods = new Method[method_vec.size()]; - method_vec.toArray(methods); - return methods; - } - - public void setMethods(Method[] methods) { - method_vec.clear(); - for(int m=0; m annotationGenObjs = new ArrayList<>(); + for (final Attribute attr : attrs) { + if (attr instanceof RuntimeVisibleAnnotations) { + final RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr; + final AnnotationEntry[] annos = rva.getAnnotationEntries(); + for (final AnnotationEntry a : annos) { + annotationGenObjs.add(new AnnotationEntryGen(a, + getConstantPool(), false)); + } + } else if (attr instanceof RuntimeInvisibleAnnotations) { + final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr; + final AnnotationEntry[] annos = ria.getAnnotationEntries(); + for (final AnnotationEntry a : annos) { + annotationGenObjs.add(new AnnotationEntryGen(a, + getConstantPool(), false)); + } + } + } + return annotationGenObjs.toArray(new AnnotationEntryGen[annotationGenObjs.size()]); + } + + /** + * @return the (finally) built up Java class object. + */ + public JavaClass getJavaClass() { + final int[] interfaces = getInterfaces(); + final Field[] fields = getFields(); + final Method[] methods = getMethods(); + Attribute[] attributes; + if (annotation_vec.isEmpty()) { + attributes = getAttributes(); + } else { + // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations' + final Attribute[] annAttributes = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries()); + attributes = new Attribute[attribute_vec.size() + annAttributes.length]; + attribute_vec.toArray(attributes); + System.arraycopy(annAttributes, 0, attributes, attribute_vec.size(), annAttributes.length); + } + // Must be last since the above calls may still add something to it + final ConstantPool _cp = this.cp.getFinalConstantPool(); + return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, + super.getAccessFlags(), _cp, interfaces, fields, methods, attributes); + } + + /** + * Add an interface to this class, i.e., this class has to implement it. + * + * @param name interface to implement (fully qualified class name) + */ + public final void addInterface(final String name) { + interface_vec.add(name); + } + + /** + * Remove an interface from this class. + * + * @param name interface to remove (fully qualified name) + */ + public void removeInterface(final String name) { + interface_vec.remove(name); + } + + /** + * @return major version number of class file + */ + public int getMajor() { + return major; + } + + /** + * Set major version number of class file, default value is 45 (JDK 1.1) + * + * @param major major version number + */ + public void setMajor(final int major) { // TODO could be package-protected - only called by test code + this.major = major; + } + + /** + * Set minor version number of class file, default value is 3 (JDK 1.1) + * + * @param minor minor version number + */ + public void setMinor(final int minor) { // TODO could be package-protected - only called by test code + this.minor = minor; + } + + /** + * @return minor version number of class file + */ + public int getMinor() { + return minor; + } + + /** + * Add an attribute to this class. + * + * @param a attribute to add + */ + public final void addAttribute(final Attribute a) { + attribute_vec.add(a); + } + + public final void addAnnotationEntry(final AnnotationEntryGen a) { + annotation_vec.add(a); + } + + /** + * Add a method to this class. + * + * @param m method to add + */ + public final void addMethod(final Method m) { + method_vec.add(m); + } + + /** + * Convenience method. + * + * Add an empty constructor to this class that does nothing but calling + * super(). + * + * @param access_flags rights for constructor + */ + public void addEmptyConstructor(final int access_flags) { + final InstructionList il = new InstructionList(); + il.append(InstructionConst.THIS); // Push `this' + il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "", "()V"))); + il.append(InstructionConst.RETURN); + final MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "", + class_name, il, cp); + mg.setMaxStack(1); + addMethod(mg.getMethod()); + } + + /** + * Add a field to this class. + * + * @param f field to add + */ + public final void addField(final Field f) { + field_vec.add(f); + } + + public boolean containsField(final Field f) { + return field_vec.contains(f); + } + + /** + * @return field object with given name, or null + */ + public Field containsField(final String name) { + for (final Field f : field_vec) { + if (f.getName().equals(name)) { + return f; + } + } + return null; + } + + /** + * @return method object with given name and signature, or null + */ + public Method containsMethod(final String name, final String signature) { + for (final Method m : method_vec) { + if (m.getName().equals(name) && m.getSignature().equals(signature)) { + return m; + } + } + return null; + } + + /** + * Remove an attribute from this class. + * + * @param a attribute to remove + */ + public void removeAttribute(final Attribute a) { + attribute_vec.remove(a); + } + + /** + * Remove a method from this class. + * + * @param m method to remove + */ + public void removeMethod(final Method m) { + method_vec.remove(m); + } + + /** + * Replace given method with new one. If the old one does not exist add the + * new_ method to the class anyway. + */ + public void replaceMethod(final Method old, final Method new_) { + if (new_ == null) { + throw new ClassGenException("Replacement method must not be null"); + } + final int i = method_vec.indexOf(old); + if (i < 0) { + method_vec.add(new_); + } else { + method_vec.set(i, new_); + } + } + + /** + * Replace given field with new one. If the old one does not exist add the + * new_ field to the class anyway. + */ + public void replaceField(final Field old, final Field new_) { + if (new_ == null) { + throw new ClassGenException("Replacement method must not be null"); + } + final int i = field_vec.indexOf(old); + if (i < 0) { + field_vec.add(new_); + } else { + field_vec.set(i, new_); + } + } + + /** + * Remove a field to this class. + * + * @param f field to remove + */ + public void removeField(final Field f) { + field_vec.remove(f); + } + + public String getClassName() { + return class_name; + } + + public String getSuperclassName() { + return super_class_name; + } + + public String getFileName() { + return file_name; + } + + public void setClassName(final String name) { + class_name = name.replace('/', '.'); + class_name_index = cp.addClass(name); + } + + public void setSuperclassName(final String name) { + super_class_name = name.replace('/', '.'); + superclass_name_index = cp.addClass(name); + } + + public Method[] getMethods() { + return method_vec.toArray(new Method[method_vec.size()]); + } + + public void setMethods(final Method[] methods) { + method_vec.clear(); + for (final Method method : methods) { + addMethod(method); + } + } + + public void setMethodAt(final Method method, final int pos) { + method_vec.set(pos, method); + } + + public Method getMethodAt(final int pos) { + return method_vec.get(pos); + } + + public String[] getInterfaceNames() { + final int size = interface_vec.size(); + final String[] interfaces = new String[size]; + interface_vec.toArray(interfaces); + return interfaces; + } + + public int[] getInterfaces() { + final int size = interface_vec.size(); + final int[] interfaces = new int[size]; + for (int i = 0; i < size; i++) { + interfaces[i] = cp.addClass(interface_vec.get(i)); + } + return interfaces; + } + + public Field[] getFields() { + return field_vec.toArray(new Field[field_vec.size()]); + } + + public Attribute[] getAttributes() { + return attribute_vec.toArray(new Attribute[attribute_vec.size()]); + } + + // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here? + public AnnotationEntryGen[] getAnnotationEntries() { + return annotation_vec.toArray(new AnnotationEntryGen[annotation_vec.size()]); + } + + public ConstantPoolGen getConstantPool() { + return cp; + } + + public void setConstantPool(final ConstantPoolGen constant_pool) { + cp = constant_pool; + } + + public void setClassNameIndex(final int class_name_index) { + this.class_name_index = class_name_index; + class_name = cp.getConstantPool().getConstantString(class_name_index, + Const.CONSTANT_Class).replace('/', '.'); + } + + public void setSuperclassNameIndex(final int superclass_name_index) { + this.superclass_name_index = superclass_name_index; + super_class_name = cp.getConstantPool().getConstantString(superclass_name_index, + Const.CONSTANT_Class).replace('/', '.'); + } + + public int getSuperclassNameIndex() { + return superclass_name_index; + } + + public int getClassNameIndex() { + return class_name_index; + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(final ClassObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(final ClassObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (final ClassObserver observer : observers) { + observer.notify(this); + } + } + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + _cmp = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * ClassGen objects are said to be equal when their class names are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return _cmp.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the class name. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java index 6bc4ee6c534..cd3168ecaa3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java @@ -21,14 +21,26 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared * in the throws clause every time. * - * @author M. Dahm + * @version $Id: ClassGenException.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ClassGenException extends RuntimeException { - public ClassGenException() { super(); } - public ClassGenException(String s) { super(s); } + + private static final long serialVersionUID = 7247369755051242791L; + + public ClassGenException() { + super(); + } + + + public ClassGenException(final String s) { + super(s); + } + + public ClassGenException(final String s, final Throwable initCause) { + super(s, initCause); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java index a01e5b6288c..7229c40cf00 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Implement this interface if you're interested in changes to a ClassGen object * and register yourself with addObserver(). * - * @author M. Dahm + * @version $Id: ClassObserver.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface ClassObserver { - public void notify(ClassGen clazz); + + void notify( ClassGen clazz ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java index 96bd2124f37..2bace2f1836 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java @@ -18,14 +18,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.classfile.*; +import com.sun.org.apache.bcel.internal.classfile.CodeException; /** - * This class represents an exception handler, i.e., specifies the region where + * This class represents an exception handler, i.e., specifies the region where * a handler is active and an instruction where the actual handling is done. * pool as parameters. Opposed to the JVM specification the end of the handled * region is set to be inclusive, i.e. all instructions between start and end @@ -33,143 +31,156 @@ import com.sun.org.apache.bcel.internal.classfile.*; * The end of the region is automatically mapped to be exclusive when calling * getCodeException(), i.e., there is no difference semantically. * - * @author M. Dahm - * @see MethodGen - * @see CodeException - * @see InstructionHandle + * @version $Id: CodeExceptionGen.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see MethodGen + * @see CodeException + * @see InstructionHandle */ -public final class CodeExceptionGen - implements InstructionTargeter, Cloneable, java.io.Serializable { - private InstructionHandle start_pc; - private InstructionHandle end_pc; - private InstructionHandle handler_pc; - private ObjectType catch_type; +public final class CodeExceptionGen implements InstructionTargeter, Cloneable { - /** - * Add an exception handler, i.e., specify region where a handler is active and an - * instruction where the actual handling is done. - * - * @param start_pc Start of handled region (inclusive) - * @param end_pc End of handled region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type which exception is handled, null for ANY - */ - public CodeExceptionGen(InstructionHandle start_pc, InstructionHandle end_pc, - InstructionHandle handler_pc, ObjectType catch_type) { - setStartPC(start_pc); - setEndPC(end_pc); - setHandlerPC(handler_pc); - this.catch_type = catch_type; - } + private InstructionHandle start_pc; + private InstructionHandle end_pc; + private InstructionHandle handler_pc; + private ObjectType catch_type; - /** - * Get CodeException object.
    - * - * This relies on that the instruction list has already been dumped - * to byte code or or that the `setPositions' methods has been - * called for the instruction list. - * - * @param cp constant pool - */ - public CodeException getCodeException(ConstantPoolGen cp) { - return new CodeException(start_pc.getPosition(), - end_pc.getPosition() + end_pc.getInstruction().getLength(), - handler_pc.getPosition(), - (catch_type == null)? 0 : cp.addClass(catch_type)); - } - - /* Set start of handler - * @param start_pc Start of handled region (inclusive) - */ - public final void setStartPC(InstructionHandle start_pc) { - BranchInstruction.notifyTargetChanging(this.start_pc, this); - this.start_pc = start_pc; - BranchInstruction.notifyTargetChanged(this.start_pc, this); - } - - /* Set end of handler - * @param end_pc End of handled region (inclusive) - */ - public final void setEndPC(InstructionHandle end_pc) { - BranchInstruction.notifyTargetChanging(this.end_pc, this); - this.end_pc = end_pc; - BranchInstruction.notifyTargetChanged(this.end_pc, this); - } - - /* Set handler code - * @param handler_pc Start of handler - */ - public final void setHandlerPC(InstructionHandle handler_pc) { - BranchInstruction.notifyTargetChanging(this.handler_pc, this); - this.handler_pc = handler_pc; - BranchInstruction.notifyTargetChanged(this.handler_pc, this); - } - - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if(start_pc == old_ih) { - targeted = true; - setStartPC(new_ih); + /** + * Add an exception handler, i.e., specify region where a handler is active + * and an instruction where the actual handling is done. + * + * @param start_pc Start of handled region (inclusive) + * @param end_pc End of handled region (inclusive) + * @param handler_pc Where handling is done + * @param catch_type which exception is handled, null for ANY + */ + public CodeExceptionGen(final InstructionHandle start_pc, final InstructionHandle end_pc, + final InstructionHandle handler_pc, final ObjectType catch_type) { + setStartPC(start_pc); + setEndPC(end_pc); + setHandlerPC(handler_pc); + this.catch_type = catch_type; } - if(end_pc == old_ih) { - targeted = true; - setEndPC(new_ih); + /** + * Get CodeException object.
    + * + * This relies on that the instruction list has already been dumped to byte + * code or or that the `setPositions' methods has been called for the + * instruction list. + * + * @param cp constant pool + */ + public CodeException getCodeException(final ConstantPoolGen cp) { + return new CodeException(start_pc.getPosition(), end_pc.getPosition() + + end_pc.getInstruction().getLength(), handler_pc.getPosition(), + (catch_type == null) ? 0 : cp.addClass(catch_type)); } - if(handler_pc == old_ih) { - targeted = true; - setHandlerPC(new_ih); + + /* Set start of handler + * @param start_pc Start of handled region (inclusive) + */ + public void setStartPC(final InstructionHandle start_pc) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.start_pc, start_pc, this); + this.start_pc = start_pc; } - if(!targeted) - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", " + - end_pc + ", " + handler_pc + "}"); - } - /** - * @return true, if ih is target of this handler - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); - } - - /** Sets the type of the Exception to catch. Set 'null' for ANY. */ - public void setCatchType(ObjectType catch_type) { this.catch_type = catch_type; } - /** Gets the type of the Exception to catch, 'null' for ANY. */ - public ObjectType getCatchType() { return catch_type; } - - /** @return start of handled region (inclusive) - */ - public InstructionHandle getStartPC() { return start_pc; } - - /** @return end of handled region (inclusive) - */ - public InstructionHandle getEndPC() { return end_pc; } - - /** @return start of handler - */ - public InstructionHandle getHandlerPC() { return handler_pc; } - - @Override - public String toString() { - return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; + /* Set end of handler + * @param end_pc End of handled region (inclusive) + */ + public void setEndPC(final InstructionHandle end_pc) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.end_pc, end_pc, this); + this.end_pc = end_pc; + } + + + /* Set handler code + * @param handler_pc Start of handler + */ + public void setHandlerPC(final InstructionHandle handler_pc) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this); + this.handler_pc = handler_pc; + } + + /** + * @param old_ih old target, either start or end + * @param new_ih new target + */ + @Override + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + boolean targeted = false; + if (start_pc == old_ih) { + targeted = true; + setStartPC(new_ih); + } + if (end_pc == old_ih) { + targeted = true; + setEndPC(new_ih); + } + if (handler_pc == old_ih) { + targeted = true; + setHandlerPC(new_ih); + } + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", " + + end_pc + ", " + handler_pc + "}"); + } + } + + /** + * @return true, if ih is target of this handler + */ + @Override + public boolean containsTarget(final InstructionHandle ih) { + return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); + } + + /** + * Sets the type of the Exception to catch. Set 'null' for ANY. + */ + public void setCatchType(final ObjectType catch_type) { + this.catch_type = catch_type; + } + + /** + * Gets the type of the Exception to catch, 'null' for ANY. + */ + public ObjectType getCatchType() { + return catch_type; + } + + /** + * @return start of handled region (inclusive) + */ + public InstructionHandle getStartPC() { + return start_pc; + } + + /** + * @return end of handled region (inclusive) + */ + public InstructionHandle getEndPC() { + return end_pc; + } + + /** + * @return start of handler + */ + public InstructionHandle getHandlerPC() { + return handler_pc; + } + + @Override + public String toString() { + return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java index b54af3aacf4..25250d27b70 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java @@ -21,7 +21,6 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Wrapper class for `compound' operations, virtual instructions that * don't exist as byte code, but give a useful meaning. For example, @@ -33,10 +32,11 @@ package com.sun.org.apache.bcel.internal.generic; * The interface provides the possibilty for the user to write * `templates' or `macros' for such reuseable code patterns. * - * @author M. Dahm + * @version $Id: CompoundInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see PUSH * @see SWITCH */ public interface CompoundInstruction { - public InstructionList getInstructionList(); + + InstructionList getInstructionList(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java index 4eb12e2e693..58c8a2940a0 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,736 +17,773 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.HashMap; +import java.util.Map; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantCP; +import com.sun.org.apache.bcel.internal.classfile.ConstantClass; +import com.sun.org.apache.bcel.internal.classfile.ConstantDouble; +import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref; +import com.sun.org.apache.bcel.internal.classfile.ConstantFloat; +import com.sun.org.apache.bcel.internal.classfile.ConstantInteger; +import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic; +import com.sun.org.apache.bcel.internal.classfile.ConstantLong; +import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantString; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; /** - * This class is used to build up a constant pool. The user adds - * constants via `addXXX' methods, `addString', `addClass', - * etc.. These methods return an index into the constant - * pool. Finally, `getFinalConstantPool()' returns the constant pool - * built up. Intermediate versions of the constant pool can be + * This class is used to build up a constant pool. The user adds constants via + * `addXXX' methods, `addString', `addClass', etc.. These methods return an + * index into the constant pool. Finally, `getFinalConstantPool()' returns the + * constant pool built up. Intermediate versions of the constant pool can be * obtained with `getConstantPool()'. A constant pool has capacity for - * Constants.MAX_SHORT entries. Note that the first (0) is used by the - * JVM and that Double and Long constants need two slots. + * Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and + * that Double and Long constants need two slots. * - * @author M. Dahm + * @version $Id: ConstantPoolGen.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Constant */ -public class ConstantPoolGen implements java.io.Serializable { - protected int size = 1024; // Inital size, sufficient in most cases - protected Constant[] constants = new Constant[size]; - protected int index = 1; // First entry (0) used by JVM +public class ConstantPoolGen { - private static final String METHODREF_DELIM = ":"; - private static final String IMETHODREF_DELIM = "#"; - private static final String FIELDREF_DELIM = "&"; - private static final String NAT_DELIM = "%"; + private static final int DEFAULT_BUFFER_SIZE = 256; + private int size; + private Constant[] constants; + private int index = 1; // First entry (0) used by JVM - private static class Index implements java.io.Serializable { - int index; - Index(int i) { index = i; } - } + private static final String METHODREF_DELIM = ":"; + private static final String IMETHODREF_DELIM = "#"; + private static final String FIELDREF_DELIM = "&"; + private static final String NAT_DELIM = "%"; // Name and Type - /** - * Initialize with given array of constants. - * - * @param c array of given constants, new ones will be appended - */ - public ConstantPoolGen(Constant[] cs) { - if(cs.length > size) { - size = cs.length; - constants = new Constant[size]; + private static class Index { + + final int index; + + Index(final int i) { + index = i; + } } - System.arraycopy(cs, 0, constants, 0, cs.length); + /** + * Initialize with given array of constants. + * + * @param cs array of given constants, new ones will be appended + */ + public ConstantPoolGen(final Constant[] cs) { + final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); - if(cs.length > 0) - index = cs.length; + size = Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64); + constants = new Constant[size]; - for(int i=1; i < index; i++) { - Constant c = constants[i]; + System.arraycopy(cs, 0, constants, 0, cs.length); + if (cs.length > 0) { + index = cs.length; + } - if(c instanceof ConstantString) { - ConstantString s = (ConstantString)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; + for (int i = 1; i < index; i++) { + final Constant c = constants[i]; + if (c instanceof ConstantString) { + final ConstantString s = (ConstantString) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; + final String key = u8.getBytes(); + if (!string_table.containsKey(key)) { + string_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantClass) { + final ConstantClass s = (ConstantClass) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; + final String key = u8.getBytes(); + if (!class_table.containsKey(key)) { + class_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantNameAndType) { + final ConstantNameAndType n = (ConstantNameAndType) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; - string_table.put(u8.getBytes(), new Index(i)); - } else if(c instanceof ConstantClass) { - ConstantClass s = (ConstantClass)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; + sb.append(u8.getBytes()); + sb.append(NAT_DELIM); + sb.append(u8_2.getBytes()); + final String key = sb.toString(); + sb.delete(0, sb.length()); - class_table.put(u8.getBytes(), new Index(i)); - } else if(c instanceof ConstantNameAndType) { - ConstantNameAndType n = (ConstantNameAndType)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; - ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; + if (!n_a_t_table.containsKey(key)) { + n_a_t_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantUtf8) { + final ConstantUtf8 u = (ConstantUtf8) c; + final String key = u.getBytes(); + if (!utf8_table.containsKey(key)) { + utf8_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantCP) { + final ConstantCP m = (ConstantCP) c; + String class_name; + ConstantUtf8 u8; - n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i)); - } else if(c instanceof ConstantUtf8) { - ConstantUtf8 u = (ConstantUtf8)c; + if (c instanceof ConstantInvokeDynamic) { + class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex()); + // since name can't begin with digit, can use + // METHODREF_DELIM with out fear of duplicates. + } else { + final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + class_name = u8.getBytes().replace('/', '.'); + } - utf8_table.put(u.getBytes(), new Index(i)); - } else if(c instanceof ConstantCP) { - ConstantCP m = (ConstantCP)c; - ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; - ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; + final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; + u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final String method_name = u8.getBytes(); + u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; + final String signature = u8.getBytes(); - ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; - String class_name = u8.getBytes().replace('/', '.'); + String delim = METHODREF_DELIM; + if (c instanceof ConstantInterfaceMethodref) { + delim = IMETHODREF_DELIM; + } else if (c instanceof ConstantFieldref) { + delim = FIELDREF_DELIM; + } - u8 = (ConstantUtf8)constants[n.getNameIndex()]; - String method_name = u8.getBytes(); + sb.append(class_name); + sb.append(delim); + sb.append(method_name); + sb.append(delim); + sb.append(signature); + final String key = sb.toString(); + sb.delete(0, sb.length()); - u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; - String signature = u8.getBytes(); - - String delim = METHODREF_DELIM; - - if(c instanceof ConstantInterfaceMethodref) - delim = IMETHODREF_DELIM; - else if(c instanceof ConstantFieldref) - delim = FIELDREF_DELIM; - - cp_table.put(class_name + delim + method_name + delim + signature, new Index(i)); - } - } - } - - /** - * Initialize with given constant pool. - */ - public ConstantPoolGen(ConstantPool cp) { - this(cp.getConstantPool()); - } - - /** - * Create empty constant pool. - */ - public ConstantPoolGen() {} - - /** Resize internal array of constants. - */ - protected void adjustSize() { - if(index + 3 >= size) { - Constant[] cs = constants; - - size *= 2; - constants = new Constant[size]; - System.arraycopy(cs, 0, constants, 0, index); - } - } - - private HashMap string_table = new HashMap(); - - /** - * Look for ConstantString in ConstantPool containing String `str'. - * - * @param str String to search for - * @return index on success, -1 otherwise - */ - public int lookupString(String str) { - Index index = (Index)string_table.get(str); - return (index != null)? index.index : -1; - } - - /** - * Add a new String constant to the ConstantPool, if it is not already in there. - * - * @param str String to add - * @return index of entry - */ - public int addString(String str) { - int ret; - - if((ret = lookupString(str)) != -1) - return ret; // Already in CP - - int utf8 = addUtf8(str); - - adjustSize(); - - ConstantString s = new ConstantString(utf8); - - ret = index; - constants[index++] = s; - - string_table.put(str, new Index(ret)); - - return ret; - } - - private HashMap class_table = new HashMap(); - - /** - * Look for ConstantClass in ConstantPool named `str'. - * - * @param str String to search for - * @return index on success, -1 otherwise - */ - public int lookupClass(String str) { - Index index = (Index)class_table.get(str.replace('.', '/')); - return (index != null)? index.index : -1; - } - - private int addClass_(String clazz) { - int ret; - - if((ret = lookupClass(clazz)) != -1) - return ret; // Already in CP - - adjustSize(); - - ConstantClass c = new ConstantClass(addUtf8(clazz)); - - ret = index; - constants[index++] = c; - - class_table.put(clazz, new Index(ret)); - - return ret; - } - - /** - * Add a new Class reference to the ConstantPool, if it is not already in there. - * - * @param str Class to add - * @return index of entry - */ - public int addClass(String str) { - return addClass_(str.replace('.', '/')); - } - - /** - * Add a new Class reference to the ConstantPool for a given type. - * - * @param str Class to add - * @return index of entry - */ - public int addClass(ObjectType type) { - return addClass(type.getClassName()); - } - - /** - * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY - * instruction, e.g. to the ConstantPool. - * - * @param type type of array class - * @return index of entry - */ - public int addArrayClass(ArrayType type) { - return addClass_(type.getSignature()); - } - - /** - * Look for ConstantInteger in ConstantPool. - * - * @param n integer number to look for - * @return index on success, -1 otherwise - */ - public int lookupInteger(int n) { - for(int i=1; i < index; i++) { - if(constants[i] instanceof ConstantInteger) { - ConstantInteger c = (ConstantInteger)constants[i]; - - if(c.getBytes() == n) - return i; - } + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(i)); + } + } else if (c == null) { // entries may be null + // nothing to do + } else if (c instanceof ConstantInteger) { + // nothing to do + } else if (c instanceof ConstantLong) { + // nothing to do + } else if (c instanceof ConstantFloat) { + // nothing to do + } else if (c instanceof ConstantDouble) { + // nothing to do + } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodType) { + // TODO should this be handled somehow? + } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodHandle) { + // TODO should this be handled somehow? + } else { + assert false : "Unexpected constant type: " + c.getClass().getName(); + } + } } - return -1; - } - - /** - * Add a new Integer constant to the ConstantPool, if it is not already in there. - * - * @param n integer number to add - * @return index of entry - */ - public int addInteger(int n) { - int ret; - - if((ret = lookupInteger(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index++] = new ConstantInteger(n); - - return ret; - } - - /** - * Look for ConstantFloat in ConstantPool. - * - * @param n Float number to look for - * @return index on success, -1 otherwise - */ - public int lookupFloat(float n) { - int bits = Float.floatToIntBits(n); - - for(int i=1; i < index; i++) { - if(constants[i] instanceof ConstantFloat) { - ConstantFloat c = (ConstantFloat)constants[i]; - - if(Float.floatToIntBits(c.getBytes()) == bits) - return i; - } + /** + * Initialize with given constant pool. + */ + public ConstantPoolGen(final ConstantPool cp) { + this(cp.getConstantPool()); } - return -1; - } - - /** - * Add a new Float constant to the ConstantPool, if it is not already in there. - * - * @param n Float number to add - * @return index of entry - */ - public int addFloat(float n) { - int ret; - - if((ret = lookupFloat(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index++] = new ConstantFloat(n); - - return ret; - } - - private HashMap utf8_table = new HashMap(); - - /** - * Look for ConstantUtf8 in ConstantPool. - * - * @param n Utf8 string to look for - * @return index on success, -1 otherwise - */ - public int lookupUtf8(String n) { - Index index = (Index)utf8_table.get(n); - - return (index != null)? index.index : -1; - } - - /** - * Add a new Utf8 constant to the ConstantPool, if it is not already in there. - * - * @param n Utf8 string to add - * @return index of entry - */ - public int addUtf8(String n) { - int ret; - - if((ret = lookupUtf8(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index++] = new ConstantUtf8(n); - - utf8_table.put(n, new Index(ret)); - - return ret; - } - - /** - * Look for ConstantLong in ConstantPool. - * - * @param n Long number to look for - * @return index on success, -1 otherwise - */ - public int lookupLong(long n) { - for(int i=1; i < index; i++) { - if(constants[i] instanceof ConstantLong) { - ConstantLong c = (ConstantLong)constants[i]; - - if(c.getBytes() == n) - return i; - } + /** + * Create empty constant pool. + */ + public ConstantPoolGen() { + size = DEFAULT_BUFFER_SIZE; + constants = new Constant[size]; } - return -1; - } - - /** - * Add a new long constant to the ConstantPool, if it is not already in there. - * - * @param n Long number to add - * @return index of entry - */ - public int addLong(long n) { - int ret; - - if((ret = lookupLong(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index] = new ConstantLong(n); - index += 2; // Wastes one entry according to spec - - return ret; - } - - /** - * Look for ConstantDouble in ConstantPool. - * - * @param n Double number to look for - * @return index on success, -1 otherwise - */ - public int lookupDouble(double n) { - long bits = Double.doubleToLongBits(n); - - for(int i=1; i < index; i++) { - if(constants[i] instanceof ConstantDouble) { - ConstantDouble c = (ConstantDouble)constants[i]; - - if(Double.doubleToLongBits(c.getBytes()) == bits) - return i; - } + /** + * Resize internal array of constants. + */ + protected void adjustSize() { + if (index + 3 >= size) { + final Constant[] cs = constants; + size *= 2; + constants = new Constant[size]; + System.arraycopy(cs, 0, constants, 0, index); + } } - return -1; - } + private final Map string_table = new HashMap<>(); - /** - * Add a new double constant to the ConstantPool, if it is not already in there. - * - * @param n Double number to add - * @return index of entry - */ - public int addDouble(double n) { - int ret; - - if((ret = lookupDouble(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index] = new ConstantDouble(n); - index += 2; // Wastes one entry according to spec - - return ret; - } - - private HashMap n_a_t_table = new HashMap(); - - /** - * Look for ConstantNameAndType in ConstantPool. - * - * @param name of variable/method - * @param signature of variable/method - * @return index on success, -1 otherwise - */ - public int lookupNameAndType(String name, String signature) { - Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature); - return (index != null)? index.index : -1; - } - - /** - * Add a new NameAndType constant to the ConstantPool if it is not already - * in there. - * - * @param n NameAndType string to add - * @return index of entry - */ - public int addNameAndType(String name, String signature) { - int ret; - int name_index, signature_index; - - if((ret = lookupNameAndType(name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - name_index = addUtf8(name); - signature_index = addUtf8(signature); - ret = index; - constants[index++] = new ConstantNameAndType(name_index, signature_index); - - n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret)); - return ret; - } - - private HashMap cp_table = new HashMap(); - - /** - * Look for ConstantMethodref in ConstantPool. - * - * @param class_name Where to find method - * @param method_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupMethodref(String class_name, String method_name, String signature) { - Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name + - METHODREF_DELIM + signature); - return (index != null)? index.index : -1; - } - - public int lookupMethodref(MethodGen method) { - return lookupMethodref(method.getClassName(), method.getName(), - method.getSignature()); - } - - /** - * Add a new Methodref constant to the ConstantPool, if it is not already - * in there. - * - * @param n Methodref string to add - * @return index of entry - */ - public int addMethodref(String class_name, String method_name, String signature) { - int ret, class_index, name_and_type_index; - - if((ret = lookupMethodref(class_name, method_name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - name_and_type_index = addNameAndType(method_name, signature); - class_index = addClass(class_name); - ret = index; - constants[index++] = new ConstantMethodref(class_index, name_and_type_index); - - cp_table.put(class_name + METHODREF_DELIM + method_name + - METHODREF_DELIM + signature, new Index(ret)); - - return ret; - } - - public int addMethodref(MethodGen method) { - return addMethodref(method.getClassName(), method.getName(), - method.getSignature()); - } - - /** - * Look for ConstantInterfaceMethodref in ConstantPool. - * - * @param class_name Where to find method - * @param method_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupInterfaceMethodref(String class_name, String method_name, String signature) { - Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name + - IMETHODREF_DELIM + signature); - return (index != null)? index.index : -1; - } - - public int lookupInterfaceMethodref(MethodGen method) { - return lookupInterfaceMethodref(method.getClassName(), method.getName(), - method.getSignature()); - } - - /** - * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already - * in there. - * - * @param n InterfaceMethodref string to add - * @return index of entry - */ - public int addInterfaceMethodref(String class_name, String method_name, String signature) { - int ret, class_index, name_and_type_index; - - if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - class_index = addClass(class_name); - name_and_type_index = addNameAndType(method_name, signature); - ret = index; - constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); - - cp_table.put(class_name + IMETHODREF_DELIM + method_name + - IMETHODREF_DELIM + signature, new Index(ret)); - - return ret; - } - - public int addInterfaceMethodref(MethodGen method) { - return addInterfaceMethodref(method.getClassName(), method.getName(), - method.getSignature()); - } - - /** - * Look for ConstantFieldref in ConstantPool. - * - * @param class_name Where to find method - * @param field_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupFieldref(String class_name, String field_name, String signature) { - Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name + - FIELDREF_DELIM + signature); - return (index != null)? index.index : -1; - } - - /** - * Add a new Fieldref constant to the ConstantPool, if it is not already - * in there. - * - * @param n Fieldref string to add - * @return index of entry - */ - public int addFieldref(String class_name, String field_name, String signature) { - int ret; - int class_index, name_and_type_index; - - if((ret = lookupFieldref(class_name, field_name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - class_index = addClass(class_name); - name_and_type_index = addNameAndType(field_name, signature); - ret = index; - constants[index++] = new ConstantFieldref(class_index, name_and_type_index); - - cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret)); - - return ret; - } - - /** - * @param i index in constant pool - * @return constant pool entry at index i - */ - public Constant getConstant(int i) { return constants[i]; } - - /** - * Use with care! - * - * @param i index in constant pool - * @param c new constant pool entry at index i - */ - public void setConstant(int i, Constant c) { constants[i] = c; } - - /** - * @return intermediate constant pool - */ - public ConstantPool getConstantPool() { - return new ConstantPool(constants); - } - - /** - * @return current size of constant pool - */ - public int getSize() { - return index; - } - - /** - * @return constant pool with proper length - */ - public ConstantPool getFinalConstantPool() { - Constant[] cs = new Constant[index]; - - System.arraycopy(constants, 0, cs, 0, index); - - return new ConstantPool(cs); - } - - /** - * @return String representation. - */ - public String toString() { - StringBuffer buf = new StringBuffer(); - - for(int i=1; i < index; i++) - buf.append(i + ")" + constants[i] + "\n"); - - return buf.toString(); - } - - /** Import constant from another ConstantPool and return new index. - */ - public int addConstant(Constant c, ConstantPoolGen cp) { - Constant[] constants = cp.getConstantPool().getConstantPool(); - - switch(c.getTag()) { - case Constants.CONSTANT_String: { - ConstantString s = (ConstantString)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; - - return addString(u8.getBytes()); + /** + * Look for ConstantString in ConstantPool containing String `str'. + * + * @param str String to search for + * @return index on success, -1 otherwise + */ + public int lookupString(final String str) { + final Index index = string_table.get(str); + return (index != null) ? index.index : -1; } - case Constants.CONSTANT_Class: { - ConstantClass s = (ConstantClass)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; - - return addClass(u8.getBytes()); + /** + * Add a new String constant to the ConstantPool, if it is not already in + * there. + * + * @param str String to add + * @return index of entry + */ + public int addString(final String str) { + int ret; + if ((ret = lookupString(str)) != -1) { + return ret; // Already in CP + } + final int utf8 = addUtf8(str); + adjustSize(); + final ConstantString s = new ConstantString(utf8); + ret = index; + constants[index++] = s; + if (!string_table.containsKey(str)) { + string_table.put(str, new Index(ret)); + } + return ret; } - case Constants.CONSTANT_NameAndType: { - ConstantNameAndType n = (ConstantNameAndType)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; - ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; + private final Map class_table = new HashMap<>(); - return addNameAndType(u8.getBytes(), u8_2.getBytes()); + /** + * Look for ConstantClass in ConstantPool named `str'. + * + * @param str String to search for + * @return index on success, -1 otherwise + */ + public int lookupClass(final String str) { + final Index index = class_table.get(str.replace('.', '/')); + return (index != null) ? index.index : -1; } - case Constants.CONSTANT_Utf8: - return addUtf8(((ConstantUtf8)c).getBytes()); - - case Constants.CONSTANT_Double: - return addDouble(((ConstantDouble)c).getBytes()); - - case Constants.CONSTANT_Float: - return addFloat(((ConstantFloat)c).getBytes()); - - case Constants.CONSTANT_Long: - return addLong(((ConstantLong)c).getBytes()); - - case Constants.CONSTANT_Integer: - return addInteger(((ConstantInteger)c).getBytes()); - - case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref: - case Constants.CONSTANT_Fieldref: { - ConstantCP m = (ConstantCP)c; - ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; - ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; - ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; - String class_name = u8.getBytes().replace('/', '.'); - - u8 = (ConstantUtf8)constants[n.getNameIndex()]; - String name = u8.getBytes(); - - u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; - String signature = u8.getBytes(); - - switch(c.getTag()) { - case Constants.CONSTANT_InterfaceMethodref: - return addInterfaceMethodref(class_name, name, signature); - - case Constants.CONSTANT_Methodref: - return addMethodref(class_name, name, signature); - - case Constants.CONSTANT_Fieldref: - return addFieldref(class_name, name, signature); - - default: // Never reached - throw new RuntimeException("Unknown constant type " + c); - } + private int addClass_(final String clazz) { + int ret; + if ((ret = lookupClass(clazz)) != -1) { + return ret; // Already in CP + } + adjustSize(); + final ConstantClass c = new ConstantClass(addUtf8(clazz)); + ret = index; + constants[index++] = c; + if (!class_table.containsKey(clazz)) { + class_table.put(clazz, new Index(ret)); + } + return ret; } - default: // Never reached - throw new RuntimeException("Unknown constant type " + c); + /** + * Add a new Class reference to the ConstantPool, if it is not already in + * there. + * + * @param str Class to add + * @return index of entry + */ + public int addClass(final String str) { + return addClass_(str.replace('.', '/')); + } + + /** + * Add a new Class reference to the ConstantPool for a given type. + * + * @param type Class to add + * @return index of entry + */ + public int addClass(final ObjectType type) { + return addClass(type.getClassName()); + } + + /** + * Add a reference to an array class (e.g. String[][]) as needed by + * MULTIANEWARRAY instruction, e.g. to the ConstantPool. + * + * @param type type of array class + * @return index of entry + */ + public int addArrayClass(final ArrayType type) { + return addClass_(type.getSignature()); + } + + /** + * Look for ConstantInteger in ConstantPool. + * + * @param n integer number to look for + * @return index on success, -1 otherwise + */ + public int lookupInteger(final int n) { + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantInteger) { + final ConstantInteger c = (ConstantInteger) constants[i]; + if (c.getBytes() == n) { + return i; + } + } + } + return -1; + } + + /** + * Add a new Integer constant to the ConstantPool, if it is not already in + * there. + * + * @param n integer number to add + * @return index of entry + */ + public int addInteger(final int n) { + int ret; + if ((ret = lookupInteger(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantInteger(n); + return ret; + } + + /** + * Look for ConstantFloat in ConstantPool. + * + * @param n Float number to look for + * @return index on success, -1 otherwise + */ + public int lookupFloat(final float n) { + final int bits = Float.floatToIntBits(n); + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantFloat) { + final ConstantFloat c = (ConstantFloat) constants[i]; + if (Float.floatToIntBits(c.getBytes()) == bits) { + return i; + } + } + } + return -1; + } + + /** + * Add a new Float constant to the ConstantPool, if it is not already in + * there. + * + * @param n Float number to add + * @return index of entry + */ + public int addFloat(final float n) { + int ret; + if ((ret = lookupFloat(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantFloat(n); + return ret; + } + + private final Map utf8_table = new HashMap<>(); + + /** + * Look for ConstantUtf8 in ConstantPool. + * + * @param n Utf8 string to look for + * @return index on success, -1 otherwise + */ + public int lookupUtf8(final String n) { + final Index index = utf8_table.get(n); + return (index != null) ? index.index : -1; + } + + /** + * Add a new Utf8 constant to the ConstantPool, if it is not already in + * there. + * + * @param n Utf8 string to add + * @return index of entry + */ + public int addUtf8(final String n) { + int ret; + if ((ret = lookupUtf8(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantUtf8(n); + if (!utf8_table.containsKey(n)) { + utf8_table.put(n, new Index(ret)); + } + return ret; + } + + /** + * Look for ConstantLong in ConstantPool. + * + * @param n Long number to look for + * @return index on success, -1 otherwise + */ + public int lookupLong(final long n) { + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantLong) { + final ConstantLong c = (ConstantLong) constants[i]; + if (c.getBytes() == n) { + return i; + } + } + } + return -1; + } + + /** + * Add a new long constant to the ConstantPool, if it is not already in + * there. + * + * @param n Long number to add + * @return index of entry + */ + public int addLong(final long n) { + int ret; + if ((ret = lookupLong(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index] = new ConstantLong(n); + index += 2; // Wastes one entry according to spec + return ret; + } + + /** + * Look for ConstantDouble in ConstantPool. + * + * @param n Double number to look for + * @return index on success, -1 otherwise + */ + public int lookupDouble(final double n) { + final long bits = Double.doubleToLongBits(n); + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantDouble) { + final ConstantDouble c = (ConstantDouble) constants[i]; + if (Double.doubleToLongBits(c.getBytes()) == bits) { + return i; + } + } + } + return -1; + } + + /** + * Add a new double constant to the ConstantPool, if it is not already in + * there. + * + * @param n Double number to add + * @return index of entry + */ + public int addDouble(final double n) { + int ret; + if ((ret = lookupDouble(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index] = new ConstantDouble(n); + index += 2; // Wastes one entry according to spec + return ret; + } + + private final Map n_a_t_table = new HashMap<>(); + + /** + * Look for ConstantNameAndType in ConstantPool. + * + * @param name of variable/method + * @param signature of variable/method + * @return index on success, -1 otherwise + */ + public int lookupNameAndType(final String name, final String signature) { + final Index _index = n_a_t_table.get(name + NAT_DELIM + signature); + return (_index != null) ? _index.index : -1; + } + + /** + * Add a new NameAndType constant to the ConstantPool if it is not already + * in there. + * + * @param name Name string to add + * @param signature signature string to add + * @return index of entry + */ + public int addNameAndType(final String name, final String signature) { + int ret; + int name_index; + int signature_index; + if ((ret = lookupNameAndType(name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + name_index = addUtf8(name); + signature_index = addUtf8(signature); + ret = index; + constants[index++] = new ConstantNameAndType(name_index, signature_index); + final String key = name + NAT_DELIM + signature; + if (!n_a_t_table.containsKey(key)) { + n_a_t_table.put(key, new Index(ret)); + } + return ret; + } + + private final Map cp_table = new HashMap<>(); + + /** + * Look for ConstantMethodref in ConstantPool. + * + * @param class_name Where to find method + * @param method_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupMethodref(final String class_name, final String method_name, final String signature) { + final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name + + METHODREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + public int lookupMethodref(final MethodGen method) { + return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); + } + + /** + * Add a new Methodref constant to the ConstantPool, if it is not already in + * there. + * + * @param class_name class name string to add + * @param method_name method name string to add + * @param signature method signature string to add + * @return index of entry + */ + public int addMethodref(final String class_name, final String method_name, final String signature) { + int ret; + int class_index; + int name_and_type_index; + if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + name_and_type_index = addNameAndType(method_name, signature); + class_index = addClass(class_name); + ret = index; + constants[index++] = new ConstantMethodref(class_index, name_and_type_index); + final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + public int addMethodref(final MethodGen method) { + return addMethodref(method.getClassName(), method.getName(), method.getSignature()); + } + + /** + * Look for ConstantInterfaceMethodref in ConstantPool. + * + * @param class_name Where to find method + * @param method_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupInterfaceMethodref(final String class_name, final String method_name, final String signature) { + final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name + + IMETHODREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + public int lookupInterfaceMethodref(final MethodGen method) { + return lookupInterfaceMethodref(method.getClassName(), method.getName(), method + .getSignature()); + } + + /** + * Add a new InterfaceMethodref constant to the ConstantPool, if it is not + * already in there. + * + * @param class_name class name string to add + * @param method_name method name string to add + * @param signature signature string to add + * @return index of entry + */ + public int addInterfaceMethodref(final String class_name, final String method_name, final String signature) { + int ret; + int class_index; + int name_and_type_index; + if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + class_index = addClass(class_name); + name_and_type_index = addNameAndType(method_name, signature); + ret = index; + constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); + final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + public int addInterfaceMethodref(final MethodGen method) { + return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); + } + + /** + * Look for ConstantFieldref in ConstantPool. + * + * @param class_name Where to find method + * @param field_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupFieldref(final String class_name, final String field_name, final String signature) { + final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name + + FIELDREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + /** + * Add a new Fieldref constant to the ConstantPool, if it is not already in + * there. + * + * @param class_name class name string to add + * @param field_name field name string to add + * @param signature signature string to add + * @return index of entry + */ + public int addFieldref(final String class_name, final String field_name, final String signature) { + int ret; + int class_index; + int name_and_type_index; + if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + class_index = addClass(class_name); + name_and_type_index = addNameAndType(field_name, signature); + ret = index; + constants[index++] = new ConstantFieldref(class_index, name_and_type_index); + final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + /** + * @param i index in constant pool + * @return constant pool entry at index i + */ + public Constant getConstant(final int i) { + return constants[i]; + } + + /** + * Use with care! + * + * @param i index in constant pool + * @param c new constant pool entry at index i + */ + public void setConstant(final int i, final Constant c) { + constants[i] = c; + } + + /** + * @return intermediate constant pool + */ + public ConstantPool getConstantPool() { + return new ConstantPool(constants); + } + + /** + * @return current size of constant pool + */ + public int getSize() { + return index; + } + + /** + * @return constant pool with proper length + */ + public ConstantPool getFinalConstantPool() { + final Constant[] cs = new Constant[index]; + System.arraycopy(constants, 0, cs, 0, index); + return new ConstantPool(cs); + } + + /** + * @return String representation. + */ + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + for (int i = 1; i < index; i++) { + buf.append(i).append(")").append(constants[i]).append("\n"); + } + return buf.toString(); + } + + /** + * Import constant from another ConstantPool and return new index. + */ + public int addConstant(final Constant c, final ConstantPoolGen cp) { + final Constant[] constants = cp.getConstantPool().getConstantPool(); + switch (c.getTag()) { + case Const.CONSTANT_String: { + final ConstantString s = (ConstantString) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; + return addString(u8.getBytes()); + } + case Const.CONSTANT_Class: { + final ConstantClass s = (ConstantClass) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; + return addClass(u8.getBytes()); + } + case Const.CONSTANT_NameAndType: { + final ConstantNameAndType n = (ConstantNameAndType) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; + return addNameAndType(u8.getBytes(), u8_2.getBytes()); + } + case Const.CONSTANT_Utf8: + return addUtf8(((ConstantUtf8) c).getBytes()); + case Const.CONSTANT_Double: + return addDouble(((ConstantDouble) c).getBytes()); + case Const.CONSTANT_Float: + return addFloat(((ConstantFloat) c).getBytes()); + case Const.CONSTANT_Long: + return addLong(((ConstantLong) c).getBytes()); + case Const.CONSTANT_Integer: + return addInteger(((ConstantInteger) c).getBytes()); + case Const.CONSTANT_InterfaceMethodref: + case Const.CONSTANT_Methodref: + case Const.CONSTANT_Fieldref: { + final ConstantCP m = (ConstantCP) c; + final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; + ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + final String class_name = u8.getBytes().replace('/', '.'); + u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final String name = u8.getBytes(); + u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; + final String signature = u8.getBytes(); + switch (c.getTag()) { + case Const.CONSTANT_InterfaceMethodref: + return addInterfaceMethodref(class_name, name, signature); + case Const.CONSTANT_Methodref: + return addMethodref(class_name, name, signature); + case Const.CONSTANT_Fieldref: + return addFieldref(class_name, name, signature); + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } + } + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java index f5fdaa11541..78273d2600c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java @@ -21,16 +21,16 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes a push instruction that produces a literal on the stack * such as SIPUSH, BIPUSH, ICONST, etc. * - * @author M. Dahm + * @version $Id: ConstantPushInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see ICONST * @see SIPUSH */ public interface ConstantPushInstruction extends PushInstruction, TypedInstruction { - public Number getValue(); + + Number getValue(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java index 2a1d8b6c2c3..032880888ce 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java @@ -21,48 +21,62 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; + /** * Super class for the x2y family of instructions. * - * @author M. Dahm + * @version $Id: ConversionInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class ConversionInstruction extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ConversionInstruction() {} +public abstract class ConversionInstruction extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - /** - * @param opcode opcode of instruction - */ - protected ConversionInstruction(short opcode) { - super(opcode, (short)1); - } - - /** @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - switch(opcode) { - case Constants.D2I: case Constants.F2I: case Constants.L2I: - return Type.INT; - case Constants.D2F: case Constants.I2F: case Constants.L2F: - return Type.FLOAT; - case Constants.D2L: case Constants.F2L: case Constants.I2L: - return Type.LONG; - case Constants.F2D: case Constants.I2D: case Constants.L2D: - return Type.DOUBLE; - case Constants.I2B: - return Type.BYTE; - case Constants.I2C: - return Type.CHAR; - case Constants.I2S: - return Type.SHORT; - - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ConversionInstruction() { + } + + + /** + * @param opcode opcode of instruction + */ + protected ConversionInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + /** @return type associated with the instruction + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + final short _opcode = super.getOpcode(); + switch (_opcode) { + case Const.D2I: + case Const.F2I: + case Const.L2I: + return Type.INT; + case Const.D2F: + case Const.I2F: + case Const.L2F: + return Type.FLOAT; + case Const.D2L: + case Const.F2L: + case Const.I2L: + return Type.LONG; + case Const.F2D: + case Const.I2D: + case Const.L2D: + return Type.DOUBLE; + case Const.I2B: + return Type.BYTE; + case Const.I2C: + return Type.CHAR; + case Const.I2S: + return Type.SHORT; + default: // Never reached + throw new ClassGenException("Unknown type " + _opcode); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java index 1d5cda8ae83..51fbfa9a19b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * D2F - Convert double to float *
    Stack: ..., value.word1, value.word2 -> ..., result
    * - * @author M. Dahm + * @version $Id: D2F.java 1747278 2016-06-07 17:28:43Z britter $ */ public class D2F extends ConversionInstruction { - /** Convert double to float - */ - public D2F() { - super(com.sun.org.apache.bcel.internal.Constants.D2F); - } + + /** Convert double to float + */ + public D2F() { + super(com.sun.org.apache.bcel.internal.Const.D2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2F(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2F(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java index cdc20b64f0e..2b817ff772c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * D2I - Convert double to int *
    Stack: ..., value.word1, value.word2 -> ..., result
    * - * @author M. Dahm + * @version $Id: D2I.java 1747278 2016-06-07 17:28:43Z britter $ */ public class D2I extends ConversionInstruction { - /** Convert double to int - */ - public D2I() { - super(com.sun.org.apache.bcel.internal.Constants.D2I); - } + + /** Convert double to int + */ + public D2I() { + super(com.sun.org.apache.bcel.internal.Const.D2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2I(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2I(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java index 3774d4826fa..989595fe891 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * D2L - Convert double to long *
    Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: D2L.java 1747278 2016-06-07 17:28:43Z britter $ */ public class D2L extends ConversionInstruction { - /** Convert double to long - */ - public D2L() { - super(com.sun.org.apache.bcel.internal.Constants.D2L); - } + + /** Convert double to long + */ + public D2L() { + super(com.sun.org.apache.bcel.internal.Const.D2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2L(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2L(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java index af23bf2c94f..f89b99d4cc2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DADD - Add doubles *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result1.word2 * - * @author M. Dahm + * @version $Id: DADD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DADD extends ArithmeticInstruction { - /** Add doubles - */ - public DADD() { - super(com.sun.org.apache.bcel.internal.Constants.DADD); - } + + /** Add doubles + */ + public DADD() { + super(com.sun.org.apache.bcel.internal.Const.DADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDADD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDADD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java index a414eb01432..95055ff002b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DALOAD - Load double from array *
    Stack: ..., arrayref, index -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: DALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DALOAD extends ArrayInstruction implements StackProducer { - /** Load double from array - */ - public DALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.DALOAD); - } + + /** Load double from array + */ + public DALOAD() { + super(com.sun.org.apache.bcel.internal.Const.DALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitDALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitDALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java index c100ead3e54..ad6d09e48e5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DASTORE - Store into double array *
    Stack: ..., arrayref, index, value.word1, value.word2 -> ...
    * - * @author M. Dahm + * @version $Id: DASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DASTORE extends ArrayInstruction implements StackConsumer { - /** Store double into array - */ - public DASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.DASTORE); - } + + /** Store double into array + */ + public DASTORE() { + super(com.sun.org.apache.bcel.internal.Const.DASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitDASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitDASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java index 1d447c93062..2b74d2b3d04 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java @@ -21,40 +21,38 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * DCMPG - Compare doubles: value1 > value2 - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result + * DCMPG - Compare doubles: value1 > value2 + *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result
    * - * @author M. Dahm + * @version $Id: DCMPG.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class DCMPG extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { +public class DCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - public DCMPG() { - super(com.sun.org.apache.bcel.internal.Constants.DCMPG, (short)1); - } + public DCMPG() { + super(com.sun.org.apache.bcel.internal.Const.DCMPG, (short) 1); + } - /** @return Type.DOUBLE - */ - public Type getType(ConstantPoolGen cp) { - return Type.DOUBLE; - } + /** @return Type.DOUBLE + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.DOUBLE; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitDCMPG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitDCMPG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java index 3874a682fe6..c466e79e30e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java @@ -21,39 +21,38 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * DCMPL - Compare doubles: value1 < value2 - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result + * DCMPL - Compare doubles: value1 < value2 + *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result
    * - * @author M. Dahm + * @version $Id: DCMPL.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class DCMPL extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - public DCMPL() { - super(com.sun.org.apache.bcel.internal.Constants.DCMPL, (short)1); - } +public class DCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - /** @return Type.DOUBLE - */ - public Type getType(ConstantPoolGen cp) { - return Type.DOUBLE; - } + public DCMPL() { + super(com.sun.org.apache.bcel.internal.Const.DCMPL, (short) 1); + } + /** @return Type.DOUBLE + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.DOUBLE; + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitDCMPL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitDCMPL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java index af6154b7659..ed46bfe61b5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java @@ -20,58 +20,67 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DCONST - Push 0.0 or 1.0, other values cause an exception * *
    Stack: ... -> ..., 
    * - * @author M. Dahm + * @version $Id: DCONST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class DCONST extends Instruction - implements ConstantPushInstruction, TypedInstruction { - private double value; +public class DCONST extends Instruction implements ConstantPushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DCONST() {} + private double value; - public DCONST(double f) { - super(com.sun.org.apache.bcel.internal.Constants.DCONST_0, (short)1); - if(f == 0.0) - opcode = com.sun.org.apache.bcel.internal.Constants.DCONST_0; - else if(f == 1.0) - opcode = com.sun.org.apache.bcel.internal.Constants.DCONST_1; - else - throw new ClassGenException("DCONST can be used only for 0.0 and 1.0: " + f); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DCONST() { + } - value = f; - } - public Number getValue() { return Double.valueOf(value); } + public DCONST(final double f) { + super(com.sun.org.apache.bcel.internal.Const.DCONST_0, (short) 1); + if (f == 0.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.DCONST_0); + } else if (f == 1.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.DCONST_1); + } else { + throw new ClassGenException("DCONST can be used only for 0.0 and 1.0: " + f); + } + value = f; + } - /** @return Type.DOUBLE - */ - public Type getType(ConstantPoolGen cp) { - return Type.DOUBLE; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitDCONST(this); - } + @Override + public Number getValue() { + return new Double(value); + } + + + /** @return Type.DOUBLE + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.DOUBLE; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitDCONST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java index 1c91493800f..5c794664d70 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DDIV - Divide doubles *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: DDIV.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DDIV extends ArithmeticInstruction { - /** Divide doubles - */ - public DDIV() { - super(com.sun.org.apache.bcel.internal.Constants.DDIV); - } + + /** Divide doubles + */ + public DDIV() { + super(com.sun.org.apache.bcel.internal.Const.DDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDDIV(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDDIV(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java index 3e83f1edb30..5f90cfa61c5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DLOAD - Load double from local variable *
    Stack ... -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: DLOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DLOAD() { - super(com.sun.org.apache.bcel.internal.Constants.DLOAD, com.sun.org.apache.bcel.internal.Constants.DLOAD_0); - } - /** Load double from local variable - * @param n index of local variable - */ - public DLOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.DLOAD, com.sun.org.apache.bcel.internal.Constants.DLOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DLOAD() { + super(com.sun.org.apache.bcel.internal.Const.DLOAD, com.sun.org.apache.bcel.internal.Const.DLOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitDLOAD(this); - } + + /** Load double from local variable + * @param n index of local variable + */ + public DLOAD(final int n) { + super(com.sun.org.apache.bcel.internal.Const.DLOAD, com.sun.org.apache.bcel.internal.Const.DLOAD_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitDLOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java index 908dec0da4f..f48d8c298be 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DMUL - Multiply doubles *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: DMUL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DMUL extends ArithmeticInstruction { - /** Multiply doubles - */ - public DMUL() { - super(com.sun.org.apache.bcel.internal.Constants.DMUL); - } + + /** Multiply doubles + */ + public DMUL() { + super(com.sun.org.apache.bcel.internal.Const.DMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDMUL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java index 48becc3d66a..67d19fe8388 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DNEG - Negate double *
    Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: DNEG.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DNEG extends ArithmeticInstruction { - public DNEG() { - super(com.sun.org.apache.bcel.internal.Constants.DNEG); - } + + public DNEG() { + super(com.sun.org.apache.bcel.internal.Const.DNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDNEG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java index d1f0bd09d03..e11598af13a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DREM - Remainder of doubles *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: DREM.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DREM extends ArithmeticInstruction { - /** Remainder of doubles - */ - public DREM() { - super(com.sun.org.apache.bcel.internal.Constants.DREM); - } + + /** Remainder of doubles + */ + public DREM() { + super(com.sun.org.apache.bcel.internal.Const.DREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDREM(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDREM(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java index 7c4906e8c5d..76fa2260aae 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DRETURN - Return double from method *
    Stack: ..., value.word1, value.word2 -> <empty>
    * - * @author M. Dahm + * @version $Id: DRETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DRETURN extends ReturnInstruction { - /** Return double from method - */ - public DRETURN() { - super(com.sun.org.apache.bcel.internal.Constants.DRETURN); - } + + /** Return double from method + */ + public DRETURN() { + super(com.sun.org.apache.bcel.internal.Const.DRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitDRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitDRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java index ada5407136f..e8d5808cb3e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DSTORE - Store double into local variable *
    Stack: ..., value.word1, value.word2 -> ... 
    * - * @author M. Dahm + * @version $Id: DSTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DSTORE() { - super(com.sun.org.apache.bcel.internal.Constants.DSTORE, com.sun.org.apache.bcel.internal.Constants.DSTORE_0); - } - /** Store double into local variable - * @param n index of local variable - */ - public DSTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.DSTORE, com.sun.org.apache.bcel.internal.Constants.DSTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DSTORE() { + super(com.sun.org.apache.bcel.internal.Const.DSTORE, com.sun.org.apache.bcel.internal.Const.DSTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitDSTORE(this); - } + + /** Store double into local variable + * @param n index of local variable + */ + public DSTORE(final int n) { + super(com.sun.org.apache.bcel.internal.Const.DSTORE, com.sun.org.apache.bcel.internal.Const.DSTORE_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitDSTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java index 8d6a311d6aa..74984517753 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DSUB - Substract doubles *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: DSUB.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DSUB extends ArithmeticInstruction { - /** Substract doubles - */ - public DSUB() { - super(com.sun.org.apache.bcel.internal.Constants.DSUB); - } + + /** Substract doubles + */ + public DSUB() { + super(com.sun.org.apache.bcel.internal.Const.DSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDSUB(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java index 2d61cf06218..22dcebfa689 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java @@ -21,31 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP - Duplicate top operand stack word *
    Stack: ..., word -> ..., word, word
    * - * @author M. Dahm + * @version $Id: DUP.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP extends StackInstruction implements PushInstruction { - public DUP() { - super(com.sun.org.apache.bcel.internal.Constants.DUP); - } + + public DUP() { + super(com.sun.org.apache.bcel.internal.Const.DUP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitStackInstruction(this); - v.visitDUP(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitStackInstruction(this); + v.visitDUP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java index a44f07814e6..1600d0bbf65 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java @@ -21,31 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP2 - Duplicate two top operand stack words *
    Stack: ..., word2, word1 -> ..., word2, word1, word2, word1
    * - * @author M. Dahm + * @version $Id: DUP2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP2 extends StackInstruction implements PushInstruction { - public DUP2() { - super(com.sun.org.apache.bcel.internal.Constants.DUP2); - } + + public DUP2() { + super(com.sun.org.apache.bcel.internal.Const.DUP2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitStackInstruction(this); - v.visitDUP2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitStackInstruction(this); + v.visitDUP2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java index b0b6d4c6fe2..bc73db971cf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java @@ -21,29 +21,30 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP2_X1 - Duplicate two top operand stack words and put three down *
    Stack: ..., word3, word2, word1 -> ..., word2, word1, word3, word2, word1
    * - * @author M. Dahm + * @version $Id: DUP2_X1.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP2_X1 extends StackInstruction { - public DUP2_X1() { - super(com.sun.org.apache.bcel.internal.Constants.DUP2_X1); - } + + public DUP2_X1() { + super(com.sun.org.apache.bcel.internal.Const.DUP2_X1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackInstruction(this); - v.visitDUP2_X1(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackInstruction(this); + v.visitDUP2_X1(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java index 4e394bc4012..6feba7b32ee 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java @@ -21,29 +21,30 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP2_X2 - Duplicate two top operand stack words and put four down *
    Stack: ..., word4, word3, word2, word1 -> ..., word2, word1, word4, word3, word2, word1
    * - * @author M. Dahm + * @version $Id: DUP2_X2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP2_X2 extends StackInstruction { - public DUP2_X2() { - super(com.sun.org.apache.bcel.internal.Constants.DUP2_X2); - } + + public DUP2_X2() { + super(com.sun.org.apache.bcel.internal.Const.DUP2_X2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackInstruction(this); - v.visitDUP2_X2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackInstruction(this); + v.visitDUP2_X2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java index ee895c6571c..357d091febf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java @@ -21,29 +21,30 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP_X1 - Duplicate top operand stack word and put two down *
    Stack: ..., word2, word1 -> ..., word1, word2, word1
    * - * @author M. Dahm + * @version $Id: DUP_X1.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP_X1 extends StackInstruction { - public DUP_X1() { - super(com.sun.org.apache.bcel.internal.Constants.DUP_X1); - } + + public DUP_X1() { + super(com.sun.org.apache.bcel.internal.Const.DUP_X1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackInstruction(this); - v.visitDUP_X1(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackInstruction(this); + v.visitDUP_X1(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java index 5d86a30169b..b6529072a89 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java @@ -21,29 +21,30 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP_X2 - Duplicate top operand stack word and put three down *
    Stack: ..., word3, word2, word1 -> ..., word1, word3, word2, word1
    * - * @author M. Dahm + * @version $Id: DUP_X2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP_X2 extends StackInstruction { - public DUP_X2() { - super(com.sun.org.apache.bcel.internal.Constants.DUP_X2); - } + + public DUP_X2() { + super(com.sun.org.apache.bcel.internal.Const.DUP_X2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackInstruction(this); - v.visitDUP_X2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackInstruction(this); + v.visitDUP_X2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java new file mode 100644 index 00000000000..f6a8ace0583 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.AnnotationElementValue; +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.ArrayElementValue; +import com.sun.org.apache.bcel.internal.classfile.ClassElementValue; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; +import com.sun.org.apache.bcel.internal.classfile.EnumElementValue; +import com.sun.org.apache.bcel.internal.classfile.SimpleElementValue; + +/** + * @since 6.0 + */ +public abstract class ElementValueGen +{ + private final int type; + private final ConstantPoolGen cpGen; + + protected ElementValueGen(final int type, final ConstantPoolGen cpGen) + { + this.type = type; + this.cpGen = cpGen; + } + + /** + * Subtypes return an immutable variant of the ElementValueGen + */ + public abstract ElementValue getElementValue(); + + public int getElementValueType() + { + return type; + } + + public abstract String stringifyValue(); + + public abstract void dump(DataOutputStream dos) throws IOException; + + public static final int STRING = 's'; + + public static final int ENUM_CONSTANT = 'e'; + + public static final int CLASS = 'c'; + + public static final int ANNOTATION = '@'; + + public static final int ARRAY = '['; + + public static final int PRIMITIVE_INT = 'I'; + + public static final int PRIMITIVE_BYTE = 'B'; + + public static final int PRIMITIVE_CHAR = 'C'; + + public static final int PRIMITIVE_DOUBLE = 'D'; + + public static final int PRIMITIVE_FLOAT = 'F'; + + public static final int PRIMITIVE_LONG = 'J'; + + public static final int PRIMITIVE_SHORT = 'S'; + + public static final int PRIMITIVE_BOOLEAN = 'Z'; + + public static ElementValueGen readElementValue(final DataInput dis, + final ConstantPoolGen cpGen) throws IOException + { + final int type = dis.readUnsignedByte(); + switch (type) + { + case 'B': // byte + return new SimpleElementValueGen(PRIMITIVE_BYTE, dis + .readUnsignedShort(), cpGen); + case 'C': // char + return new SimpleElementValueGen(PRIMITIVE_CHAR, dis + .readUnsignedShort(), cpGen); + case 'D': // double + return new SimpleElementValueGen(PRIMITIVE_DOUBLE, dis + .readUnsignedShort(), cpGen); + case 'F': // float + return new SimpleElementValueGen(PRIMITIVE_FLOAT, dis + .readUnsignedShort(), cpGen); + case 'I': // int + return new SimpleElementValueGen(PRIMITIVE_INT, dis + .readUnsignedShort(), cpGen); + case 'J': // long + return new SimpleElementValueGen(PRIMITIVE_LONG, dis + .readUnsignedShort(), cpGen); + case 'S': // short + return new SimpleElementValueGen(PRIMITIVE_SHORT, dis + .readUnsignedShort(), cpGen); + case 'Z': // boolean + return new SimpleElementValueGen(PRIMITIVE_BOOLEAN, dis + .readUnsignedShort(), cpGen); + case 's': // String + return new SimpleElementValueGen(STRING, dis.readUnsignedShort(), + cpGen); + case 'e': // Enum constant + return new EnumElementValueGen(dis.readUnsignedShort(), dis + .readUnsignedShort(), cpGen); + case 'c': // Class + return new ClassElementValueGen(dis.readUnsignedShort(), cpGen); + case '@': // Annotation + // TODO: isRuntimeVisible ?????????? + // FIXME + return new AnnotationElementValueGen(ANNOTATION, + new AnnotationEntryGen(AnnotationEntry.read(dis, cpGen + .getConstantPool(), true), cpGen, false), cpGen); + case '[': // Array + final int numArrayVals = dis.readUnsignedShort(); + final ElementValue[] evalues = new ElementValue[numArrayVals]; + for (int j = 0; j < numArrayVals; j++) + { + evalues[j] = ElementValue.readElementValue(dis, cpGen + .getConstantPool()); + } + return new ArrayElementValueGen(ARRAY, evalues, cpGen); + default: + throw new RuntimeException("Unexpected element value kind in annotation: " + type); + } + } + + protected ConstantPoolGen getConstantPool() + { + return cpGen; + } + + /** + * Creates an (modifiable) ElementValueGen copy of an (immutable) + * ElementValue - constant pool is assumed correct. + */ + public static ElementValueGen copy(final ElementValue value, + final ConstantPoolGen cpool, final boolean copyPoolEntries) + { + switch (value.getElementValueType()) + { + case 'B': // byte + case 'C': // char + case 'D': // double + case 'F': // float + case 'I': // int + case 'J': // long + case 'S': // short + case 'Z': // boolean + case 's': // String + return new SimpleElementValueGen((SimpleElementValue) value, cpool, + copyPoolEntries); + case 'e': // Enum constant + return new EnumElementValueGen((EnumElementValue) value, cpool, + copyPoolEntries); + case '@': // Annotation + return new AnnotationElementValueGen( + (AnnotationElementValue) value, cpool, copyPoolEntries); + case '[': // Array + return new ArrayElementValueGen((ArrayElementValue) value, cpool, + copyPoolEntries); + case 'c': // Class + return new ClassElementValueGen((ClassElementValue) value, cpool, + copyPoolEntries); + default: + throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")"); + } + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java new file mode 100644 index 00000000000..5a928375174 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java @@ -0,0 +1,119 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; +import com.sun.org.apache.bcel.internal.classfile.ElementValuePair; + +/** + * @since 6.0 + */ +public class ElementValuePairGen +{ + private int nameIdx; + + private final ElementValueGen value; + + private final ConstantPoolGen cpool; + + public ElementValuePairGen(final ElementValuePair nvp, final ConstantPoolGen cpool, + final boolean copyPoolEntries) + { + this.cpool = cpool; + // J5ASSERT: + // Could assert nvp.getNameString() points to the same thing as + // cpool.getConstant(nvp.getNameIndex()) + // if + // (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes())) + // { + // throw new RuntimeException("envp buggered"); + // } + if (copyPoolEntries) + { + nameIdx = cpool.addUtf8(nvp.getNameString()); + } + else + { + nameIdx = nvp.getNameIndex(); + } + value = ElementValueGen.copy(nvp.getValue(), cpool, copyPoolEntries); + } + + /** + * Retrieve an immutable version of this ElementNameValuePairGen + */ + public ElementValuePair getElementNameValuePair() + { + final ElementValue immutableValue = value.getElementValue(); + return new ElementValuePair(nameIdx, immutableValue, cpool + .getConstantPool()); + } + + protected ElementValuePairGen(final int idx, final ElementValueGen value, + final ConstantPoolGen cpool) + { + this.nameIdx = idx; + this.value = value; + this.cpool = cpool; + } + + public ElementValuePairGen(final String name, final ElementValueGen value, + final ConstantPoolGen cpool) + { + this.nameIdx = cpool.addUtf8(name); + this.value = value; + this.cpool = cpool; + } + + protected void dump(final DataOutputStream dos) throws IOException + { + dos.writeShort(nameIdx); // u2 name of the element + value.dump(dos); + } + + public int getNameIndex() + { + return nameIdx; + } + + public final String getNameString() + { + // ConstantString cu8 = (ConstantString)cpool.getConstant(nameIdx); + return ((ConstantUtf8) cpool.getConstant(nameIdx)).getBytes(); + } + + public final ElementValueGen getValue() + { + return value; + } + + @Override + public String toString() + { + return "ElementValuePair:[" + getNameString() + "=" + + value.stringifyValue() + "]"; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java index 275af64d69f..78476f73250 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java @@ -21,191 +21,916 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Supplies empty method bodies to be overridden by subclasses. * - * @author M. Dahm + * @version $Id: EmptyVisitor.java 1747278 2016-06-07 17:28:43Z britter $ */ public abstract class EmptyVisitor implements Visitor { - public void visitStackInstruction(StackInstruction obj) { } - public void visitLocalVariableInstruction(LocalVariableInstruction obj) { } - public void visitBranchInstruction(BranchInstruction obj) { } - public void visitLoadClass(LoadClass obj) { } - public void visitFieldInstruction(FieldInstruction obj) { } - public void visitIfInstruction(IfInstruction obj) { } - public void visitConversionInstruction(ConversionInstruction obj) { } - public void visitPopInstruction(PopInstruction obj) { } - public void visitJsrInstruction(JsrInstruction obj) { } - public void visitGotoInstruction(GotoInstruction obj) { } - public void visitStoreInstruction(StoreInstruction obj) { } - public void visitTypedInstruction(TypedInstruction obj) { } - public void visitSelect(Select obj) { } - public void visitUnconditionalBranch(UnconditionalBranch obj) { } - public void visitPushInstruction(PushInstruction obj) { } - public void visitArithmeticInstruction(ArithmeticInstruction obj) { } - public void visitCPInstruction(CPInstruction obj) { } - public void visitInvokeInstruction(InvokeInstruction obj) { } - public void visitArrayInstruction(ArrayInstruction obj) { } - public void visitAllocationInstruction(AllocationInstruction obj) { } - public void visitReturnInstruction(ReturnInstruction obj) { } - public void visitFieldOrMethod(FieldOrMethod obj) { } - public void visitConstantPushInstruction(ConstantPushInstruction obj) { } - public void visitExceptionThrower(ExceptionThrower obj) { } - public void visitLoadInstruction(LoadInstruction obj) { } - public void visitVariableLengthInstruction(VariableLengthInstruction obj) { } - public void visitStackProducer(StackProducer obj) { } - public void visitStackConsumer(StackConsumer obj) { } - public void visitACONST_NULL(ACONST_NULL obj) { } - public void visitGETSTATIC(GETSTATIC obj) { } - public void visitIF_ICMPLT(IF_ICMPLT obj) { } - public void visitMONITOREXIT(MONITOREXIT obj) { } - public void visitIFLT(IFLT obj) { } - public void visitLSTORE(LSTORE obj) { } - public void visitPOP2(POP2 obj) { } - public void visitBASTORE(BASTORE obj) { } - public void visitISTORE(ISTORE obj) { } - public void visitCHECKCAST(CHECKCAST obj) { } - public void visitFCMPG(FCMPG obj) { } - public void visitI2F(I2F obj) { } - public void visitATHROW(ATHROW obj) { } - public void visitDCMPL(DCMPL obj) { } - public void visitARRAYLENGTH(ARRAYLENGTH obj) { } - public void visitDUP(DUP obj) { } - public void visitINVOKESTATIC(INVOKESTATIC obj) { } - public void visitLCONST(LCONST obj) { } - public void visitDREM(DREM obj) { } - public void visitIFGE(IFGE obj) { } - public void visitCALOAD(CALOAD obj) { } - public void visitLASTORE(LASTORE obj) { } - public void visitI2D(I2D obj) { } - public void visitDADD(DADD obj) { } - public void visitINVOKESPECIAL(INVOKESPECIAL obj) { } - public void visitIAND(IAND obj) { } - public void visitPUTFIELD(PUTFIELD obj) { } - public void visitILOAD(ILOAD obj) { } - public void visitDLOAD(DLOAD obj) { } - public void visitDCONST(DCONST obj) { } - public void visitNEW(NEW obj) { } - public void visitIFNULL(IFNULL obj) { } - public void visitLSUB(LSUB obj) { } - public void visitL2I(L2I obj) { } - public void visitISHR(ISHR obj) { } - public void visitTABLESWITCH(TABLESWITCH obj) { } - public void visitIINC(IINC obj) { } - public void visitDRETURN(DRETURN obj) { } - public void visitFSTORE(FSTORE obj) { } - public void visitDASTORE(DASTORE obj) { } - public void visitIALOAD(IALOAD obj) { } - public void visitDDIV(DDIV obj) { } - public void visitIF_ICMPGE(IF_ICMPGE obj) { } - public void visitLAND(LAND obj) { } - public void visitIDIV(IDIV obj) { } - public void visitLOR(LOR obj) { } - public void visitCASTORE(CASTORE obj) { } - public void visitFREM(FREM obj) { } - public void visitLDC(LDC obj) { } - public void visitBIPUSH(BIPUSH obj) { } - public void visitDSTORE(DSTORE obj) { } - public void visitF2L(F2L obj) { } - public void visitFMUL(FMUL obj) { } - public void visitLLOAD(LLOAD obj) { } - public void visitJSR(JSR obj) { } - public void visitFSUB(FSUB obj) { } - public void visitSASTORE(SASTORE obj) { } - public void visitALOAD(ALOAD obj) { } - public void visitDUP2_X2(DUP2_X2 obj) { } - public void visitRETURN(RETURN obj) { } - public void visitDALOAD(DALOAD obj) { } - public void visitSIPUSH(SIPUSH obj) { } - public void visitDSUB(DSUB obj) { } - public void visitL2F(L2F obj) { } - public void visitIF_ICMPGT(IF_ICMPGT obj) { } - public void visitF2D(F2D obj) { } - public void visitI2L(I2L obj) { } - public void visitIF_ACMPNE(IF_ACMPNE obj) { } - public void visitPOP(POP obj) { } - public void visitI2S(I2S obj) { } - public void visitIFEQ(IFEQ obj) { } - public void visitSWAP(SWAP obj) { } - public void visitIOR(IOR obj) { } - public void visitIREM(IREM obj) { } - public void visitIASTORE(IASTORE obj) { } - public void visitNEWARRAY(NEWARRAY obj) { } - public void visitINVOKEINTERFACE(INVOKEINTERFACE obj) { } - public void visitINEG(INEG obj) { } - public void visitLCMP(LCMP obj) { } - public void visitJSR_W(JSR_W obj) { } - public void visitMULTIANEWARRAY(MULTIANEWARRAY obj) { } - public void visitDUP_X2(DUP_X2 obj) { } - public void visitSALOAD(SALOAD obj) { } - public void visitIFNONNULL(IFNONNULL obj) { } - public void visitDMUL(DMUL obj) { } - public void visitIFNE(IFNE obj) { } - public void visitIF_ICMPLE(IF_ICMPLE obj) { } - public void visitLDC2_W(LDC2_W obj) { } - public void visitGETFIELD(GETFIELD obj) { } - public void visitLADD(LADD obj) { } - public void visitNOP(NOP obj) { } - public void visitFALOAD(FALOAD obj) { } - public void visitINSTANCEOF(INSTANCEOF obj) { } - public void visitIFLE(IFLE obj) { } - public void visitLXOR(LXOR obj) { } - public void visitLRETURN(LRETURN obj) { } - public void visitFCONST(FCONST obj) { } - public void visitIUSHR(IUSHR obj) { } - public void visitBALOAD(BALOAD obj) { } - public void visitDUP2(DUP2 obj) { } - public void visitIF_ACMPEQ(IF_ACMPEQ obj) { } - public void visitIMPDEP1(IMPDEP1 obj) { } - public void visitMONITORENTER(MONITORENTER obj) { } - public void visitLSHL(LSHL obj) { } - public void visitDCMPG(DCMPG obj) { } - public void visitD2L(D2L obj) { } - public void visitIMPDEP2(IMPDEP2 obj) { } - public void visitL2D(L2D obj) { } - public void visitRET(RET obj) { } - public void visitIFGT(IFGT obj) { } - public void visitIXOR(IXOR obj) { } - public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { } - public void visitFASTORE(FASTORE obj) { } - public void visitIRETURN(IRETURN obj) { } - public void visitIF_ICMPNE(IF_ICMPNE obj) { } - public void visitFLOAD(FLOAD obj) { } - public void visitLDIV(LDIV obj) { } - public void visitPUTSTATIC(PUTSTATIC obj) { } - public void visitAALOAD(AALOAD obj) { } - public void visitD2I(D2I obj) { } - public void visitIF_ICMPEQ(IF_ICMPEQ obj) { } - public void visitAASTORE(AASTORE obj) { } - public void visitARETURN(ARETURN obj) { } - public void visitDUP2_X1(DUP2_X1 obj) { } - public void visitFNEG(FNEG obj) { } - public void visitGOTO_W(GOTO_W obj) { } - public void visitD2F(D2F obj) { } - public void visitGOTO(GOTO obj) { } - public void visitISUB(ISUB obj) { } - public void visitF2I(F2I obj) { } - public void visitDNEG(DNEG obj) { } - public void visitICONST(ICONST obj) { } - public void visitFDIV(FDIV obj) { } - public void visitI2B(I2B obj) { } - public void visitLNEG(LNEG obj) { } - public void visitLREM(LREM obj) { } - public void visitIMUL(IMUL obj) { } - public void visitIADD(IADD obj) { } - public void visitLSHR(LSHR obj) { } - public void visitLOOKUPSWITCH(LOOKUPSWITCH obj) { } - public void visitDUP_X1(DUP_X1 obj) { } - public void visitFCMPL(FCMPL obj) { } - public void visitI2C(I2C obj) { } - public void visitLMUL(LMUL obj) { } - public void visitLUSHR(LUSHR obj) { } - public void visitISHL(ISHL obj) { } - public void visitLALOAD(LALOAD obj) { } - public void visitASTORE(ASTORE obj) { } - public void visitANEWARRAY(ANEWARRAY obj) { } - public void visitFRETURN(FRETURN obj) { } - public void visitFADD(FADD obj) { } - public void visitBREAKPOINT(BREAKPOINT obj) { } + + @Override + public void visitStackInstruction( final StackInstruction obj ) { + } + + + @Override + public void visitLocalVariableInstruction( final LocalVariableInstruction obj ) { + } + + + @Override + public void visitBranchInstruction( final BranchInstruction obj ) { + } + + + @Override + public void visitLoadClass( final LoadClass obj ) { + } + + + @Override + public void visitFieldInstruction( final FieldInstruction obj ) { + } + + + @Override + public void visitIfInstruction( final IfInstruction obj ) { + } + + + @Override + public void visitConversionInstruction( final ConversionInstruction obj ) { + } + + + @Override + public void visitPopInstruction( final PopInstruction obj ) { + } + + + @Override + public void visitJsrInstruction( final JsrInstruction obj ) { + } + + + @Override + public void visitGotoInstruction( final GotoInstruction obj ) { + } + + + @Override + public void visitStoreInstruction( final StoreInstruction obj ) { + } + + + @Override + public void visitTypedInstruction( final TypedInstruction obj ) { + } + + + @Override + public void visitSelect( final Select obj ) { + } + + + @Override + public void visitUnconditionalBranch( final UnconditionalBranch obj ) { + } + + + @Override + public void visitPushInstruction( final PushInstruction obj ) { + } + + + @Override + public void visitArithmeticInstruction( final ArithmeticInstruction obj ) { + } + + + @Override + public void visitCPInstruction( final CPInstruction obj ) { + } + + + @Override + public void visitInvokeInstruction( final InvokeInstruction obj ) { + } + + + @Override + public void visitArrayInstruction( final ArrayInstruction obj ) { + } + + + @Override + public void visitAllocationInstruction( final AllocationInstruction obj ) { + } + + + @Override + public void visitReturnInstruction( final ReturnInstruction obj ) { + } + + + @Override + public void visitFieldOrMethod( final FieldOrMethod obj ) { + } + + + @Override + public void visitConstantPushInstruction( final ConstantPushInstruction obj ) { + } + + + @Override + public void visitExceptionThrower( final ExceptionThrower obj ) { + } + + + @Override + public void visitLoadInstruction( final LoadInstruction obj ) { + } + + + @Override + public void visitVariableLengthInstruction( final VariableLengthInstruction obj ) { + } + + + @Override + public void visitStackProducer( final StackProducer obj ) { + } + + + @Override + public void visitStackConsumer( final StackConsumer obj ) { + } + + + @Override + public void visitACONST_NULL( final ACONST_NULL obj ) { + } + + + @Override + public void visitGETSTATIC( final GETSTATIC obj ) { + } + + + @Override + public void visitIF_ICMPLT( final IF_ICMPLT obj ) { + } + + + @Override + public void visitMONITOREXIT( final MONITOREXIT obj ) { + } + + + @Override + public void visitIFLT( final IFLT obj ) { + } + + + @Override + public void visitLSTORE( final LSTORE obj ) { + } + + + @Override + public void visitPOP2( final POP2 obj ) { + } + + + @Override + public void visitBASTORE( final BASTORE obj ) { + } + + + @Override + public void visitISTORE( final ISTORE obj ) { + } + + + @Override + public void visitCHECKCAST( final CHECKCAST obj ) { + } + + + @Override + public void visitFCMPG( final FCMPG obj ) { + } + + + @Override + public void visitI2F( final I2F obj ) { + } + + + @Override + public void visitATHROW( final ATHROW obj ) { + } + + + @Override + public void visitDCMPL( final DCMPL obj ) { + } + + + @Override + public void visitARRAYLENGTH( final ARRAYLENGTH obj ) { + } + + + @Override + public void visitDUP( final DUP obj ) { + } + + + @Override + public void visitINVOKESTATIC( final INVOKESTATIC obj ) { + } + + + @Override + public void visitLCONST( final LCONST obj ) { + } + + + @Override + public void visitDREM( final DREM obj ) { + } + + + @Override + public void visitIFGE( final IFGE obj ) { + } + + + @Override + public void visitCALOAD( final CALOAD obj ) { + } + + + @Override + public void visitLASTORE( final LASTORE obj ) { + } + + + @Override + public void visitI2D( final I2D obj ) { + } + + + @Override + public void visitDADD( final DADD obj ) { + } + + + @Override + public void visitINVOKESPECIAL( final INVOKESPECIAL obj ) { + } + + + @Override + public void visitIAND( final IAND obj ) { + } + + + @Override + public void visitPUTFIELD( final PUTFIELD obj ) { + } + + + @Override + public void visitILOAD( final ILOAD obj ) { + } + + + @Override + public void visitDLOAD( final DLOAD obj ) { + } + + + @Override + public void visitDCONST( final DCONST obj ) { + } + + + @Override + public void visitNEW( final NEW obj ) { + } + + + @Override + public void visitIFNULL( final IFNULL obj ) { + } + + + @Override + public void visitLSUB( final LSUB obj ) { + } + + + @Override + public void visitL2I( final L2I obj ) { + } + + + @Override + public void visitISHR( final ISHR obj ) { + } + + + @Override + public void visitTABLESWITCH( final TABLESWITCH obj ) { + } + + + @Override + public void visitIINC( final IINC obj ) { + } + + + @Override + public void visitDRETURN( final DRETURN obj ) { + } + + + @Override + public void visitFSTORE( final FSTORE obj ) { + } + + + @Override + public void visitDASTORE( final DASTORE obj ) { + } + + + @Override + public void visitIALOAD( final IALOAD obj ) { + } + + + @Override + public void visitDDIV( final DDIV obj ) { + } + + + @Override + public void visitIF_ICMPGE( final IF_ICMPGE obj ) { + } + + + @Override + public void visitLAND( final LAND obj ) { + } + + + @Override + public void visitIDIV( final IDIV obj ) { + } + + + @Override + public void visitLOR( final LOR obj ) { + } + + + @Override + public void visitCASTORE( final CASTORE obj ) { + } + + + @Override + public void visitFREM( final FREM obj ) { + } + + + @Override + public void visitLDC( final LDC obj ) { + } + + + @Override + public void visitBIPUSH( final BIPUSH obj ) { + } + + + @Override + public void visitDSTORE( final DSTORE obj ) { + } + + + @Override + public void visitF2L( final F2L obj ) { + } + + + @Override + public void visitFMUL( final FMUL obj ) { + } + + + @Override + public void visitLLOAD( final LLOAD obj ) { + } + + + @Override + public void visitJSR( final JSR obj ) { + } + + + @Override + public void visitFSUB( final FSUB obj ) { + } + + + @Override + public void visitSASTORE( final SASTORE obj ) { + } + + + @Override + public void visitALOAD( final ALOAD obj ) { + } + + + @Override + public void visitDUP2_X2( final DUP2_X2 obj ) { + } + + + @Override + public void visitRETURN( final RETURN obj ) { + } + + + @Override + public void visitDALOAD( final DALOAD obj ) { + } + + + @Override + public void visitSIPUSH( final SIPUSH obj ) { + } + + + @Override + public void visitDSUB( final DSUB obj ) { + } + + + @Override + public void visitL2F( final L2F obj ) { + } + + + @Override + public void visitIF_ICMPGT( final IF_ICMPGT obj ) { + } + + + @Override + public void visitF2D( final F2D obj ) { + } + + + @Override + public void visitI2L( final I2L obj ) { + } + + + @Override + public void visitIF_ACMPNE( final IF_ACMPNE obj ) { + } + + + @Override + public void visitPOP( final POP obj ) { + } + + + @Override + public void visitI2S( final I2S obj ) { + } + + + @Override + public void visitIFEQ( final IFEQ obj ) { + } + + + @Override + public void visitSWAP( final SWAP obj ) { + } + + + @Override + public void visitIOR( final IOR obj ) { + } + + + @Override + public void visitIREM( final IREM obj ) { + } + + + @Override + public void visitIASTORE( final IASTORE obj ) { + } + + + @Override + public void visitNEWARRAY( final NEWARRAY obj ) { + } + + + @Override + public void visitINVOKEINTERFACE( final INVOKEINTERFACE obj ) { + } + + + @Override + public void visitINEG( final INEG obj ) { + } + + + @Override + public void visitLCMP( final LCMP obj ) { + } + + + @Override + public void visitJSR_W( final JSR_W obj ) { + } + + + @Override + public void visitMULTIANEWARRAY( final MULTIANEWARRAY obj ) { + } + + + @Override + public void visitDUP_X2( final DUP_X2 obj ) { + } + + + @Override + public void visitSALOAD( final SALOAD obj ) { + } + + + @Override + public void visitIFNONNULL( final IFNONNULL obj ) { + } + + + @Override + public void visitDMUL( final DMUL obj ) { + } + + + @Override + public void visitIFNE( final IFNE obj ) { + } + + + @Override + public void visitIF_ICMPLE( final IF_ICMPLE obj ) { + } + + + @Override + public void visitLDC2_W( final LDC2_W obj ) { + } + + + @Override + public void visitGETFIELD( final GETFIELD obj ) { + } + + + @Override + public void visitLADD( final LADD obj ) { + } + + + @Override + public void visitNOP( final NOP obj ) { + } + + + @Override + public void visitFALOAD( final FALOAD obj ) { + } + + + @Override + public void visitINSTANCEOF( final INSTANCEOF obj ) { + } + + + @Override + public void visitIFLE( final IFLE obj ) { + } + + + @Override + public void visitLXOR( final LXOR obj ) { + } + + + @Override + public void visitLRETURN( final LRETURN obj ) { + } + + + @Override + public void visitFCONST( final FCONST obj ) { + } + + + @Override + public void visitIUSHR( final IUSHR obj ) { + } + + + @Override + public void visitBALOAD( final BALOAD obj ) { + } + + + @Override + public void visitDUP2( final DUP2 obj ) { + } + + + @Override + public void visitIF_ACMPEQ( final IF_ACMPEQ obj ) { + } + + + @Override + public void visitIMPDEP1( final IMPDEP1 obj ) { + } + + + @Override + public void visitMONITORENTER( final MONITORENTER obj ) { + } + + + @Override + public void visitLSHL( final LSHL obj ) { + } + + + @Override + public void visitDCMPG( final DCMPG obj ) { + } + + + @Override + public void visitD2L( final D2L obj ) { + } + + + @Override + public void visitIMPDEP2( final IMPDEP2 obj ) { + } + + + @Override + public void visitL2D( final L2D obj ) { + } + + + @Override + public void visitRET( final RET obj ) { + } + + + @Override + public void visitIFGT( final IFGT obj ) { + } + + + @Override + public void visitIXOR( final IXOR obj ) { + } + + + @Override + public void visitINVOKEVIRTUAL( final INVOKEVIRTUAL obj ) { + } + + + @Override + public void visitFASTORE( final FASTORE obj ) { + } + + + @Override + public void visitIRETURN( final IRETURN obj ) { + } + + + @Override + public void visitIF_ICMPNE( final IF_ICMPNE obj ) { + } + + + @Override + public void visitFLOAD( final FLOAD obj ) { + } + + + @Override + public void visitLDIV( final LDIV obj ) { + } + + + @Override + public void visitPUTSTATIC( final PUTSTATIC obj ) { + } + + + @Override + public void visitAALOAD( final AALOAD obj ) { + } + + + @Override + public void visitD2I( final D2I obj ) { + } + + + @Override + public void visitIF_ICMPEQ( final IF_ICMPEQ obj ) { + } + + + @Override + public void visitAASTORE( final AASTORE obj ) { + } + + + @Override + public void visitARETURN( final ARETURN obj ) { + } + + + @Override + public void visitDUP2_X1( final DUP2_X1 obj ) { + } + + + @Override + public void visitFNEG( final FNEG obj ) { + } + + + @Override + public void visitGOTO_W( final GOTO_W obj ) { + } + + + @Override + public void visitD2F( final D2F obj ) { + } + + + @Override + public void visitGOTO( final GOTO obj ) { + } + + + @Override + public void visitISUB( final ISUB obj ) { + } + + + @Override + public void visitF2I( final F2I obj ) { + } + + + @Override + public void visitDNEG( final DNEG obj ) { + } + + + @Override + public void visitICONST( final ICONST obj ) { + } + + + @Override + public void visitFDIV( final FDIV obj ) { + } + + + @Override + public void visitI2B( final I2B obj ) { + } + + + @Override + public void visitLNEG( final LNEG obj ) { + } + + + @Override + public void visitLREM( final LREM obj ) { + } + + + @Override + public void visitIMUL( final IMUL obj ) { + } + + + @Override + public void visitIADD( final IADD obj ) { + } + + + @Override + public void visitLSHR( final LSHR obj ) { + } + + + @Override + public void visitLOOKUPSWITCH( final LOOKUPSWITCH obj ) { + } + + + @Override + public void visitDUP_X1( final DUP_X1 obj ) { + } + + + @Override + public void visitFCMPL( final FCMPL obj ) { + } + + + @Override + public void visitI2C( final I2C obj ) { + } + + + @Override + public void visitLMUL( final LMUL obj ) { + } + + + @Override + public void visitLUSHR( final LUSHR obj ) { + } + + + @Override + public void visitISHL( final ISHL obj ) { + } + + + @Override + public void visitLALOAD( final LALOAD obj ) { + } + + + @Override + public void visitASTORE( final ASTORE obj ) { + } + + + @Override + public void visitANEWARRAY( final ANEWARRAY obj ) { + } + + + @Override + public void visitFRETURN( final FRETURN obj ) { + } + + + @Override + public void visitFADD( final FADD obj ) { + } + + + @Override + public void visitBREAKPOINT( final BREAKPOINT obj ) { + } + + /** + * @since 6.0 + */ + @Override + public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC obj) { + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java new file mode 100644 index 00000000000..ae2746e2d53 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java @@ -0,0 +1,147 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; +import com.sun.org.apache.bcel.internal.classfile.EnumElementValue; + +/** + * @since 6.0 + */ +public class EnumElementValueGen extends ElementValueGen +{ + // For enum types, these two indices point to the type and value + private int typeIdx; + + private int valueIdx; + + /** + * This ctor assumes the constant pool already contains the right type and + * value - as indicated by typeIdx and valueIdx. This ctor is used for + * deserialization + */ + protected EnumElementValueGen(final int typeIdx, final int valueIdx, + final ConstantPoolGen cpool) + { + super(ElementValueGen.ENUM_CONSTANT, cpool); + if (super.getElementValueType() != ENUM_CONSTANT) { + throw new RuntimeException( + "Only element values of type enum can be built with this ctor - type specified: " + + super.getElementValueType()); + } + this.typeIdx = typeIdx; + this.valueIdx = valueIdx; + } + + /** + * Return immutable variant of this EnumElementValue + */ + @Override + public ElementValue getElementValue() + { + System.err.println("Duplicating value: " + getEnumTypeString() + ":" + + getEnumValueString()); + return new EnumElementValue(super.getElementValueType(), typeIdx, valueIdx, + getConstantPool().getConstantPool()); + } + + public EnumElementValueGen(final ObjectType t, final String value, final ConstantPoolGen cpool) + { + super(ElementValueGen.ENUM_CONSTANT, cpool); + typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t); + valueIdx = cpool.addUtf8(value);// was addString(value); + } + + public EnumElementValueGen(final EnumElementValue value, final ConstantPoolGen cpool, + final boolean copyPoolEntries) + { + super(ENUM_CONSTANT, cpool); + if (copyPoolEntries) + { + typeIdx = cpool.addUtf8(value.getEnumTypeString());// was + // addClass(value.getEnumTypeString()); + valueIdx = cpool.addUtf8(value.getEnumValueString()); // was + // addString(value.getEnumValueString()); + } + else + { + typeIdx = value.getTypeIndex(); + valueIdx = value.getValueIndex(); + } + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 type of value (ENUM_CONSTANT == 'e') + dos.writeShort(typeIdx); // u2 + dos.writeShort(valueIdx); // u2 + } + + @Override + public String stringifyValue() + { + final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(valueIdx); + return cu8.getBytes(); + // ConstantString cu8 = + // (ConstantString)getConstantPool().getConstant(valueIdx); + // return + // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); + } + + // BCELBUG: Should we need to call utility.signatureToString() on the output + // here? + public String getEnumTypeString() + { + // Constant cc = getConstantPool().getConstant(typeIdx); + // ConstantClass cu8 = + // (ConstantClass)getConstantPool().getConstant(typeIdx); + // return + // ((ConstantUtf8)getConstantPool().getConstant(cu8.getNameIndex())).getBytes(); + return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)) + .getBytes(); + // return Utility.signatureToString(cu8.getBytes()); + } + + public String getEnumValueString() + { + return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getBytes(); + // ConstantString cu8 = + // (ConstantString)getConstantPool().getConstant(valueIdx); + // return + // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); + } + + public int getValueIndex() + { + return valueIdx; + } + + public int getTypeIndex() + { + return typeIdx; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java index d41af1032c8..a0947190b10 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java @@ -21,7 +21,6 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote an instruction that may throw a run-time or a linking * exception (or both) during execution. This is not quite the truth @@ -39,8 +38,9 @@ package com.sun.org.apache.bcel.internal.generic; * "Throwable" object; so this term is equally used for "Exception" * and "Error" objects. * - * @author Enver Haase + * @version $Id: ExceptionThrower.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface ExceptionThrower { - public java.lang.Class[] getExceptions(); + + java.lang.Class[] getExceptions(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java index 417b429c682..f374a10f8a2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * F2D - Convert float to double *
    Stack: ..., value -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: F2D.java 1747278 2016-06-07 17:28:43Z britter $ */ public class F2D extends ConversionInstruction { - /** Convert float to double - */ - public F2D() { - super(com.sun.org.apache.bcel.internal.Constants.F2D); - } + + /** Convert float to double + */ + public F2D() { + super(com.sun.org.apache.bcel.internal.Const.F2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2D(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2D(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java index a8d75d1389f..c5962696a8d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * F2I - Convert float to int *
    Stack: ..., value -> ..., result
    * - * @author M. Dahm + * @version $Id: F2I.java 1747278 2016-06-07 17:28:43Z britter $ */ public class F2I extends ConversionInstruction { - /** Convert float to int - */ - public F2I() { - super(com.sun.org.apache.bcel.internal.Constants.F2I); - } + + /** Convert float to int + */ + public F2I() { + super(com.sun.org.apache.bcel.internal.Const.F2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2I(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2I(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java index 2f58b563fd5..d47b2a1c5af 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * F2L - Convert float to long *
    Stack: ..., value -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: F2L.java 1747278 2016-06-07 17:28:43Z britter $ */ public class F2L extends ConversionInstruction { - /** Convert float to long - */ - public F2L() { - super(com.sun.org.apache.bcel.internal.Constants.F2L); - } + + /** Convert float to long + */ + public F2L() { + super(com.sun.org.apache.bcel.internal.Const.F2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2L(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2L(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java index 6460c871037..f1a9a7a5b1f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FADD - Add floats *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: FADD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FADD extends ArithmeticInstruction { - /** Add floats - */ - public FADD() { - super(com.sun.org.apache.bcel.internal.Constants.FADD); - } + + /** Add floats + */ + public FADD() { + super(com.sun.org.apache.bcel.internal.Const.FADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFADD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFADD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java index c3e67ab8f26..55f950a3793 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FALOAD - Load float from array *
    Stack: ..., arrayref, index -> ..., value
    * - * @author M. Dahm + * @version $Id: FALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FALOAD extends ArrayInstruction implements StackProducer { - /** Load float from array - */ - public FALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.FALOAD); - } + + /** Load float from array + */ + public FALOAD() { + super(com.sun.org.apache.bcel.internal.Const.FALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitFALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitFALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java index 231eb319684..f7e893e9273 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FASTORE - Store into float array *
    Stack: ..., arrayref, index, value -> ...
    * - * @author M. Dahm + * @version $Id: FASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FASTORE extends ArrayInstruction implements StackConsumer { - /** Store float into array - */ - public FASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.FASTORE); - } + + /** Store float into array + */ + public FASTORE() { + super(com.sun.org.apache.bcel.internal.Const.FASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitFASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitFASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java index 761df11e7e9..b950c85d102 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java @@ -21,38 +21,40 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * FCMPG - Compare floats: value1 > value2 + * FCMPG - Compare floats: value1 > value2 *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: FCMPG.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class FCMPG extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - public FCMPG() { - super(com.sun.org.apache.bcel.internal.Constants.FCMPG, (short)1); - } +public class FCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - /** @return Type.FLOAT - */ - public Type getType(ConstantPoolGen cp) { - return Type.FLOAT; - } + public FCMPG() { + super(com.sun.org.apache.bcel.internal.Const.FCMPG, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitFCMPG(this); - } + /** @return Type.FLOAT + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.FLOAT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitFCMPG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java index a6aa1780681..ddb68b08866 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java @@ -21,38 +21,40 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * FCMPL - Compare floats: value1 < value2 + * FCMPL - Compare floats: value1 < value2 *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: FCMPL.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class FCMPL extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - public FCMPL() { - super(com.sun.org.apache.bcel.internal.Constants.FCMPL, (short)1); - } +public class FCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - /** @return Type.FLOAT - */ - public Type getType(ConstantPoolGen cp) { - return Type.FLOAT; - } + public FCMPL() { + super(com.sun.org.apache.bcel.internal.Const.FCMPL, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitFCMPL(this); - } + /** @return Type.FLOAT + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.FLOAT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitFCMPL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java index 76f2b40cd06..0b29d7b7472 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java @@ -20,60 +20,69 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FCONST - Push 0.0, 1.0 or 2.0, other values cause an exception * *
    Stack: ... -> ..., 
    * - * @author M. Dahm + * @version $Id: FCONST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class FCONST extends Instruction - implements ConstantPushInstruction, TypedInstruction { - private float value; +public class FCONST extends Instruction implements ConstantPushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FCONST() {} + private float value; - public FCONST(float f) { - super(com.sun.org.apache.bcel.internal.Constants.FCONST_0, (short)1); - if(f == 0.0) - opcode = com.sun.org.apache.bcel.internal.Constants.FCONST_0; - else if(f == 1.0) - opcode = com.sun.org.apache.bcel.internal.Constants.FCONST_1; - else if(f == 2.0) - opcode = com.sun.org.apache.bcel.internal.Constants.FCONST_2; - else - throw new ClassGenException("FCONST can be used only for 0.0, 1.0 and 2.0: " + f); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FCONST() { + } - value = f; - } - public Number getValue() { return Float.valueOf(value); } + public FCONST(final float f) { + super(com.sun.org.apache.bcel.internal.Const.FCONST_0, (short) 1); + if (f == 0.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.FCONST_0); + } else if (f == 1.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.FCONST_1); + } else if (f == 2.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.FCONST_2); + } else { + throw new ClassGenException("FCONST can be used only for 0.0, 1.0 and 2.0: " + f); + } + value = f; + } - /** @return Type.FLOAT - */ - public Type getType(ConstantPoolGen cp) { - return Type.FLOAT; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitFCONST(this); - } + @Override + public Number getValue() { + return new Float(value); + } + + + /** @return Type.FLOAT + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.FLOAT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitFCONST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java index 8c7da046dfe..d3639219ed9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FDIV - Divide floats *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: FDIV.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FDIV extends ArithmeticInstruction { - /** Divide floats - */ - public FDIV() { - super(com.sun.org.apache.bcel.internal.Constants.FDIV); - } + + /** Divide floats + */ + public FDIV() { + super(com.sun.org.apache.bcel.internal.Const.FDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFDIV(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFDIV(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java index afd730cf528..40c49d74cc3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FLOAD - Load float from local variable *
    Stack ... -> ..., result
    * - * @author M. Dahm + * @version $Id: FLOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FLOAD() { - super(com.sun.org.apache.bcel.internal.Constants.FLOAD, com.sun.org.apache.bcel.internal.Constants.FLOAD_0); - } - /** Load float from local variable - * @param n index of local variable - */ - public FLOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.FLOAD, com.sun.org.apache.bcel.internal.Constants.FLOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FLOAD() { + super(com.sun.org.apache.bcel.internal.Const.FLOAD, com.sun.org.apache.bcel.internal.Const.FLOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitFLOAD(this); - } + + /** Load float from local variable + * @param n index of local variable + */ + public FLOAD(final int n) { + super(com.sun.org.apache.bcel.internal.Const.FLOAD, com.sun.org.apache.bcel.internal.Const.FLOAD_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitFLOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java index fbba7f71f34..6af6dafc8c3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FMUL - Multiply floats *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: FMUL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FMUL extends ArithmeticInstruction { - /** Multiply floats - */ - public FMUL() { - super(com.sun.org.apache.bcel.internal.Constants.FMUL); - } + + /** Multiply floats + */ + public FMUL() { + super(com.sun.org.apache.bcel.internal.Const.FMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFMUL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java index 33fe74faa22..586116fd439 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FNEG - Negate float *
    Stack: ..., value -> ..., result
    * - * @author M. Dahm + * @version $Id: FNEG.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FNEG extends ArithmeticInstruction { - public FNEG() { - super(com.sun.org.apache.bcel.internal.Constants.FNEG); - } + + public FNEG() { + super(com.sun.org.apache.bcel.internal.Const.FNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFNEG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java index ad0f94de62d..e392069a5cf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FREM - Remainder of floats *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: FREM.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FREM extends ArithmeticInstruction { - /** Remainder of floats - */ - public FREM() { - super(com.sun.org.apache.bcel.internal.Constants.FREM); - } + + /** Remainder of floats + */ + public FREM() { + super(com.sun.org.apache.bcel.internal.Const.FREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFREM(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFREM(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java index d2198f82162..80accc29613 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FRETURN - Return float from method *
    Stack: ..., value -> <empty>
    * - * @author M. Dahm + * @version $Id: FRETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FRETURN extends ReturnInstruction { - /** Return float from method - */ - public FRETURN() { - super(com.sun.org.apache.bcel.internal.Constants.FRETURN); - } + + /** Return float from method + */ + public FRETURN() { + super(com.sun.org.apache.bcel.internal.Const.FRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitFRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitFRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java index 124e8b347f1..6af475efaab 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FSTORE - Store float into local variable *
    Stack: ..., value -> ... 
    * - * @author M. Dahm + * @version $Id: FSTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FSTORE() { - super(com.sun.org.apache.bcel.internal.Constants.FSTORE, com.sun.org.apache.bcel.internal.Constants.FSTORE_0); - } - /** Store float into local variable - * @param n index of local variable - */ - public FSTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.FSTORE, com.sun.org.apache.bcel.internal.Constants.FSTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FSTORE() { + super(com.sun.org.apache.bcel.internal.Const.FSTORE, com.sun.org.apache.bcel.internal.Const.FSTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitFSTORE(this); - } + + /** Store float into local variable + * @param n index of local variable + */ + public FSTORE(final int n) { + super(com.sun.org.apache.bcel.internal.Const.FSTORE, com.sun.org.apache.bcel.internal.Const.FSTORE_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitFSTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java index 213c802a23f..71d3f726f9a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FSUB - Substract floats *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: FSUB.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FSUB extends ArithmeticInstruction { - /** Substract floats - */ - public FSUB() { - super(com.sun.org.apache.bcel.internal.Constants.FSUB); - } + + /** Substract floats + */ + public FSUB() { + super(com.sun.org.apache.bcel.internal.Const.FSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFSUB(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java index 42f76abf9f3..f1c65a67e21 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java @@ -17,260 +17,345 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.ArrayList; -import java.util.Iterator; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.Annotations; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantObject; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.Utility; +import com.sun.org.apache.bcel.internal.util.BCELComparator; /** - * Template class for building up a field. The only extraordinary thing - * one can do is to add a constant value attribute to a field (which must of - * course be compatible with to the declared type). + * Template class for building up a field. The only extraordinary thing one can + * do is to add a constant value attribute to a field (which must of course be + * compatible with to the declared type). * - * @author M. Dahm + * @version $Id: FieldGen.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Field */ public class FieldGen extends FieldGenOrMethodGen { - private Object value = null; - /** - * Declare a field. If it is static (isStatic() == true) and has a - * basic type like int or String it may have an initial value - * associated with it as defined by setInitValue(). - * - * @param access_flags access qualifiers - * @param type field type - * @param name field name - * @param cp constant pool - */ - public FieldGen(int access_flags, Type type, String name, ConstantPoolGen cp) { - setAccessFlags(access_flags); - setType(type); - setName(name); - setConstantPool(cp); - } + private Object value = null; + private static BCELComparator bcelComparator = new BCELComparator() { - /** - * Instantiate from existing field. - * - * @param field Field object - * @param cp constant pool (must contain the same entries as the field's constant pool) - */ - public FieldGen(Field field, ConstantPoolGen cp) { - this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp); + @Override + public boolean equals(final Object o1, final Object o2) { + final FieldGen THIS = (FieldGen) o1; + final FieldGen THAT = (FieldGen) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); + } - Attribute[] attrs = field.getAttributes(); + @Override + public int hashCode(final Object o) { + final FieldGen THIS = (FieldGen) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; - for(int i=0; i < attrs.length; i++) { - if(attrs[i] instanceof ConstantValue) - setValue(((ConstantValue)attrs[i]).getConstantValueIndex()); - else - addAttribute(attrs[i]); - } - } - - private void setValue(int index) { - ConstantPool cp = this.cp.getConstantPool(); - Constant c = cp.getConstant(index); - value = ((ConstantObject)c).getConstantValue(cp); - } - - /** - * Set (optional) initial value of field, otherwise it will be set to null/0/false - * by the JVM automatically. - */ - public void setInitValue(String str) { - checkType(new ObjectType("java.lang.String")); - - if(str != null) - value = str; - } - - public void setInitValue(long l) { - checkType(Type.LONG); - - if(l != 0L) - value = Long.valueOf(l); - } - - public void setInitValue(int i) { - checkType(Type.INT); - - if(i != 0) - value = Integer.valueOf(i); - } - - public void setInitValue(short s) { - checkType(Type.SHORT); - - if(s != 0) - value = Integer.valueOf(s); - } - - public void setInitValue(char c) { - checkType(Type.CHAR); - - if(c != 0) - value = Integer.valueOf(c); - } - - public void setInitValue(byte b) { - checkType(Type.BYTE); - - if(b != 0) - value = Integer.valueOf(b); - } - - public void setInitValue(boolean b) { - checkType(Type.BOOLEAN); - - if(b) - value = Integer.valueOf(1); - } - - public void setInitValue(float f) { - checkType(Type.FLOAT); - - if(f != 0.0) - value = Float.valueOf(f); - } - - public void setInitValue(double d) { - checkType(Type.DOUBLE); - - if(d != 0.0) - value = Double.valueOf(d); - } - - /** Remove any initial value. - */ - public void cancelInitValue() { - value = null; - } - - private void checkType(Type atype) { - if(type == null) - throw new ClassGenException("You haven't defined the type of the field yet"); - - if(!isFinal()) - throw new ClassGenException("Only final fields may have an initial value!"); - - if(!type.equals(atype)) - throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype); - } - - /** - * Get field object after having set up all necessary values. - */ - public Field getField() { - String signature = getSignature(); - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(signature); - - if(value != null) { - checkType(type); - int index = addConstant(); - addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), - 2, index, cp.getConstantPool())); + /** + * Declare a field. If it is static (isStatic() == true) and has a basic + * type like int or String it may have an initial value associated with it + * as defined by setInitValue(). + * + * @param access_flags access qualifiers + * @param type field type + * @param name field name + * @param cp constant pool + */ + public FieldGen(final int access_flags, final Type type, final String name, final ConstantPoolGen cp) { + super(access_flags); + setType(type); + setName(name); + setConstantPool(cp); } - return new Field(access_flags, name_index, signature_index, getAttributes(), - cp.getConstantPool()); - } - - private int addConstant() { - switch(type.getType()) { - case Constants.T_INT: case Constants.T_CHAR: case Constants.T_BYTE: - case Constants.T_BOOLEAN: case Constants.T_SHORT: - return cp.addInteger(((Integer)value).intValue()); - - case Constants.T_FLOAT: - return cp.addFloat(((Float)value).floatValue()); - - case Constants.T_DOUBLE: - return cp.addDouble(((Double)value).doubleValue()); - - case Constants.T_LONG: - return cp.addLong(((Long)value).longValue()); - - case Constants.T_REFERENCE: - return cp.addString(((String)value)); - - default: - throw new RuntimeException("Oops: Unhandled : " + type.getType()); + /** + * Instantiate from existing field. + * + * @param field Field object + * @param cp constant pool (must contain the same entries as the field's + * constant pool) + */ + public FieldGen(final Field field, final ConstantPoolGen cp) { + this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp); + final Attribute[] attrs = field.getAttributes(); + for (final Attribute attr : attrs) { + if (attr instanceof ConstantValue) { + setValue(((ConstantValue) attr).getConstantValueIndex()); + } else if (attr instanceof Annotations) { + final Annotations runtimeAnnotations = (Annotations) attr; + final AnnotationEntry[] annotationEntries = runtimeAnnotations.getAnnotationEntries(); + for (final AnnotationEntry element : annotationEntries) { + addAnnotationEntry(new AnnotationEntryGen(element, cp, false)); + } + } else { + addAttribute(attr); + } + } } - } - public String getSignature() { return type.getSignature(); } + private void setValue(final int index) { + final ConstantPool cp = super.getConstantPool().getConstantPool(); + final Constant c = cp.getConstant(index); + value = ((ConstantObject) c).getConstantValue(cp); + } - private ArrayList observers; + /** + * Set (optional) initial value of field, otherwise it will be set to + * null/0/false by the JVM automatically. + */ + public void setInitValue(final String str) { + checkType(ObjectType.getInstance("java.lang.String")); + if (str != null) { + value = str; + } + } - /** Add observer for this object. - */ - public void addObserver(FieldObserver o) { - if(observers == null) - observers = new ArrayList(); + public void setInitValue(final long l) { + checkType(Type.LONG); + if (l != 0L) { + value = l; + } + } - observers.add(o); - } + public void setInitValue(final int i) { + checkType(Type.INT); + if (i != 0) { + value = i; + } + } - /** Remove observer for this object. - */ - public void removeObserver(FieldObserver o) { - if(observers != null) - observers.remove(o); - } + public void setInitValue(final short s) { + checkType(Type.SHORT); + if (s != 0) { + value = (int) s; + } + } - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if(observers != null) - for(Iterator e = observers.iterator(); e.hasNext(); ) - ((FieldObserver)e.next()).notify(this); - } + public void setInitValue(final char c) { + checkType(Type.CHAR); + if (c != 0) { + value = (int) c; + } + } - public String getInitValue() { - if(value != null) { - return value.toString(); - } else - return null; - } + public void setInitValue(final byte b) { + checkType(Type.BYTE); + if (b != 0) { + value = (int) b; + } + } - /** - * Return string representation close to declaration format, - * `public static final short MAX = 100', e.g.. - * - * @return String representation of field - */ - public final String toString() { - String name, signature, access; // Short cuts to constant pool + public void setInitValue(final boolean b) { + checkType(Type.BOOLEAN); + if (b) { + value = 1; + } + } - access = Utility.accessToString(access_flags); - access = access.equals("")? "" : (access + " "); - signature = type.toString(); - name = getName(); + public void setInitValue(final float f) { + checkType(Type.FLOAT); + if (f != 0.0) { + value = f; + } + } - StringBuffer buf = new StringBuffer(access + signature + " " + name); - String value = getInitValue(); + public void setInitValue(final double d) { + checkType(Type.DOUBLE); + if (d != 0.0) { + value = d; + } + } - if(value != null) - buf.append(" = " + value); + /** + * Remove any initial value. + */ + public void cancelInitValue() { + value = null; + } - return buf.toString(); - } + private void checkType(final Type atype) { + final Type superType = super.getType(); + if (superType == null) { + throw new ClassGenException("You haven't defined the type of the field yet"); + } + if (!isFinal()) { + throw new ClassGenException("Only final fields may have an initial value!"); + } + if (!superType.equals(atype)) { + throw new ClassGenException("Types are not compatible: " + superType + " vs. " + atype); + } + } - /** @return deep copy of this field - */ - public FieldGen copy(ConstantPoolGen cp) { - FieldGen fg = (FieldGen)clone(); + /** + * Get field object after having set up all necessary values. + */ + public Field getField() { + final String signature = getSignature(); + final int name_index = super.getConstantPool().addUtf8(super.getName()); + final int signature_index = super.getConstantPool().addUtf8(signature); + if (value != null) { + checkType(super.getType()); + final int index = addConstant(); + addAttribute(new ConstantValue(super.getConstantPool().addUtf8("ConstantValue"), 2, index, + super.getConstantPool().getConstantPool())); // sic + } + addAnnotationsAsAttribute(super.getConstantPool()); + return new Field(super.getAccessFlags(), name_index, signature_index, getAttributes(), + super.getConstantPool().getConstantPool()); // sic + } - fg.setConstantPool(cp); - return fg; - } + private void addAnnotationsAsAttribute(final ConstantPoolGen cp) { + final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); + for (final Attribute attr : attrs) { + addAttribute(attr); + } + } + + private int addConstant() { + switch (super.getType().getType()) { // sic + case Const.T_INT: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_BOOLEAN: + case Const.T_SHORT: + return super.getConstantPool().addInteger(((Integer) value)); + case Const.T_FLOAT: + return super.getConstantPool().addFloat(((Float) value)); + case Const.T_DOUBLE: + return super.getConstantPool().addDouble(((Double) value)); + case Const.T_LONG: + return super.getConstantPool().addLong(((Long) value)); + case Const.T_REFERENCE: + return super.getConstantPool().addString((String) value); + default: + throw new RuntimeException("Oops: Unhandled : " + super.getType().getType()); // sic + } + } + + @Override + public String getSignature() { + return super.getType().getSignature(); + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(final FieldObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(final FieldObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (final FieldObserver observer : observers) { + observer.notify(this); + } + } + } + + public String getInitValue() { + if (value != null) { + return value.toString(); + } + return null; + } + + /** + * Return string representation close to declaration format, `public static + * final short MAX = 100', e.g.. + * + * @return String representation of field + */ + @Override + public final String toString() { + String name; + String signature; + String access; // Short cuts to constant pool + access = Utility.accessToString(super.getAccessFlags()); + access = access.isEmpty() ? "" : (access + " "); + signature = super.getType().toString(); + name = getName(); + final StringBuilder buf = new StringBuilder(32); // CHECKSTYLE IGNORE MagicNumber + buf.append(access).append(signature).append(" ").append(name); + final String value = getInitValue(); + if (value != null) { + buf.append(" = ").append(value); + } + return buf.toString(); + } + + /** + * @return deep copy of this field + */ + public FieldGen copy(final ConstantPoolGen cp) { + final FieldGen fg = (FieldGen) clone(); + fg.setConstantPool(cp); + return fg; + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * FieldGen objects are said to be equal when their names and signatures are + * equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the field's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java index 677dba091df..f4aa17d9ff0 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,85 +17,152 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; - -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.ArrayList; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.AccessFlags; +import com.sun.org.apache.bcel.internal.classfile.Attribute; /** - * Super class for FieldGen and MethodGen objects, since they have - * some methods in common! + * Super class for FieldGen and MethodGen objects, since they have some methods + * in common! * - * @author M. Dahm + * @version $Id: FieldGenOrMethodGen.java 1749603 2016-06-21 20:50:19Z ggregory + * $ */ -public abstract class FieldGenOrMethodGen extends AccessFlags - implements NamedAndTyped, Cloneable -{ - protected String name; - protected Type type; - protected ConstantPoolGen cp; - private ArrayList attribute_vec = new ArrayList(); +public abstract class FieldGenOrMethodGen extends AccessFlags implements NamedAndTyped, Cloneable { - protected FieldGenOrMethodGen() {} + private String name; + private Type type; + private ConstantPoolGen cp; - public void setType(Type type) { - if(type.getType() == Constants.T_ADDRESS) - throw new IllegalArgumentException("Type can not be " + type); + private final List attribute_vec = new ArrayList<>(); - this.type = type; - } - public Type getType() { return type; } + // @since 6.0 + private final List annotation_vec = new ArrayList<>(); - /** @return name of method/field. - */ - public String getName() { return name; } - public void setName(String name) { this.name = name; } - - public ConstantPoolGen getConstantPool() { return cp; } - public void setConstantPool(ConstantPoolGen cp) { this.cp = cp; } - - /** - * Add an attribute to this method. Currently, the JVM knows about - * the `Code', `ConstantValue', `Synthetic' and `Exceptions' - * attributes. Other attributes will be ignored by the JVM but do no - * harm. - * - * @param a attribute to be added - */ - public void addAttribute(Attribute a) { attribute_vec.add(a); } - - /** - * Remove an attribute. - */ - public void removeAttribute(Attribute a) { attribute_vec.remove(a); } - - /** - * Remove all attributes. - */ - public void removeAttributes() { attribute_vec.clear(); } - - /** - * @return all attributes of this method. - */ - public Attribute[] getAttributes() { - Attribute[] attributes = new Attribute[attribute_vec.size()]; - attribute_vec.toArray(attributes); - return attributes; - } - - /** @return signature of method/field. - */ - public abstract String getSignature(); - - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; + protected FieldGenOrMethodGen() { + } + + /** + * @since 6.0 + */ + protected FieldGenOrMethodGen(final int access_flags) { // TODO could this be package protected? + super(access_flags); + } + + @Override + public void setType(final Type type) { // TODO could be package-protected? + if (type.getType() == Const.T_ADDRESS) { + throw new IllegalArgumentException("Type can not be " + type); + } + this.type = type; + } + + @Override + public Type getType() { + return type; + } + + /** + * @return name of method/field. + */ + @Override + public String getName() { + return name; + } + + @Override + public void setName(final String name) { // TODO could be package-protected? + this.name = name; + } + + public ConstantPoolGen getConstantPool() { + return cp; + } + + public void setConstantPool(final ConstantPoolGen cp) { // TODO could be package-protected? + this.cp = cp; + } + + /** + * Add an attribute to this method. Currently, the JVM knows about the + * `Code', `ConstantValue', `Synthetic' and `Exceptions' attributes. Other + * attributes will be ignored by the JVM but do no harm. + * + * @param a attribute to be added + */ + public void addAttribute(final Attribute a) { + attribute_vec.add(a); + } + + /** + * @since 6.0 + */ + protected void addAnnotationEntry(final AnnotationEntryGen ag) // TODO could this be package protected? + { + annotation_vec.add(ag); + } + + /** + * Remove an attribute. + */ + public void removeAttribute(final Attribute a) { + attribute_vec.remove(a); + } + + /** + * @since 6.0 + */ + protected void removeAnnotationEntry(final AnnotationEntryGen ag) // TODO could this be package protected? + { + annotation_vec.remove(ag); + } + + /** + * Remove all attributes. + */ + public void removeAttributes() { + attribute_vec.clear(); + } + + /** + * @since 6.0 + */ + protected void removeAnnotationEntries() // TODO could this be package protected? + { + annotation_vec.clear(); + } + + /** + * @return all attributes of this method. + */ + public Attribute[] getAttributes() { + final Attribute[] attributes = new Attribute[attribute_vec.size()]; + attribute_vec.toArray(attributes); + return attributes; + } + + public AnnotationEntryGen[] getAnnotationEntries() { + final AnnotationEntryGen[] annotations = new AnnotationEntryGen[annotation_vec.size()]; + annotation_vec.toArray(annotations); + return annotations; + } + + /** + * @return signature of method/field. + */ + public abstract String getSignature(); + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java index 30224f1e20d..9848e5e905f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java @@ -21,62 +21,66 @@ package com.sun.org.apache.bcel.internal.generic; - import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; -import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; -import com.sun.org.apache.bcel.internal.classfile.ConstantCP; -import com.sun.org.apache.bcel.internal.classfile.*; /** * Super class for the GET/PUTxxx family of instructions. * - * @author M. Dahm + * @version $Id: FieldInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class FieldInstruction extends FieldOrMethod - implements TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FieldInstruction() {} +public abstract class FieldInstruction extends FieldOrMethod { - /** - * @param index to constant pool - */ - protected FieldInstruction(short opcode, int index) { - super(opcode, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FieldInstruction() { + } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - return com.sun.org.apache.bcel.internal.Constants.OPCODE_NAMES[opcode] + " " + - cp.constantToString(index, com.sun.org.apache.bcel.internal.Constants.CONSTANT_Fieldref); - } - /** @return size of field (1 or 2) - */ - protected int getFieldSize(ConstantPoolGen cpg) { - return getType(cpg).getSize(); - } + /** + * @param index to constant pool + */ + protected FieldInstruction(final short opcode, final int index) { + super(opcode, index); + } - /** @return return type of referenced field - */ - public Type getType(ConstantPoolGen cpg) { - return getFieldType(cpg); - } - /** @return type of field - */ - public Type getFieldType(ConstantPoolGen cpg) { - return Type.getType(getSignature(cpg)); - } + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " + + cp.constantToString(super.getIndex(), com.sun.org.apache.bcel.internal.Const.CONSTANT_Fieldref); + } - /** @return name of referenced field. - */ - public String getFieldName(ConstantPoolGen cpg) { - return getName(cpg); - } + + /** @return size of field (1 or 2) + */ + protected int getFieldSize( final ConstantPoolGen cpg ) { + return Type.size(Type.getTypeSize(getSignature(cpg))); + } + + + /** @return return type of referenced field + */ + @Override + public Type getType( final ConstantPoolGen cpg ) { + return getFieldType(cpg); + } + + + /** @return type of field + */ + public Type getFieldType( final ConstantPoolGen cpg ) { + return Type.getType(getSignature(cpg)); + } + + + /** @return name of referenced field. + */ + public String getFieldName( final ConstantPoolGen cpg ) { + return getName(cpg); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java index b2ee9d1a957..a26ab4a2a20 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Imnplement this interface if you're interested in changes to a FieldGen object * and register yourself with addObserver(). * - * @author M. Dahm + * @version $Id: FieldObserver.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface FieldObserver { - public void notify(FieldGen field); + + void notify( FieldGen field ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java index 5d32603ac5c..84f19cccf8e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java @@ -21,64 +21,123 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.classfile.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.ConstantCP; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; /** * Super class for InvokeInstruction and FieldInstruction, since they have * some methods in common! * - * @author M. Dahm + * @version $Id: FieldOrMethod.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public abstract class FieldOrMethod extends CPInstruction implements LoadClass { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FieldOrMethod() {} - /** - * @param index to constant pool - */ - protected FieldOrMethod(short opcode, int index) { - super(opcode, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FieldOrMethod() { + } - /** @return signature of referenced method/field. - */ - public String getSignature(ConstantPoolGen cpg) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP)cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType)cp.getConstant(cmr.getNameAndTypeIndex()); - return ((ConstantUtf8)cp.getConstant(cnat.getSignatureIndex())).getBytes(); - } + /** + * @param index to constant pool + */ + protected FieldOrMethod(final short opcode, final int index) { + super(opcode, index); + } - /** @return name of referenced method/field. - */ - public String getName(ConstantPoolGen cpg) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP)cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType)cp.getConstant(cmr.getNameAndTypeIndex()); - return ((ConstantUtf8)cp.getConstant(cnat.getNameIndex())).getBytes(); - } - /** @return name of the referenced class/interface - */ - public String getClassName(ConstantPoolGen cpg) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP)cp.getConstant(index); - return cp.getConstantString(cmr.getClassIndex(), com.sun.org.apache.bcel.internal.Constants.CONSTANT_Class).replace('/', '.'); - } + /** @return signature of referenced method/field. + */ + public String getSignature( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); + } - /** @return type of the referenced class/interface - */ - public ObjectType getClassType(ConstantPoolGen cpg) { - return new ObjectType(getClassName(cpg)); - } - /** @return type of the referenced class/interface - */ - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - return getClassType(cpg); - } + /** @return name of referenced method/field. + */ + public String getName( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); + } + + + /** + * @return name of the referenced class/interface + * @deprecated If the instruction references an array class, + * this method will return "java.lang.Object". + * For code generated by Java 1.5, this answer is + * sometimes wrong (e.g., if the "clone()" method is + * called on an array). A better idea is to use + * the {@link #getReferenceType(ConstantPoolGen)} method, which correctly distinguishes + * between class types and array types. + * + */ + @Deprecated + public String getClassName( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class); + if (className.startsWith("[")) { + // Turn array classes into java.lang.Object. + return "java.lang.Object"; + } + return className.replace('/', '.'); + } + + + /** @return type of the referenced class/interface + * @deprecated If the instruction references an array class, + * the ObjectType returned will be invalid. Use + * getReferenceType() instead. + */ + @Deprecated + public ObjectType getClassType( final ConstantPoolGen cpg ) { + return ObjectType.getInstance(getClassName(cpg)); + } + + + /** + * Return the reference type representing the class, interface, + * or array class referenced by the instruction. + * @param cpg the ConstantPoolGen used to create the instruction + * @return an ObjectType (if the referenced class type is a class + * or interface), or an ArrayType (if the referenced class + * type is an array class) + */ + public ReferenceType getReferenceType( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class); + if (className.startsWith("[")) { + return (ArrayType) Type.getType(className); + } + className = className.replace('/', '.'); + return ObjectType.getInstance(className); + } + + + /** + * Get the ObjectType of the method return or field. + * + * @return type of the referenced class/interface + * @throws ClassGenException when the field is (or method returns) an array, + */ + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + final ReferenceType rt = getReferenceType(cpg); + if(rt instanceof ObjectType) { + return (ObjectType)rt; + } + throw new ClassGenException(rt.getSignature() + " does not represent an ObjectType"); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java index 2f2ae53ae31..ce68521a808 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java @@ -18,67 +18,62 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * GETFIELD - Fetch field from object - *
    Stack: ..., objectref -> ..., value
    - * OR + *
    Stack: ..., objectref -> ..., value
    OR *
    Stack: ..., objectref -> ..., value.word1, value.word2
    * - * @author M. Dahm + * @version $Id: GETFIELD.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class GETFIELD extends FieldInstruction - implements ExceptionThrower, StackConsumer, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GETFIELD() {} +public class GETFIELD extends FieldInstruction implements ExceptionThrower, StackConsumer, + StackProducer { - public GETFIELD(int index) { - super(Constants.GETFIELD, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GETFIELD() { + } - public int produceStack(ConstantPoolGen cpg) { return getFieldSize(cpg); } + public GETFIELD(final int index) { + super(Const.GETFIELD, index); + } - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + @Override + public int produceStack(final ConstantPoolGen cpg) { + return getFieldSize(cpg); + } - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = - ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = - ExceptionConstants.NULL_POINTER_EXCEPTION; - - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitGETFIELD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitGETFIELD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java index d66b2ddef0c..40cf8a44882 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java @@ -21,9 +21,8 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * GETSTATIC - Fetch static field from class @@ -31,50 +30,54 @@ import com.sun.org.apache.bcel.internal.ExceptionConstants; * OR *
    Stack: ..., -> ..., value.word1, value.word2
    * - * @author M. Dahm + * @version $Id: GETSTATIC.java 1747278 2016-06-07 17:28:43Z britter $ */ public class GETSTATIC extends FieldInstruction implements PushInstruction, ExceptionThrower { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GETSTATIC() {} - public GETSTATIC(int index) { - super(Constants.GETSTATIC, index); - } - - public int produceStack(ConstantPoolGen cpg) { return getFieldSize(cpg); } - - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = - ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GETSTATIC() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitGETSTATIC(this); - } + public GETSTATIC(final int index) { + super(Const.GETSTATIC, index); + } + + + @Override + public int produceStack( final ConstantPoolGen cpg ) { + return getFieldSize(cpg); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitGETSTATIC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java index 64707b27532..ea5f59c20aa 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java @@ -21,69 +21,83 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; /** * GOTO - Branch always (to relative offset, not absolute address) * - * @author M. Dahm + * @version $Id: GOTO.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class GOTO extends GotoInstruction implements VariableLengthInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GOTO() {} - public GOTO(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.GOTO, target); - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - index = getTargetOffset(); - if(opcode == com.sun.org.apache.bcel.internal.Constants.GOTO) - super.dump(out); - else { // GOTO_W - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - } - - /** Called in pass 2 of InstructionList.setPositions() in order to update - * the branch target, that may shift due to variable length instructions. - */ - protected int updatePosition(int offset, int max_offset) { - int i = getTargetOffset(); // Depending on old position value - - position += offset; // Position may be shifted by preceding expansions - - if(Math.abs(i) >= (32767 - max_offset)) { // to large for short (estimate) - opcode = com.sun.org.apache.bcel.internal.Constants.GOTO_W; - length = 5; - return 2; // 5 - 3 + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GOTO() { } - return 0; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitVariableLengthInstruction(this); - v.visitUnconditionalBranch(this); - v.visitBranchInstruction(this); - v.visitGotoInstruction(this); - v.visitGOTO(this); - } + public GOTO(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.GOTO, target); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.setIndex(getTargetOffset()); + final short _opcode = getOpcode(); + if (_opcode == com.sun.org.apache.bcel.internal.Const.GOTO) { + super.dump(out); + } else { // GOTO_W + super.setIndex(getTargetOffset()); + out.writeByte(_opcode); + out.writeInt(super.getIndex()); + } + } + + + /** + * Called in pass 2 of InstructionList.setPositions() in order to update + * the branch target, that may shift due to variable length instructions. + * + * @param offset additional offset caused by preceding (variable length) instructions + * @param max_offset the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's length + */ + @Override + protected int updatePosition( final int offset, final int max_offset ) { + final int i = getTargetOffset(); // Depending on old position value + setPosition(getPosition() + offset); // Position may be shifted by preceding expansions + if (Math.abs(i) >= (Short.MAX_VALUE - max_offset)) { // to large for short (estimate) + super.setOpcode(com.sun.org.apache.bcel.internal.Const.GOTO_W); + final short old_length = (short) super.getLength(); + super.setLength(5); + return super.getLength() - old_length; + } + return 0; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitVariableLengthInstruction(this); + v.visitUnconditionalBranch(this); + v.visitBranchInstruction(this); + v.visitGotoInstruction(this); + v.visitGOTO(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java index 95e1727d205..fefcd124ad7 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java @@ -21,57 +21,67 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * GOTO_W - Branch always (to relative offset, not absolute address) * - * @author M. Dahm + * @version $Id: GOTO_W.java 1747278 2016-06-07 17:28:43Z britter $ */ public class GOTO_W extends GotoInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GOTO_W() {} - public GOTO_W(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.GOTO_W, target); - length = 5; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GOTO_W() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - index = bytes.readInt(); - length = 5; - } + public GOTO_W(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.GOTO_W, target); + super.setLength(5); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitUnconditionalBranch(this); - v.visitBranchInstruction(this); - v.visitGotoInstruction(this); - v.visitGOTO_W(this); - } + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.setIndex(getTargetOffset()); + out.writeByte(super.getOpcode()); + out.writeInt(super.getIndex()); + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.setIndex(bytes.readInt()); + super.setLength(5); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitUnconditionalBranch(this); + v.visitBranchInstruction(this); + v.visitGotoInstruction(this); + v.visitGOTO_W(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java index aa5ac98971c..4d78765fa4e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java @@ -21,22 +21,22 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Super class for GOTO * - * @author M. Dahm + * @version $Id: GotoInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class GotoInstruction extends BranchInstruction - implements UnconditionalBranch -{ - GotoInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } +public abstract class GotoInstruction extends BranchInstruction implements UnconditionalBranch { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GotoInstruction(){} + GotoInstruction(final short opcode, final InstructionHandle target) { + super(opcode, target); + } + + + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GotoInstruction() { + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java index 4bc35f44a9e..d634be4c8af 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2B - Convert int to byte *
    Stack: ..., value -> ..., result
    * - * @author M. Dahm + * @version $Id: I2B.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2B extends ConversionInstruction { - /** Convert int to byte - */ - public I2B() { - super(com.sun.org.apache.bcel.internal.Constants.I2B); - } + + /** Convert int to byte + */ + public I2B() { + super(com.sun.org.apache.bcel.internal.Const.I2B); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2B(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2B(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java index 704001a96f7..71dface192a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2C - Convert int to char *
    Stack: ..., value -> ..., result
    * - * @author M. Dahm + * @version $Id: I2C.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2C extends ConversionInstruction { - /** Convert int to char - */ - public I2C() { - super(com.sun.org.apache.bcel.internal.Constants.I2C); - } + + /** Convert int to char + */ + public I2C() { + super(com.sun.org.apache.bcel.internal.Const.I2C); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2C(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2C(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java index c35511dc17d..cf8a47b0127 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2D - Convert int to double *
    Stack: ..., value -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: I2D.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2D extends ConversionInstruction { - /** Convert int to double - */ - public I2D() { - super(com.sun.org.apache.bcel.internal.Constants.I2D); - } + + /** Convert int to double + */ + public I2D() { + super(com.sun.org.apache.bcel.internal.Const.I2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2D(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2D(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java index 567e4b08cd3..b1bdda855ff 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2F - Convert int to float *
    Stack: ..., value -> ..., result
    * - * @author M. Dahm + * @version $Id: I2F.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2F extends ConversionInstruction { - /** Convert int to float - */ - public I2F() { - super(com.sun.org.apache.bcel.internal.Constants.I2F); - } + + /** Convert int to float + */ + public I2F() { + super(com.sun.org.apache.bcel.internal.Const.I2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2F(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2F(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java index f087d4507e7..e9f14a34ae9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2L - Convert int to long *
    Stack: ..., value -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: I2L.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2L extends ConversionInstruction { - /** Convert int to long - */ - public I2L() { - super(com.sun.org.apache.bcel.internal.Constants.I2L); - } + + /** Convert int to long + */ + public I2L() { + super(com.sun.org.apache.bcel.internal.Const.I2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2L(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2L(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java index e917e3e6a70..fa4c72b647f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2S - Convert int to short *
    Stack: ..., value -> ..., result
    * - * @author M. Dahm + * @version $Id: I2S.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2S extends ConversionInstruction { - public I2S() { - super(com.sun.org.apache.bcel.internal.Constants.I2S); - } + + public I2S() { + super(com.sun.org.apache.bcel.internal.Const.I2S); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2S(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2S(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java index 71127939b4d..4e709dbc370 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IADD - Add ints *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: IADD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IADD extends ArithmeticInstruction { - /** Add ints - */ - public IADD() { - super(com.sun.org.apache.bcel.internal.Constants.IADD); - } + + /** Add ints + */ + public IADD() { + super(com.sun.org.apache.bcel.internal.Const.IADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIADD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIADD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java index e957e6c19b8..222424a5261 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IALOAD - Load int from array *
    Stack: ..., arrayref, index -> ..., value
    * - * @author M. Dahm + * @version $Id: IALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IALOAD extends ArrayInstruction implements StackProducer { - /** - * Load int from array - */ - public IALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.IALOAD); - } + + /** + * Load int from array + */ + public IALOAD() { + super(com.sun.org.apache.bcel.internal.Const.IALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitIALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitIALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java index f62d301c2a5..5e47267aef4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IAND - Bitwise AND int *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: IAND.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IAND extends ArithmeticInstruction { - public IAND() { - super(com.sun.org.apache.bcel.internal.Constants.IAND); - } + + public IAND() { + super(com.sun.org.apache.bcel.internal.Const.IAND); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIAND(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIAND(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java index a5f0aa2499d..1170a35bcd4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IASTORE - Store into int array *
    Stack: ..., arrayref, index, value -> ...
    * - * @author M. Dahm + * @version $Id: IASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IASTORE extends ArrayInstruction implements StackConsumer { - /** - * Store into int array - */ - public IASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.IASTORE); - } + + /** + * Store into int array + */ + public IASTORE() { + super(com.sun.org.apache.bcel.internal.Const.IASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitIASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitIASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java index 41345d82864..71a592ec550 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java @@ -17,59 +17,63 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** * ICONST - Push value between -1, ..., 5, other values cause an exception * *
    Stack: ... -> ..., 
    * - * @author M. Dahm + * @version $Id: ICONST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class ICONST extends Instruction - implements ConstantPushInstruction, TypedInstruction { - private int value; +public class ICONST extends Instruction implements ConstantPushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ICONST() {} + private int value; - public ICONST(int i) { - super(com.sun.org.apache.bcel.internal.Constants.ICONST_0, (short)1); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ICONST() { + } - if((i >= -1) && (i <= 5)) - opcode = (short)(com.sun.org.apache.bcel.internal.Constants.ICONST_0 + i); // Even works for i == -1 - else - throw new ClassGenException("ICONST can be used only for value between -1 and 5: " + - i); - value = i; - } + public ICONST(final int i) { + super(com.sun.org.apache.bcel.internal.Const.ICONST_0, (short) 1); + if ((i >= -1) && (i <= 5)) { + super.setOpcode((short) (com.sun.org.apache.bcel.internal.Const.ICONST_0 + i)); // Even works for i == -1 + } else { + throw new ClassGenException("ICONST can be used only for value between -1 and 5: " + i); + } + value = i; + } - public Number getValue() { return Integer.valueOf(value); } + @Override + public Number getValue() { + return Integer.valueOf(value); + } - /** @return Type.INT - */ - public Type getType(ConstantPoolGen cp) { - return Type.INT; - } + /** + * @return Type.INT + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.INT; + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitICONST(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitICONST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java index 7043f0408a3..97793944713 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java @@ -21,41 +21,48 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * IDIV - Divide ints *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: IDIV.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IDIV extends ArithmeticInstruction implements ExceptionThrower { - /** Divide ints - */ - public IDIV() { - super(com.sun.org.apache.bcel.internal.Constants.IDIV); - } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.ARITHMETIC_EXCEPTION }; - } + /** Divide ints + */ + public IDIV() { + super(com.sun.org.apache.bcel.internal.Const.IDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIDIV(this); - } + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ARITHMETIC_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIDIV(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java index 87c2bb61e2a..188cdd17eba 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFEQ - Branch if int comparison with zero succeeds * *
    Stack: ..., value -> ...
    * - * @author M. Dahm + * @version $Id: IFEQ.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFEQ() {} - public IFEQ(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFEQ, target); - } - - /** - * @return negation of instruction, e.g. IFEQ.negate() == IFNE - */ - public IfInstruction negate() { - return new IFNE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFEQ() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFEQ(this); - } + public IFEQ(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFEQ, target); + } + + + /** + * @return negation of instruction, e.g. IFEQ.negate() == IFNE + */ + @Override + public IfInstruction negate() { + return new IFNE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFEQ(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java index 90636622e7f..8488b7610c5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFGE - Branch if int comparison with zero succeeds * *
    Stack: ..., value -> ...
    * - * @author M. Dahm + * @version $Id: IFGE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFGE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFGE() {} - public IFGE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFGE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFLT(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFGE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFGE(this); - } + public IFGE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFGE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFLT(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFGE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java index 0195733021f..b9a53779057 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFGT - Branch if int comparison with zero succeeds * *
    Stack: ..., value -> ...
    * - * @author M. Dahm + * @version $Id: IFGT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFGT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFGT() {} - public IFGT(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFGT, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFLE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFGT() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFGT(this); - } + public IFGT(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFGT, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFLE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFGT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java index b5fd9fec1c8..38c69d60555 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFLE - Branch if int comparison with zero succeeds * *
    Stack: ..., value -> ...
    * - * @author M. Dahm + * @version $Id: IFLE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFLE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFLE() {} - public IFLE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFLE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFGT(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFLE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFLE(this); - } + public IFLE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFLE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFGT(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFLE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java index 124e874bbfb..c74ae9edba4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFLT - Branch if int comparison with zero succeeds * *
    Stack: ..., value -> ...
    * - * @author M. Dahm + * @version $Id: IFLT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFLT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFLT() {} - public IFLT(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFLT, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFGE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFLT() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFLT(this); - } + public IFLT(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFLT, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFGE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFLT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java index 1d99492a6d0..104c2ed24eb 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFNE - Branch if int comparison with zero succeeds * *
    Stack: ..., value -> ...
    * - * @author M. Dahm + * @version $Id: IFNE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNE() {} - public IFNE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFNE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFEQ(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNE(this); - } + public IFNE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFNE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFEQ(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java index 9b519f5e129..77c8be6a451 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java @@ -21,44 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFNONNULL - Branch if reference is not null * *
    Stack: ..., reference -> ...
    * - * @author M. Dahm + * @version $Id: IFNONNULL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFNONNULL extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNONNULL() {} - public IFNONNULL(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFNONNULL, target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNONNULL() { + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFNULL(target); - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNONNULL(this); - } + public IFNONNULL(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFNONNULL, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFNULL(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNONNULL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java index 45b15c22b4f..bf8e4346745 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFNULL - Branch if reference is not null * *
    Stack: ..., reference -> ...
    * - * @author M. Dahm + * @version $Id: IFNULL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFNULL extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNULL() {} - public IFNULL(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFNULL, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFNONNULL(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNULL() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNULL(this); - } + public IFNULL(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFNULL, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFNONNULL(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNULL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java index c18b9c84329..cb9979709eb 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java @@ -21,44 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ACMPEQ - Branch if reference comparison succeeds * *
    Stack: ..., value1, value2 -> ...
    * - * @author M. Dahm + * @version $Id: IF_ACMPEQ.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ACMPEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ACMPEQ() {} - public IF_ACMPEQ(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ACMPEQ, target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ACMPEQ() { + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ACMPNE(target); - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ACMPEQ(this); - } + public IF_ACMPEQ(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ACMPEQ, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ACMPNE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ACMPEQ(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java index 5a3df6d8a43..50f1a17fd82 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ACMPNE - Branch if reference comparison doesn't succeed * *
    Stack: ..., value1, value2 -> ...
    * - * @author M. Dahm + * @version $Id: IF_ACMPNE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ACMPNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ACMPNE() {} - public IF_ACMPNE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ACMPNE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ACMPEQ(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ACMPNE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ACMPNE(this); - } + public IF_ACMPNE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ACMPNE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ACMPEQ(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ACMPNE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java index f14a5b88217..0d3666c99bc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPEQ - Branch if int comparison succeeds * *
    Stack: ..., value1, value2 -> ...
    * - * @author M. Dahm + * @version $Id: IF_ICMPEQ.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPEQ() {} - public IF_ICMPEQ(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPEQ, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPNE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPEQ() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPEQ(this); - } + public IF_ICMPEQ(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPEQ, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPNE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPEQ(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java index 9b978416da1..abb0d21c03a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPGE - Branch if int comparison succeeds * *
    Stack: ..., value1, value2 -> ...
    * - * @author M. Dahm + * @version $Id: IF_ICMPGE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPGE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPGE() {} - public IF_ICMPGE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPGE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPLT(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPGE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPGE(this); - } + public IF_ICMPGE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPGE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPLT(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPGE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java index f0de3fc407d..da1749604f3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPGT - Branch if int comparison succeeds * *
    Stack: ..., value1, value2 -> ...
    * - * @author M. Dahm + * @version $Id: IF_ICMPGT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPGT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPGT() {} - public IF_ICMPGT(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPGT, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPLE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPGT() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPGT(this); - } + public IF_ICMPGT(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPGT, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPLE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPGT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java index 3c13250cafb..b816ab0e863 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPLE - Branch if int comparison succeeds * *
    Stack: ..., value1, value2 -> ...
    * - * @author M. Dahm + * @version $Id: IF_ICMPLE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPLE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPLE() {} - public IF_ICMPLE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPLE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPGT(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPLE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPLE(this); - } + public IF_ICMPLE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPLE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPGT(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPLE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java index 849951cf548..58eee78d9bf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPLT - Branch if int comparison succeeds * *
    Stack: ..., value1, value2 -> ...
    * - * @author M. Dahm + * @version $Id: IF_ICMPLT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPLT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPLT() {} - public IF_ICMPLT(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPLT, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPGE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPLT() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPLT(this); - } + public IF_ICMPLT(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPLT, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPGE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPLT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java index f1de6f641a3..78e7d341250 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPNE - Branch if int comparison doesn't succeed * *
    Stack: ..., value1, value2 -> ...
    * - * @author M. Dahm + * @version $Id: IF_ICMPNE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPNE() {} - public IF_ICMPNE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPNE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPEQ(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPNE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPNE(this); - } + public IF_ICMPNE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPNE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPEQ(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPNE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java index 897d426a549..1067443d66b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java @@ -21,130 +21,149 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * IINC - Increment local variable by constant * - * @author M. Dahm + * @version $Id: IINC.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IINC extends LocalVariableInstruction { - private boolean wide; - private int c; - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IINC() {} + private boolean wide; + private int c; - /** - * @param n index of local variable - * @param c increment factor - */ - public IINC(int n, int c) { - super(); // Default behaviour of LocalVariableInstruction causes error - this.opcode = com.sun.org.apache.bcel.internal.Constants.IINC; - this.length = (short)3; - - setIndex(n); // May set wide as side effect - setIncrement(c); - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - if(wide) // Need WIDE prefix ? - out.writeByte(com.sun.org.apache.bcel.internal.Constants.WIDE); - - out.writeByte(opcode); - - if(wide) { - out.writeShort(n); - out.writeShort(c); - } else { - out.writeByte(n); - out.writeByte(c); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IINC() { } - } - private final void setWide() { - if(wide = ((n > com.sun.org.apache.bcel.internal.Constants.MAX_SHORT) || - (Math.abs(c) > Byte.MAX_VALUE))) - length = 6; // wide byte included - else - length = 3; - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - this.wide = wide; - - if(wide) { - length = 6; - n = bytes.readUnsignedShort(); - c = bytes.readShort(); - } else { - length = 3; - n = bytes.readUnsignedByte(); - c = bytes.readByte(); + /** + * @param n index of local variable + * @param c increment factor + */ + public IINC(final int n, final int c) { + super(); // Default behaviour of LocalVariableInstruction causes error + super.setOpcode(com.sun.org.apache.bcel.internal.Const.IINC); + super.setLength((short) 3); + setIndex(n); // May set wide as side effect + setIncrement(c); } - } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + c; - } - /** - * Set index of local variable. - */ - public final void setIndex(int n) { - if(n < 0) - throw new ClassGenException("Negative index value: " + n); + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + if (wide) { + out.writeByte(com.sun.org.apache.bcel.internal.Const.WIDE); + } + out.writeByte(super.getOpcode()); + if (wide) { + out.writeShort(super.getIndex()); + out.writeShort(c); + } else { + out.writeByte(super.getIndex()); + out.writeByte(c); + } + } - this.n = n; - setWide(); - } - /** - * @return increment factor - */ - public final int getIncrement() { return c; } + private void setWide() { + wide = (super.getIndex() > com.sun.org.apache.bcel.internal.Const.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE); + if (wide) { + super.setLength(6); // wide byte included + } else { + super.setLength(3); + } + } - /** - * Set increment factor. - */ - public final void setIncrement(int c) { - this.c = c; - setWide(); - } - /** @return int type - */ - public Type getType(ConstantPoolGen cp) { - return Type.INT; - } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + this.wide = wide; + if (wide) { + super.setLength(6); + super.setIndexOnly(bytes.readUnsignedShort()); + c = bytes.readShort(); + } else { + super.setLength(3); + super.setIndexOnly(bytes.readUnsignedByte()); + c = bytes.readByte(); + } + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLocalVariableInstruction(this); - v.visitIINC(this); - } + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + c; + } + + + /** + * Set index of local variable. + */ + @Override + public final void setIndex( final int n ) { + if (n < 0) { + throw new ClassGenException("Negative index value: " + n); + } + super.setIndexOnly(n); + setWide(); + } + + + /** + * @return increment factor + */ + public final int getIncrement() { + return c; + } + + + /** + * Set increment factor. + */ + public final void setIncrement( final int c ) { + this.c = c; + setWide(); + } + + + /** @return int type + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.INT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLocalVariableInstruction(this); + v.visitIINC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java index 748da0b860f..cf63d872b34 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ILOAD - Load int from local variable onto stack *
    Stack: ... -> ..., result
    * - * @author M. Dahm + * @version $Id: ILOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ILOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ILOAD() { - super(com.sun.org.apache.bcel.internal.Constants.ILOAD, com.sun.org.apache.bcel.internal.Constants.ILOAD_0); - } - /** Load int from local variable - * @param n index of local variable - */ - public ILOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.ILOAD, com.sun.org.apache.bcel.internal.Constants.ILOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ILOAD() { + super(com.sun.org.apache.bcel.internal.Const.ILOAD, com.sun.org.apache.bcel.internal.Const.ILOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitILOAD(this); - } + + /** Load int from local variable + * @param n index of local variable + */ + public ILOAD(final int n) { + super(com.sun.org.apache.bcel.internal.Const.ILOAD, com.sun.org.apache.bcel.internal.Const.ILOAD_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitILOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java index 20555243e3d..a1603214864 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java @@ -21,27 +21,28 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IMPDEP1 - Implementation dependent * - * @author M. Dahm + * @version $Id: IMPDEP1.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IMPDEP1 extends Instruction { - public IMPDEP1() { - super(com.sun.org.apache.bcel.internal.Constants.IMPDEP1, (short)1); - } + + public IMPDEP1() { + super(com.sun.org.apache.bcel.internal.Const.IMPDEP1, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitIMPDEP1(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitIMPDEP1(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java index 9caa3523bde..e7d9dd8f03f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java @@ -21,27 +21,28 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IMPDEP2 - Implementation dependent * - * @author M. Dahm + * @version $Id: IMPDEP2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IMPDEP2 extends Instruction { - public IMPDEP2() { - super(com.sun.org.apache.bcel.internal.Constants.IMPDEP2, (short)1); - } + + public IMPDEP2() { + super(com.sun.org.apache.bcel.internal.Const.IMPDEP2, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitIMPDEP2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitIMPDEP2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java index 8c8e150c725..7bf4cf98ed5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IMUL - Multiply ints *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: IMUL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IMUL extends ArithmeticInstruction { - /** Multiply ints - */ - public IMUL() { - super(com.sun.org.apache.bcel.internal.Constants.IMUL); - } + + /** Multiply ints + */ + public IMUL() { + super(com.sun.org.apache.bcel.internal.Const.IMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIMUL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java index c874e95c440..87e0356daf4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * INEG - Negate int *
    Stack: ..., value -> ..., result
    * - * @author M. Dahm + * @version $Id: INEG.java 1747278 2016-06-07 17:28:43Z britter $ */ public class INEG extends ArithmeticInstruction { - public INEG() { - super(com.sun.org.apache.bcel.internal.Constants.INEG); - } + + public INEG() { + super(com.sun.org.apache.bcel.internal.Const.INEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitINEG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitINEG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java index c67ffeb3fd9..15b48b85068 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java @@ -21,53 +21,62 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * INSTANCEOF - Determine if object is of given type *
    Stack: ..., objectref -> ..., result
    * - * @author M. Dahm + * @version $Id: INSTANCEOF.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class INSTANCEOF extends CPInstruction - implements LoadClass, ExceptionThrower, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INSTANCEOF() {} +public class INSTANCEOF extends CPInstruction implements LoadClass, ExceptionThrower, + StackProducer, StackConsumer { - public INSTANCEOF(int index) { - super(com.sun.org.apache.bcel.internal.Constants.INSTANCEOF, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INSTANCEOF() { + } - public Class[] getExceptions() { - return com.sun.org.apache.bcel.internal.ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION; - } - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - Type t = getType(cpg); + public INSTANCEOF(final int index) { + super(com.sun.org.apache.bcel.internal.Const.INSTANCEOF, index); + } - if(t instanceof ArrayType) - t = ((ArrayType) t).getBasicType(); - return (t instanceof ObjectType)? (ObjectType) t : null; - } + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitINSTANCEOF(this); - } + + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitINSTANCEOF(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java new file mode 100644 index 00000000000..a41ffdcb1f5 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java @@ -0,0 +1,134 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; +import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.util.ByteSequence; + +/** + * Class for INVOKEDYNAMIC. Not an instance of InvokeInstruction, since that class + * expects to be able to get the class of the method. Ignores the bootstrap + * mechanism entirely. + * + * @version $Id: InvokeInstruction.java 1152072 2011-07-29 01:54:05Z dbrosius $ + * @see + * + * The invokedynamic instruction in The Java Virtual Machine Specification + * @since 6.0 + */ +public class INVOKEDYNAMIC extends InvokeInstruction { + + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKEDYNAMIC() { + } + + + public INVOKEDYNAMIC(final int index) { + super(Const.INVOKEDYNAMIC, index); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + out.writeByte(0); + out.writeByte(0); + } + + + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + super.setLength(5); + bytes.readByte(); // Skip 0 byte + bytes.readByte(); // Skip 0 byte + } + + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + return super.toString(cp); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION, + ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, + ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEDYNAMIC(this); + } + + /** + * Override the parent method because our classname is held elsewhere. + */ + @Override + public String getClassName( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic); + return ((ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex())).getName(cp); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java index bda3a357a46..a47afc06cd2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java @@ -21,110 +21,123 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import java.io.DataOutputStream; +import java.io.IOException; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * INVOKEINTERFACE - Invoke interface method *
    Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    * - * @author M. Dahm + * @version $Id: INVOKEINTERFACE.java 1747278 2016-06-07 17:28:43Z britter $ + * @see + * + * The invokeinterface instruction in The Java Virtual Machine Specification */ public final class INVOKEINTERFACE extends InvokeInstruction { - private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2 - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKEINTERFACE() {} + private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2 - public INVOKEINTERFACE(int index, int nargs) { - super(Constants.INVOKEINTERFACE, index); - length = 5; - if(nargs < 1) - throw new ClassGenException("Number of arguments must be > 0 " + nargs); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKEINTERFACE() { + } - this.nargs = nargs; - } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - out.writeByte(nargs); - out.writeByte(0); - } + public INVOKEINTERFACE(final int index, final int nargs) { + super(Const.INVOKEINTERFACE, index); + super.setLength(5); + if (nargs < 1) { + throw new ClassGenException("Number of arguments must be > 0 " + nargs); + } + this.nargs = nargs; + } - /** - * The count argument according to the Java Language Specification, - * Second Edition. - */ - public int getCount() { return nargs; } - /** - * Read needed data (i.e., index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - super.initFromFile(bytes, wide); + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + out.writeByte(nargs); + out.writeByte(0); + } - length = 5; - nargs = bytes.readUnsignedByte(); - bytes.readByte(); // Skip 0 byte - } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - return super.toString(cp) + " " + nargs; - } + /** + * The count argument according to the Java Language Specification, + * Second Edition. + */ + public int getCount() { + return nargs; + } - public int consumeStack(ConstantPoolGen cpg) { // nargs is given in byte-code - return nargs; // nargs includes this reference - } - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length]; + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + super.setLength(5); + nargs = bytes.readUnsignedByte(); + bytes.readByte(); // Skip 0 byte + } - System.arraycopy(ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length+3] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length+2] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length+1] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR; + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + return super.toString(cp) + " " + nargs; + } - return cs; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKEINTERFACE(this); - } + @Override + public int consumeStack( final ConstantPoolGen cpg ) { // nargs is given in byte-code + return nargs; // nargs includes this reference + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION, + ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, + ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEINTERFACE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java index 566f58e2112..387b39ca59f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java @@ -21,8 +21,11 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * INVOKESPECIAL - Invoke instance method; special handling for superclass, private @@ -30,51 +33,64 @@ import com.sun.org.apache.bcel.internal.ExceptionConstants; * *
    Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    * - * @author M. Dahm + * @version $Id: INVOKESPECIAL.java 1747278 2016-06-07 17:28:43Z britter $ + * @see + * + * The invokespecial instruction in The Java Virtual Machine Specification */ public class INVOKESPECIAL extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKESPECIAL() {} - public INVOKESPECIAL(int index) { - super(Constants.INVOKESPECIAL, index); - } - - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+3] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+2] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKESPECIAL() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKESPECIAL(this); - } + public INVOKESPECIAL(final int index) { + super(Const.INVOKESPECIAL, index); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, + ExceptionConst.UNSATISFIED_LINK_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKESPECIAL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java index 2946d477a73..415527faf95 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java @@ -21,57 +21,73 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * INVOKESTATIC - Invoke a class (static) method * *
    Stack: ..., [arg1, [arg2 ...]] -> ...
    * - * @author M. Dahm + * @version $Id: INVOKESTATIC.java 1747278 2016-06-07 17:28:43Z britter $ + * @see + * + * The invokestatic instruction in The Java Virtual Machine Specification */ public class INVOKESTATIC extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKESTATIC() {} - public INVOKESTATIC(int index) { - super(Constants.INVOKESTATIC, index); - } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKESTATIC() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKESTATIC(this); - } + public INVOKESTATIC(final int index) { + super(Const.INVOKESTATIC, index); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKESTATIC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java index 9e7d7e2622a..eb814d4889a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java @@ -21,59 +21,75 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * INVOKEVIRTUAL - Invoke instance method; dispatch based on class * *
    Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    * - * @author M. Dahm + * @version $Id: INVOKEVIRTUAL.java 1747278 2016-06-07 17:28:43Z britter $ + * @see + * + * The invokevirtual instruction in The Java Virtual Machine Specification */ public class INVOKEVIRTUAL extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKEVIRTUAL() {} - public INVOKEVIRTUAL(int index) { - super(Constants.INVOKEVIRTUAL, index); - } - - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+3] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+2] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKEVIRTUAL() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKEVIRTUAL(this); - } + public INVOKEVIRTUAL(final int index) { + super(Const.INVOKEVIRTUAL, index); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, + ExceptionConst.UNSATISFIED_LINK_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEVIRTUAL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java index 3b030d9f34d..7bf38937e35 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IOR - Bitwise OR int *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: IOR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IOR extends ArithmeticInstruction { - public IOR() { - super(com.sun.org.apache.bcel.internal.Constants.IOR); - } + + public IOR() { + super(com.sun.org.apache.bcel.internal.Const.IOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIOR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIOR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java index 472ce73bde8..85810f5ff36 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java @@ -21,41 +21,48 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * IREM - Remainder of int *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: IREM.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IREM extends ArithmeticInstruction implements ExceptionThrower { - /** Remainder of ints - */ - public IREM() { - super(com.sun.org.apache.bcel.internal.Constants.IREM); - } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.ARITHMETIC_EXCEPTION }; - } + /** Remainder of ints + */ + public IREM() { + super(com.sun.org.apache.bcel.internal.Const.IREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIREM(this); - } + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ARITHMETIC_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIREM(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java index 53d9384a1aa..f2f1fdbcccd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IRETURN - Return int from method *
    Stack: ..., value -> <empty>
    * - * @author M. Dahm + * @version $Id: IRETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IRETURN extends ReturnInstruction { - /** Return int from method - */ - public IRETURN() { - super(com.sun.org.apache.bcel.internal.Constants.IRETURN); - } + + /** Return int from method + */ + public IRETURN() { + super(com.sun.org.apache.bcel.internal.Const.IRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitIRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitIRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java index 577e3b204a7..e4848f897bd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ISHL - Arithmetic shift left int *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: ISHL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ISHL extends ArithmeticInstruction { - public ISHL() { - super(com.sun.org.apache.bcel.internal.Constants.ISHL); - } + + public ISHL() { + super(com.sun.org.apache.bcel.internal.Const.ISHL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISHL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISHL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java index e9b121f00c3..92a06e07d12 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ISHR - Arithmetic shift right int *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: ISHR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ISHR extends ArithmeticInstruction { - public ISHR() { - super(com.sun.org.apache.bcel.internal.Constants.ISHR); - } + + public ISHR() { + super(com.sun.org.apache.bcel.internal.Const.ISHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISHR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISHR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java index fd270fd4d65..6e42ea0c578 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ISTORE - Store int from stack into local variable *
    Stack: ..., value -> ... 
    * - * @author M. Dahm + * @version $Id: ISTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ISTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ISTORE() { - super(com.sun.org.apache.bcel.internal.Constants.ISTORE, com.sun.org.apache.bcel.internal.Constants.ISTORE_0); - } - /** Store int into local variable - * @param n index of local variable - */ - public ISTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.ISTORE, com.sun.org.apache.bcel.internal.Constants.ISTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ISTORE() { + super(com.sun.org.apache.bcel.internal.Const.ISTORE, com.sun.org.apache.bcel.internal.Const.ISTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitISTORE(this); - } + + /** Store int into local variable + * @param n index of local variable + */ + public ISTORE(final int n) { + super(com.sun.org.apache.bcel.internal.Const.ISTORE, com.sun.org.apache.bcel.internal.Const.ISTORE_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitISTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java index 824b0e3bc60..e3415486ed0 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ISUB - Substract ints *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: ISUB.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ISUB extends ArithmeticInstruction { - /** Substract ints - */ - public ISUB() { - super(com.sun.org.apache.bcel.internal.Constants.ISUB); - } + + /** Substract ints + */ + public ISUB() { + super(com.sun.org.apache.bcel.internal.Const.ISUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISUB(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISUB(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java index b9fe7308803..6c0d46d545e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IUSHR - Logical shift right int *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: IUSHR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IUSHR extends ArithmeticInstruction { - public IUSHR() { - super(com.sun.org.apache.bcel.internal.Constants.IUSHR); - } + + public IUSHR() { + super(com.sun.org.apache.bcel.internal.Const.IUSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIUSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIUSHR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java index 27545563dc2..3cd49158dc2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IXOR - Bitwise XOR int *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: IXOR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IXOR extends ArithmeticInstruction { - public IXOR() { - super(com.sun.org.apache.bcel.internal.Constants.IXOR); - } + + public IXOR() { + super(com.sun.org.apache.bcel.internal.Const.IXOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIXOR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIXOR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java index d677f220b66..64b3381f83f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java @@ -21,28 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Super class for the IFxxx family of instructions. * - * @author M. Dahm + * @version $Id: IfInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ public abstract class IfInstruction extends BranchInstruction implements StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IfInstruction() {} - /** - * @param instruction Target instruction to branch to - */ - protected IfInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IfInstruction() { + } - /** - * @return negation of instruction, e.g. IFEQ.negate() == IFNE - */ - public abstract IfInstruction negate(); + + /** + * @param opcode opcode of instruction + * @param target Target instruction to branch to + */ + protected IfInstruction(final short opcode, final InstructionHandle target) { + super(opcode, target); + } + + + /** + * @return negation of instruction, e.g. IFEQ.negate() == IFNE + */ + public abstract IfInstruction negate(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java index 5c6fb7bc618..0202c82fe38 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java @@ -21,14 +21,16 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote entity that refers to an index, e.g. local variable instructions, * RET, CPInstruction, etc. * - * @author M. Dahm + * @version $Id: IndexedInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface IndexedInstruction { - public int getIndex(); - public void setIndex(int index); + + int getIndex(); + + + void setIndex( int index ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java index 7b2753e2d68..463875fb27d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java @@ -17,254 +17,583 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import java.io.*; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * Abstract super class for all Java byte codes. * - * @author M. Dahm + * @version $Id: Instruction.java 1750029 2016-06-23 22:14:38Z sebb $ */ -public abstract class Instruction implements Cloneable, Serializable { - protected short length = 1; // Length of instruction in bytes - protected short opcode = -1; // Opcode number +public abstract class Instruction implements Cloneable { - private static InstructionComparator cmp = InstructionComparator.DEFAULT; + private short length = 1; // Length of instruction in bytes + private short opcode = -1; // Opcode number - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - Instruction() {} + private static InstructionComparator cmp = InstructionComparator.DEFAULT; - public Instruction(short opcode, short length) { - this.length = length; - this.opcode = opcode; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); // Common for all instructions - } - - /** @return name of instruction, i.e., opcode name - */ - public String getName() { - return Constants.OPCODE_NAMES[opcode]; - } - - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - if(verbose) - return getName() + "[" + opcode + "](" + length + ")"; - else - return getName(); - } - - /** - * @return mnemonic for instruction in verbose format - */ - public String toString() { - return toString(true); - } - - /** - * @return mnemonic for instruction with sumbolic references resolved - */ - public String toString(ConstantPool cp) { - return toString(false); - } - - /** - * Use with caution, since `BranchInstruction's have a `target' reference which - * is not copied correctly (only basic types are). This also applies for - * `Select' instructions with their multiple branch targets. - * - * @see BranchInstruction - * @return (shallow) copy of an instruction - */ - public Instruction copy() { - Instruction i = null; - - // "Constant" instruction, no need to duplicate - if(InstructionConstants.INSTRUCTIONS[this.getOpcode()] != null) - i = this; - else { - try { - i = (Instruction)clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - } - } - - return i; - } - - /** - * Read needed data (e.g. index) from file. - * - * @param bytes byte sequence to read from - * @param wide "wide" instruction flag - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - {} - - /** - * Read an instruction from (byte code) input stream and return the - * appropiate object. - * - * @param file file to read from - * @return instruction object being read - */ - public static final Instruction readInstruction(ByteSequence bytes) - throws IOException - { - boolean wide = false; - short opcode = (short)bytes.readUnsignedByte(); - Instruction obj = null; - - if(opcode == Constants.WIDE) { // Read next opcode after wide byte - wide = true; - opcode = (short)bytes.readUnsignedByte(); - } - - if(InstructionConstants.INSTRUCTIONS[opcode] != null) - return InstructionConstants.INSTRUCTIONS[opcode]; // Used predefined immutable object, if available - - /* Find appropiate class, instantiate an (empty) instruction object - * and initialize it by hand. + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. */ - Class clazz; - - try { - clazz = Class.forName(className(opcode)); - } catch (ClassNotFoundException cnfe){ - // If a class by that name does not exist, the opcode is illegal. - // Note that IMPDEP1, IMPDEP2, BREAKPOINT are also illegal in a sense. - throw new ClassGenException("Illegal opcode detected."); + Instruction() { } - try { - obj = (Instruction)clazz.getConstructor().newInstance(); + public Instruction(final short opcode, final short length) { + this.length = length; + this.opcode = opcode; + } - if(wide && !((obj instanceof LocalVariableInstruction) || - (obj instanceof IINC) || - (obj instanceof RET))) - throw new Exception("Illegal opcode after wide: " + opcode); - - obj.setOpcode(opcode); - obj.initFromFile(bytes, wide); // Do further initializations, if any - // Byte code offset set in InstructionList - } catch(Exception e) { throw new ClassGenException(e.toString()); } - - return obj; - } - - private static final String className(short opcode) { - String name = Constants.OPCODE_NAMES[opcode].toUpperCase(); - - /* ICONST_0, etc. will be shortened to ICONST, etc., since ICONST_0 and the like - * are not implemented (directly). + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream */ - try { - int len = name.length(); - char ch1 = name.charAt(len - 2), ch2 = name.charAt(len - 1); + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(opcode); // Common for all instructions + } - if((ch1 == '_') && (ch2 >= '0') && (ch2 <= '5')) - name = name.substring(0, len - 2); + /** + * @return name of instruction, i.e., opcode name + */ + public String getName() { + return Const.getOpcodeName(opcode); + } - if(name.equals("ICONST_M1")) // Special case - name = "ICONST"; - } catch(StringIndexOutOfBoundsException e) { System.err.println(e); } + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + public String toString(final boolean verbose) { + if (verbose) { + return getName() + "[" + opcode + "](" + length + ")"; + } + return getName(); + } - return "com.sun.org.apache.bcel.internal.generic." + name; - } + /** + * @return mnemonic for instruction in verbose format + */ + @Override + public String toString() { + return toString(true); + } - /** - * This method also gives right results for instructions whose - * effect on the stack depends on the constant pool entry they - * reference. - * @return Number of words consumed from stack by this instruction, - * or Constants.UNPREDICTABLE, if this can not be computed statically - */ - public int consumeStack(ConstantPoolGen cpg) { - return Constants.CONSUME_STACK[opcode]; - } + /** + * @return mnemonic for instruction with sumbolic references resolved + */ + public String toString(final ConstantPool cp) { + return toString(false); + } - /** - * This method also gives right results for instructions whose - * effect on the stack depends on the constant pool entry they - * reference. - * @return Number of words produced onto stack by this instruction, - * or Constants.UNPREDICTABLE, if this can not be computed statically - */ - public int produceStack(ConstantPoolGen cpg) { - return Constants.PRODUCE_STACK[opcode]; - } + /** + * Use with caution, since `BranchInstruction's have a `target' reference + * which is not copied correctly (only basic types are). This also applies + * for `Select' instructions with their multiple branch targets. + * + * @see BranchInstruction + * @return (shallow) copy of an instruction + */ + public Instruction copy() { + Instruction i = null; + // "Constant" instruction, no need to duplicate + if (InstructionConst.getInstruction(this.getOpcode()) != null) { + i = this; + } else { + try { + i = (Instruction) clone(); + } catch (final CloneNotSupportedException e) { + System.err.println(e); + } + } + return i; + } - /** - * @return this instructions opcode - */ - public short getOpcode() { return opcode; } + /** + * Read needed data (e.g. index) from file. + * + * @param bytes byte sequence to read from + * @param wide "wide" instruction flag + * @throws IOException may be thrown if the implementation needs to read + * data from the file + */ + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + } - /** - * @return length (in bytes) of instruction - */ - public int getLength() { return length; } + /** + * Read an instruction from (byte code) input stream and return the + * appropiate object. + *

    + * If the Instruction is defined in {@link InstructionConst}, then the + * singleton instance is returned. + * + * @param bytes input stream bytes + * @return instruction object being read + * @see InstructionConst#getInstruction(int) + */ + // @since 6.0 no longer final + public static Instruction readInstruction(final ByteSequence bytes) throws IOException { + boolean wide = false; + short opcode = (short) bytes.readUnsignedByte(); + Instruction obj = null; + if (opcode == Const.WIDE) { // Read next opcode after wide byte + wide = true; + opcode = (short) bytes.readUnsignedByte(); + } + final Instruction instruction = InstructionConst.getInstruction(opcode); + if (instruction != null) { + return instruction; // Used predefined immutable object, if available + } - /** - * Needed in readInstruction. - */ - private void setOpcode(short opcode) { this.opcode = opcode; } + switch (opcode) { + case Const.BIPUSH: + obj = new BIPUSH(); + break; + case Const.SIPUSH: + obj = new SIPUSH(); + break; + case Const.LDC: + obj = new LDC(); + break; + case Const.LDC_W: + obj = new LDC_W(); + break; + case Const.LDC2_W: + obj = new LDC2_W(); + break; + case Const.ILOAD: + obj = new ILOAD(); + break; + case Const.LLOAD: + obj = new LLOAD(); + break; + case Const.FLOAD: + obj = new FLOAD(); + break; + case Const.DLOAD: + obj = new DLOAD(); + break; + case Const.ALOAD: + obj = new ALOAD(); + break; + case Const.ILOAD_0: + obj = new ILOAD(0); + break; + case Const.ILOAD_1: + obj = new ILOAD(1); + break; + case Const.ILOAD_2: + obj = new ILOAD(2); + break; + case Const.ILOAD_3: + obj = new ILOAD(3); + break; + case Const.LLOAD_0: + obj = new LLOAD(0); + break; + case Const.LLOAD_1: + obj = new LLOAD(1); + break; + case Const.LLOAD_2: + obj = new LLOAD(2); + break; + case Const.LLOAD_3: + obj = new LLOAD(3); + break; + case Const.FLOAD_0: + obj = new FLOAD(0); + break; + case Const.FLOAD_1: + obj = new FLOAD(1); + break; + case Const.FLOAD_2: + obj = new FLOAD(2); + break; + case Const.FLOAD_3: + obj = new FLOAD(3); + break; + case Const.DLOAD_0: + obj = new DLOAD(0); + break; + case Const.DLOAD_1: + obj = new DLOAD(1); + break; + case Const.DLOAD_2: + obj = new DLOAD(2); + break; + case Const.DLOAD_3: + obj = new DLOAD(3); + break; + case Const.ALOAD_0: + obj = new ALOAD(0); + break; + case Const.ALOAD_1: + obj = new ALOAD(1); + break; + case Const.ALOAD_2: + obj = new ALOAD(2); + break; + case Const.ALOAD_3: + obj = new ALOAD(3); + break; + case Const.ISTORE: + obj = new ISTORE(); + break; + case Const.LSTORE: + obj = new LSTORE(); + break; + case Const.FSTORE: + obj = new FSTORE(); + break; + case Const.DSTORE: + obj = new DSTORE(); + break; + case Const.ASTORE: + obj = new ASTORE(); + break; + case Const.ISTORE_0: + obj = new ISTORE(0); + break; + case Const.ISTORE_1: + obj = new ISTORE(1); + break; + case Const.ISTORE_2: + obj = new ISTORE(2); + break; + case Const.ISTORE_3: + obj = new ISTORE(3); + break; + case Const.LSTORE_0: + obj = new LSTORE(0); + break; + case Const.LSTORE_1: + obj = new LSTORE(1); + break; + case Const.LSTORE_2: + obj = new LSTORE(2); + break; + case Const.LSTORE_3: + obj = new LSTORE(3); + break; + case Const.FSTORE_0: + obj = new FSTORE(0); + break; + case Const.FSTORE_1: + obj = new FSTORE(1); + break; + case Const.FSTORE_2: + obj = new FSTORE(2); + break; + case Const.FSTORE_3: + obj = new FSTORE(3); + break; + case Const.DSTORE_0: + obj = new DSTORE(0); + break; + case Const.DSTORE_1: + obj = new DSTORE(1); + break; + case Const.DSTORE_2: + obj = new DSTORE(2); + break; + case Const.DSTORE_3: + obj = new DSTORE(3); + break; + case Const.ASTORE_0: + obj = new ASTORE(0); + break; + case Const.ASTORE_1: + obj = new ASTORE(1); + break; + case Const.ASTORE_2: + obj = new ASTORE(2); + break; + case Const.ASTORE_3: + obj = new ASTORE(3); + break; + case Const.IINC: + obj = new IINC(); + break; + case Const.IFEQ: + obj = new IFEQ(); + break; + case Const.IFNE: + obj = new IFNE(); + break; + case Const.IFLT: + obj = new IFLT(); + break; + case Const.IFGE: + obj = new IFGE(); + break; + case Const.IFGT: + obj = new IFGT(); + break; + case Const.IFLE: + obj = new IFLE(); + break; + case Const.IF_ICMPEQ: + obj = new IF_ICMPEQ(); + break; + case Const.IF_ICMPNE: + obj = new IF_ICMPNE(); + break; + case Const.IF_ICMPLT: + obj = new IF_ICMPLT(); + break; + case Const.IF_ICMPGE: + obj = new IF_ICMPGE(); + break; + case Const.IF_ICMPGT: + obj = new IF_ICMPGT(); + break; + case Const.IF_ICMPLE: + obj = new IF_ICMPLE(); + break; + case Const.IF_ACMPEQ: + obj = new IF_ACMPEQ(); + break; + case Const.IF_ACMPNE: + obj = new IF_ACMPNE(); + break; + case Const.GOTO: + obj = new GOTO(); + break; + case Const.JSR: + obj = new JSR(); + break; + case Const.RET: + obj = new RET(); + break; + case Const.TABLESWITCH: + obj = new TABLESWITCH(); + break; + case Const.LOOKUPSWITCH: + obj = new LOOKUPSWITCH(); + break; + case Const.GETSTATIC: + obj = new GETSTATIC(); + break; + case Const.PUTSTATIC: + obj = new PUTSTATIC(); + break; + case Const.GETFIELD: + obj = new GETFIELD(); + break; + case Const.PUTFIELD: + obj = new PUTFIELD(); + break; + case Const.INVOKEVIRTUAL: + obj = new INVOKEVIRTUAL(); + break; + case Const.INVOKESPECIAL: + obj = new INVOKESPECIAL(); + break; + case Const.INVOKESTATIC: + obj = new INVOKESTATIC(); + break; + case Const.INVOKEINTERFACE: + obj = new INVOKEINTERFACE(); + break; + case Const.INVOKEDYNAMIC: + obj = new INVOKEDYNAMIC(); + break; + case Const.NEW: + obj = new NEW(); + break; + case Const.NEWARRAY: + obj = new NEWARRAY(); + break; + case Const.ANEWARRAY: + obj = new ANEWARRAY(); + break; + case Const.CHECKCAST: + obj = new CHECKCAST(); + break; + case Const.INSTANCEOF: + obj = new INSTANCEOF(); + break; + case Const.MULTIANEWARRAY: + obj = new MULTIANEWARRAY(); + break; + case Const.IFNULL: + obj = new IFNULL(); + break; + case Const.IFNONNULL: + obj = new IFNONNULL(); + break; + case Const.GOTO_W: + obj = new GOTO_W(); + break; + case Const.JSR_W: + obj = new JSR_W(); + break; + case Const.BREAKPOINT: + obj = new BREAKPOINT(); + break; + case Const.IMPDEP1: + obj = new IMPDEP1(); + break; + case Const.IMPDEP2: + obj = new IMPDEP2(); + break; + default: + throw new ClassGenException("Illegal opcode detected: " + opcode); - /** Some instructions may be reused, so don't do anything by default. - */ - void dispose() {} + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public abstract void accept(Visitor v); + if (wide + && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) { + throw new ClassGenException("Illegal opcode after wide: " + opcode); + } + obj.setOpcode(opcode); + obj.initFromFile(bytes, wide); // Do further initializations, if any + return obj; + } - /** Get Comparator object used in the equals() method to determine - * equality of instructions. - * - * @return currently used comparator for equals() - */ - public static InstructionComparator getComparator() { return cmp; } + /** + * This method also gives right results for instructions whose effect on the + * stack depends on the constant pool entry they reference. + * + * @return Number of words consumed from stack by this instruction, or + * Constants.UNPREDICTABLE, if this can not be computed statically + */ + public int consumeStack(final ConstantPoolGen cpg) { + return Const.getConsumeStack(opcode); + } - /** Set comparator to be used for equals(). - */ - public static void setComparator(InstructionComparator c) { cmp = c; } + /** + * This method also gives right results for instructions whose effect on the + * stack depends on the constant pool entry they reference. + * + * @return Number of words produced onto stack by this instruction, or + * Constants.UNPREDICTABLE, if this can not be computed statically + */ + public int produceStack(final ConstantPoolGen cpg) { + return Const.getProduceStack(opcode); + } - /** Check for equality, delegated to comparator - * @return true if that is an Instruction and has the same opcode - */ - public boolean equals(Object that) { - return (that instanceof Instruction)? - cmp.equals(this, (Instruction)that) : false; - } + /** + * @return this instructions opcode + */ + public short getOpcode() { + return opcode; + } + + /** + * @return length (in bytes) of instruction + */ + public int getLength() { + return length; + } + + /** + * Needed in readInstruction and subclasses in this package + */ + final void setOpcode(final short opcode) { + this.opcode = opcode; + } + + /** + * Needed in readInstruction and subclasses in this package + * + * @since 6.0 + */ + final void setLength(final int length) { + this.length = (short) length; // TODO check range? + } + + /** + * Some instructions may be reused, so don't do anything by default. + */ + void dispose() { + } + + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + public abstract void accept(Visitor v); + + /** + * Get Comparator object used in the equals() method to determine equality + * of instructions. + * + * @return currently used comparator for equals() + * @deprecated (6.0) use the built in comparator, or wrap this class in + * another object that implements these methods + */ + @Deprecated + public static InstructionComparator getComparator() { + return cmp; + } + + /** + * Set comparator to be used for equals(). + * + * @deprecated (6.0) use the built in comparator, or wrap this class in + * another object that implements these methods + */ + @Deprecated + public static void setComparator(final InstructionComparator c) { + cmp = c; + } + + /** + * Check for equality, delegated to comparator + * + * @return true if that is an Instruction and has the same opcode + */ + @Override + public boolean equals(final Object that) { + return (that instanceof Instruction) ? cmp.equals(this, (Instruction) that) : false; + } + + /** + * calculate the hashCode of this object + * + * @return the hashCode + * @since 6.0 + */ + @Override + public int hashCode() { + return opcode; + } + + /** + * Check if the value can fit in a byte (signed) + * + * @param value the value to check + * @return true if the value is in range + * @since 6.0 + */ + public static boolean isValidByte(final int value) { + return value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE; + } + + /** + * Check if the value can fit in a short (signed) + * + * @param value the value to check + * @return true if the value is in range + * @since 6.0 + */ + public static boolean isValidShort(final int value) { + return value >= Short.MIN_VALUE && value <= Short.MAX_VALUE; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java index 03589cb2dbc..a1a17370674 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java @@ -21,7 +21,6 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Equality of instructions isn't clearly to be defined. You might * wish, for example, to compare whether instructions have the same @@ -32,45 +31,36 @@ package com.sun.org.apache.bcel.internal.generic; * instructions must have the same target. * * @see Instruction - * @author M. Dahm + * @version $Id: InstructionComparator.java 1749597 2016-06-21 20:28:51Z ggregory $ */ public interface InstructionComparator { - public static final InstructionComparator DEFAULT = - new InstructionComparator() { - public boolean equals(Instruction i1, Instruction i2) { - if(i1.opcode == i2.opcode) { - if(i1 instanceof Select) { - InstructionHandle[] t1 = ((Select)i1).getTargets(); - InstructionHandle[] t2 = ((Select)i2).getTargets(); - if(t1.length == t2.length) { - for(int i = 0; i < t1.length; i++) { - if(t1[i] != t2[i]) { + InstructionComparator DEFAULT = new InstructionComparator() { + + @Override + public boolean equals( final Instruction i1, final Instruction i2 ) { + if (i1.getOpcode() == i2.getOpcode()) { + if (i1 instanceof BranchInstruction) { + // BIs are never equal to make targeters work correctly (BCEL-195) return false; - } +// } else if (i1 == i2) { TODO consider adding this shortcut +// return true; // this must be AFTER the BI test + } else if (i1 instanceof ConstantPushInstruction) { + return ((ConstantPushInstruction) i1).getValue().equals( + ((ConstantPushInstruction) i2).getValue()); + } else if (i1 instanceof IndexedInstruction) { + return ((IndexedInstruction) i1).getIndex() == ((IndexedInstruction) i2) + .getIndex(); + } else if (i1 instanceof NEWARRAY) { + return ((NEWARRAY) i1).getTypecode() == ((NEWARRAY) i2).getTypecode(); + } else { + return true; } - - return true; - } - } else if(i1 instanceof BranchInstruction) { - return ((BranchInstruction)i1).target == - ((BranchInstruction)i2).target; - } else if(i1 instanceof ConstantPushInstruction) { - return ((ConstantPushInstruction)i1).getValue(). - equals(((ConstantPushInstruction)i2).getValue()); - } else if(i1 instanceof IndexedInstruction) { - return ((IndexedInstruction)i1).getIndex() == - ((IndexedInstruction)i2).getIndex(); - } else if(i1 instanceof NEWARRAY) { - return ((NEWARRAY)i1).getTypecode() == ((NEWARRAY)i2).getTypecode(); - } else { - return true; } - } - - return false; + return false; } - }; + }; - public boolean equals(Instruction i1, Instruction i2); + + boolean equals( Instruction i1, Instruction i2 ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java new file mode 100644 index 00000000000..5e33ab3dd9e --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java @@ -0,0 +1,301 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * This interface contains shareable instruction objects. + * + * In order to save memory you can use some instructions multiply, + * since they have an immutable state and are directly derived from + * Instruction. I.e. they have no instance fields that could be + * changed. Since some of these instructions like ICONST_0 occur + * very frequently this can save a lot of time and space. This + * feature is an adaptation of the FlyWeight design pattern, we + * just use an array instead of a factory. + * + * The Instructions can also accessed directly under their names, so + * it's possible to write il.append(Instruction.ICONST_0); + * + * @version $Id: InstructionConst.java 1695415 2015-08-12 01:02:39Z chas $ + */ +public final class InstructionConst { + + /** + * Predefined instruction objects + */ + /* + * NOTE these are not currently immutable, because Instruction + * has mutable protected fields opcode and length. + */ + public static final Instruction NOP = new NOP(); + public static final Instruction ACONST_NULL = new ACONST_NULL(); + public static final Instruction ICONST_M1 = new ICONST(-1); + public static final Instruction ICONST_0 = new ICONST(0); + public static final Instruction ICONST_1 = new ICONST(1); + public static final Instruction ICONST_2 = new ICONST(2); + public static final Instruction ICONST_3 = new ICONST(3); + public static final Instruction ICONST_4 = new ICONST(4); + public static final Instruction ICONST_5 = new ICONST(5); + public static final Instruction LCONST_0 = new LCONST(0); + public static final Instruction LCONST_1 = new LCONST(1); + public static final Instruction FCONST_0 = new FCONST(0); + public static final Instruction FCONST_1 = new FCONST(1); + public static final Instruction FCONST_2 = new FCONST(2); + public static final Instruction DCONST_0 = new DCONST(0); + public static final Instruction DCONST_1 = new DCONST(1); + public static final ArrayInstruction IALOAD = new IALOAD(); + public static final ArrayInstruction LALOAD = new LALOAD(); + public static final ArrayInstruction FALOAD = new FALOAD(); + public static final ArrayInstruction DALOAD = new DALOAD(); + public static final ArrayInstruction AALOAD = new AALOAD(); + public static final ArrayInstruction BALOAD = new BALOAD(); + public static final ArrayInstruction CALOAD = new CALOAD(); + public static final ArrayInstruction SALOAD = new SALOAD(); + public static final ArrayInstruction IASTORE = new IASTORE(); + public static final ArrayInstruction LASTORE = new LASTORE(); + public static final ArrayInstruction FASTORE = new FASTORE(); + public static final ArrayInstruction DASTORE = new DASTORE(); + public static final ArrayInstruction AASTORE = new AASTORE(); + public static final ArrayInstruction BASTORE = new BASTORE(); + public static final ArrayInstruction CASTORE = new CASTORE(); + public static final ArrayInstruction SASTORE = new SASTORE(); + public static final StackInstruction POP = new POP(); + public static final StackInstruction POP2 = new POP2(); + public static final StackInstruction DUP = new DUP(); + public static final StackInstruction DUP_X1 = new DUP_X1(); + public static final StackInstruction DUP_X2 = new DUP_X2(); + public static final StackInstruction DUP2 = new DUP2(); + public static final StackInstruction DUP2_X1 = new DUP2_X1(); + public static final StackInstruction DUP2_X2 = new DUP2_X2(); + public static final StackInstruction SWAP = new SWAP(); + public static final ArithmeticInstruction IADD = new IADD(); + public static final ArithmeticInstruction LADD = new LADD(); + public static final ArithmeticInstruction FADD = new FADD(); + public static final ArithmeticInstruction DADD = new DADD(); + public static final ArithmeticInstruction ISUB = new ISUB(); + public static final ArithmeticInstruction LSUB = new LSUB(); + public static final ArithmeticInstruction FSUB = new FSUB(); + public static final ArithmeticInstruction DSUB = new DSUB(); + public static final ArithmeticInstruction IMUL = new IMUL(); + public static final ArithmeticInstruction LMUL = new LMUL(); + public static final ArithmeticInstruction FMUL = new FMUL(); + public static final ArithmeticInstruction DMUL = new DMUL(); + public static final ArithmeticInstruction IDIV = new IDIV(); + public static final ArithmeticInstruction LDIV = new LDIV(); + public static final ArithmeticInstruction FDIV = new FDIV(); + public static final ArithmeticInstruction DDIV = new DDIV(); + public static final ArithmeticInstruction IREM = new IREM(); + public static final ArithmeticInstruction LREM = new LREM(); + public static final ArithmeticInstruction FREM = new FREM(); + public static final ArithmeticInstruction DREM = new DREM(); + public static final ArithmeticInstruction INEG = new INEG(); + public static final ArithmeticInstruction LNEG = new LNEG(); + public static final ArithmeticInstruction FNEG = new FNEG(); + public static final ArithmeticInstruction DNEG = new DNEG(); + public static final ArithmeticInstruction ISHL = new ISHL(); + public static final ArithmeticInstruction LSHL = new LSHL(); + public static final ArithmeticInstruction ISHR = new ISHR(); + public static final ArithmeticInstruction LSHR = new LSHR(); + public static final ArithmeticInstruction IUSHR = new IUSHR(); + public static final ArithmeticInstruction LUSHR = new LUSHR(); + public static final ArithmeticInstruction IAND = new IAND(); + public static final ArithmeticInstruction LAND = new LAND(); + public static final ArithmeticInstruction IOR = new IOR(); + public static final ArithmeticInstruction LOR = new LOR(); + public static final ArithmeticInstruction IXOR = new IXOR(); + public static final ArithmeticInstruction LXOR = new LXOR(); + public static final ConversionInstruction I2L = new I2L(); + public static final ConversionInstruction I2F = new I2F(); + public static final ConversionInstruction I2D = new I2D(); + public static final ConversionInstruction L2I = new L2I(); + public static final ConversionInstruction L2F = new L2F(); + public static final ConversionInstruction L2D = new L2D(); + public static final ConversionInstruction F2I = new F2I(); + public static final ConversionInstruction F2L = new F2L(); + public static final ConversionInstruction F2D = new F2D(); + public static final ConversionInstruction D2I = new D2I(); + public static final ConversionInstruction D2L = new D2L(); + public static final ConversionInstruction D2F = new D2F(); + public static final ConversionInstruction I2B = new I2B(); + public static final ConversionInstruction I2C = new I2C(); + public static final ConversionInstruction I2S = new I2S(); + public static final Instruction LCMP = new LCMP(); + public static final Instruction FCMPL = new FCMPL(); + public static final Instruction FCMPG = new FCMPG(); + public static final Instruction DCMPL = new DCMPL(); + public static final Instruction DCMPG = new DCMPG(); + public static final ReturnInstruction IRETURN = new IRETURN(); + public static final ReturnInstruction LRETURN = new LRETURN(); + public static final ReturnInstruction FRETURN = new FRETURN(); + public static final ReturnInstruction DRETURN = new DRETURN(); + public static final ReturnInstruction ARETURN = new ARETURN(); + public static final ReturnInstruction RETURN = new RETURN(); + public static final Instruction ARRAYLENGTH = new ARRAYLENGTH(); + public static final Instruction ATHROW = new ATHROW(); + public static final Instruction MONITORENTER = new MONITORENTER(); + public static final Instruction MONITOREXIT = new MONITOREXIT(); + + /** You can use these constants in multiple places safely, if you can guarantee + * that you will never alter their internal values, e.g. call setIndex(). + */ + public static final LocalVariableInstruction THIS = new ALOAD(0); + public static final LocalVariableInstruction ALOAD_0 = THIS; + public static final LocalVariableInstruction ALOAD_1 = new ALOAD(1); + public static final LocalVariableInstruction ALOAD_2 = new ALOAD(2); + public static final LocalVariableInstruction ILOAD_0 = new ILOAD(0); + public static final LocalVariableInstruction ILOAD_1 = new ILOAD(1); + public static final LocalVariableInstruction ILOAD_2 = new ILOAD(2); + public static final LocalVariableInstruction ASTORE_0 = new ASTORE(0); + public static final LocalVariableInstruction ASTORE_1 = new ASTORE(1); + public static final LocalVariableInstruction ASTORE_2 = new ASTORE(2); + public static final LocalVariableInstruction ISTORE_0 = new ISTORE(0); + public static final LocalVariableInstruction ISTORE_1 = new ISTORE(1); + public static final LocalVariableInstruction ISTORE_2 = new ISTORE(2); + + /** Get object via its opcode, for immutable instructions like + * branch instructions entries are set to null. + */ + private static final Instruction[] INSTRUCTIONS = new Instruction[256]; + + static { + INSTRUCTIONS[Const.NOP] = NOP; + INSTRUCTIONS[Const.ACONST_NULL] = ACONST_NULL; + INSTRUCTIONS[Const.ICONST_M1] = ICONST_M1; + INSTRUCTIONS[Const.ICONST_0] = ICONST_0; + INSTRUCTIONS[Const.ICONST_1] = ICONST_1; + INSTRUCTIONS[Const.ICONST_2] = ICONST_2; + INSTRUCTIONS[Const.ICONST_3] = ICONST_3; + INSTRUCTIONS[Const.ICONST_4] = ICONST_4; + INSTRUCTIONS[Const.ICONST_5] = ICONST_5; + INSTRUCTIONS[Const.LCONST_0] = LCONST_0; + INSTRUCTIONS[Const.LCONST_1] = LCONST_1; + INSTRUCTIONS[Const.FCONST_0] = FCONST_0; + INSTRUCTIONS[Const.FCONST_1] = FCONST_1; + INSTRUCTIONS[Const.FCONST_2] = FCONST_2; + INSTRUCTIONS[Const.DCONST_0] = DCONST_0; + INSTRUCTIONS[Const.DCONST_1] = DCONST_1; + INSTRUCTIONS[Const.IALOAD] = IALOAD; + INSTRUCTIONS[Const.LALOAD] = LALOAD; + INSTRUCTIONS[Const.FALOAD] = FALOAD; + INSTRUCTIONS[Const.DALOAD] = DALOAD; + INSTRUCTIONS[Const.AALOAD] = AALOAD; + INSTRUCTIONS[Const.BALOAD] = BALOAD; + INSTRUCTIONS[Const.CALOAD] = CALOAD; + INSTRUCTIONS[Const.SALOAD] = SALOAD; + INSTRUCTIONS[Const.IASTORE] = IASTORE; + INSTRUCTIONS[Const.LASTORE] = LASTORE; + INSTRUCTIONS[Const.FASTORE] = FASTORE; + INSTRUCTIONS[Const.DASTORE] = DASTORE; + INSTRUCTIONS[Const.AASTORE] = AASTORE; + INSTRUCTIONS[Const.BASTORE] = BASTORE; + INSTRUCTIONS[Const.CASTORE] = CASTORE; + INSTRUCTIONS[Const.SASTORE] = SASTORE; + INSTRUCTIONS[Const.POP] = POP; + INSTRUCTIONS[Const.POP2] = POP2; + INSTRUCTIONS[Const.DUP] = DUP; + INSTRUCTIONS[Const.DUP_X1] = DUP_X1; + INSTRUCTIONS[Const.DUP_X2] = DUP_X2; + INSTRUCTIONS[Const.DUP2] = DUP2; + INSTRUCTIONS[Const.DUP2_X1] = DUP2_X1; + INSTRUCTIONS[Const.DUP2_X2] = DUP2_X2; + INSTRUCTIONS[Const.SWAP] = SWAP; + INSTRUCTIONS[Const.IADD] = IADD; + INSTRUCTIONS[Const.LADD] = LADD; + INSTRUCTIONS[Const.FADD] = FADD; + INSTRUCTIONS[Const.DADD] = DADD; + INSTRUCTIONS[Const.ISUB] = ISUB; + INSTRUCTIONS[Const.LSUB] = LSUB; + INSTRUCTIONS[Const.FSUB] = FSUB; + INSTRUCTIONS[Const.DSUB] = DSUB; + INSTRUCTIONS[Const.IMUL] = IMUL; + INSTRUCTIONS[Const.LMUL] = LMUL; + INSTRUCTIONS[Const.FMUL] = FMUL; + INSTRUCTIONS[Const.DMUL] = DMUL; + INSTRUCTIONS[Const.IDIV] = IDIV; + INSTRUCTIONS[Const.LDIV] = LDIV; + INSTRUCTIONS[Const.FDIV] = FDIV; + INSTRUCTIONS[Const.DDIV] = DDIV; + INSTRUCTIONS[Const.IREM] = IREM; + INSTRUCTIONS[Const.LREM] = LREM; + INSTRUCTIONS[Const.FREM] = FREM; + INSTRUCTIONS[Const.DREM] = DREM; + INSTRUCTIONS[Const.INEG] = INEG; + INSTRUCTIONS[Const.LNEG] = LNEG; + INSTRUCTIONS[Const.FNEG] = FNEG; + INSTRUCTIONS[Const.DNEG] = DNEG; + INSTRUCTIONS[Const.ISHL] = ISHL; + INSTRUCTIONS[Const.LSHL] = LSHL; + INSTRUCTIONS[Const.ISHR] = ISHR; + INSTRUCTIONS[Const.LSHR] = LSHR; + INSTRUCTIONS[Const.IUSHR] = IUSHR; + INSTRUCTIONS[Const.LUSHR] = LUSHR; + INSTRUCTIONS[Const.IAND] = IAND; + INSTRUCTIONS[Const.LAND] = LAND; + INSTRUCTIONS[Const.IOR] = IOR; + INSTRUCTIONS[Const.LOR] = LOR; + INSTRUCTIONS[Const.IXOR] = IXOR; + INSTRUCTIONS[Const.LXOR] = LXOR; + INSTRUCTIONS[Const.I2L] = I2L; + INSTRUCTIONS[Const.I2F] = I2F; + INSTRUCTIONS[Const.I2D] = I2D; + INSTRUCTIONS[Const.L2I] = L2I; + INSTRUCTIONS[Const.L2F] = L2F; + INSTRUCTIONS[Const.L2D] = L2D; + INSTRUCTIONS[Const.F2I] = F2I; + INSTRUCTIONS[Const.F2L] = F2L; + INSTRUCTIONS[Const.F2D] = F2D; + INSTRUCTIONS[Const.D2I] = D2I; + INSTRUCTIONS[Const.D2L] = D2L; + INSTRUCTIONS[Const.D2F] = D2F; + INSTRUCTIONS[Const.I2B] = I2B; + INSTRUCTIONS[Const.I2C] = I2C; + INSTRUCTIONS[Const.I2S] = I2S; + INSTRUCTIONS[Const.LCMP] = LCMP; + INSTRUCTIONS[Const.FCMPL] = FCMPL; + INSTRUCTIONS[Const.FCMPG] = FCMPG; + INSTRUCTIONS[Const.DCMPL] = DCMPL; + INSTRUCTIONS[Const.DCMPG] = DCMPG; + INSTRUCTIONS[Const.IRETURN] = IRETURN; + INSTRUCTIONS[Const.LRETURN] = LRETURN; + INSTRUCTIONS[Const.FRETURN] = FRETURN; + INSTRUCTIONS[Const.DRETURN] = DRETURN; + INSTRUCTIONS[Const.ARETURN] = ARETURN; + INSTRUCTIONS[Const.RETURN] = RETURN; + INSTRUCTIONS[Const.ARRAYLENGTH] = ARRAYLENGTH; + INSTRUCTIONS[Const.ATHROW] = ATHROW; + INSTRUCTIONS[Const.MONITORENTER] = MONITORENTER; + INSTRUCTIONS[Const.MONITOREXIT] = MONITOREXIT; + } + + private InstructionConst() { } // non-instantiable + + /** + * Gets the Instruction. + * @param index the index, e.g. {@link Const#RETURN} + * @return the entry from the private INSTRUCTIONS table + */ + public static Instruction getInstruction(final int index) { + return INSTRUCTIONS[index]; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConstants.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConstants.java deleted file mode 100644 index 4b624d7cf0a..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConstants.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal.generic; - - -import com.sun.org.apache.bcel.internal.Constants; - -/** - * This interface contains shareable instruction objects. - * - * In order to save memory you can use some instructions multiply, - * since they have an immutable state and are directly derived from - * Instruction. I.e. they have no instance fields that could be - * changed. Since some of these instructions like ICONST_0 occur - * very frequently this can save a lot of time and space. This - * feature is an adaptation of the FlyWeight design pattern, we - * just use an array instead of a factory. - * - * The Instructions can also accessed directly under their names, so - * it's possible to write il.append(Instruction.ICONST_0); - * - * @author M. Dahm - */ -public interface InstructionConstants { - /** Predefined instruction objects - */ - public static final Instruction NOP = new NOP(); - public static final Instruction ACONST_NULL = new ACONST_NULL(); - public static final Instruction ICONST_M1 = new ICONST(-1); - public static final Instruction ICONST_0 = new ICONST(0); - public static final Instruction ICONST_1 = new ICONST(1); - public static final Instruction ICONST_2 = new ICONST(2); - public static final Instruction ICONST_3 = new ICONST(3); - public static final Instruction ICONST_4 = new ICONST(4); - public static final Instruction ICONST_5 = new ICONST(5); - public static final Instruction LCONST_0 = new LCONST(0); - public static final Instruction LCONST_1 = new LCONST(1); - public static final Instruction FCONST_0 = new FCONST(0); - public static final Instruction FCONST_1 = new FCONST(1); - public static final Instruction FCONST_2 = new FCONST(2); - public static final Instruction DCONST_0 = new DCONST(0); - public static final Instruction DCONST_1 = new DCONST(1); - public static final ArrayInstruction IALOAD = new IALOAD(); - public static final ArrayInstruction LALOAD = new LALOAD(); - public static final ArrayInstruction FALOAD = new FALOAD(); - public static final ArrayInstruction DALOAD = new DALOAD(); - public static final ArrayInstruction AALOAD = new AALOAD(); - public static final ArrayInstruction BALOAD = new BALOAD(); - public static final ArrayInstruction CALOAD = new CALOAD(); - public static final ArrayInstruction SALOAD = new SALOAD(); - public static final ArrayInstruction IASTORE = new IASTORE(); - public static final ArrayInstruction LASTORE = new LASTORE(); - public static final ArrayInstruction FASTORE = new FASTORE(); - public static final ArrayInstruction DASTORE = new DASTORE(); - public static final ArrayInstruction AASTORE = new AASTORE(); - public static final ArrayInstruction BASTORE = new BASTORE(); - public static final ArrayInstruction CASTORE = new CASTORE(); - public static final ArrayInstruction SASTORE = new SASTORE(); - public static final StackInstruction POP = new POP(); - public static final StackInstruction POP2 = new POP2(); - public static final StackInstruction DUP = new DUP(); - public static final StackInstruction DUP_X1 = new DUP_X1(); - public static final StackInstruction DUP_X2 = new DUP_X2(); - public static final StackInstruction DUP2 = new DUP2(); - public static final StackInstruction DUP2_X1 = new DUP2_X1(); - public static final StackInstruction DUP2_X2 = new DUP2_X2(); - public static final StackInstruction SWAP = new SWAP(); - public static final ArithmeticInstruction IADD = new IADD(); - public static final ArithmeticInstruction LADD = new LADD(); - public static final ArithmeticInstruction FADD = new FADD(); - public static final ArithmeticInstruction DADD = new DADD(); - public static final ArithmeticInstruction ISUB = new ISUB(); - public static final ArithmeticInstruction LSUB = new LSUB(); - public static final ArithmeticInstruction FSUB = new FSUB(); - public static final ArithmeticInstruction DSUB = new DSUB(); - public static final ArithmeticInstruction IMUL = new IMUL(); - public static final ArithmeticInstruction LMUL = new LMUL(); - public static final ArithmeticInstruction FMUL = new FMUL(); - public static final ArithmeticInstruction DMUL = new DMUL(); - public static final ArithmeticInstruction IDIV = new IDIV(); - public static final ArithmeticInstruction LDIV = new LDIV(); - public static final ArithmeticInstruction FDIV = new FDIV(); - public static final ArithmeticInstruction DDIV = new DDIV(); - public static final ArithmeticInstruction IREM = new IREM(); - public static final ArithmeticInstruction LREM = new LREM(); - public static final ArithmeticInstruction FREM = new FREM(); - public static final ArithmeticInstruction DREM = new DREM(); - public static final ArithmeticInstruction INEG = new INEG(); - public static final ArithmeticInstruction LNEG = new LNEG(); - public static final ArithmeticInstruction FNEG = new FNEG(); - public static final ArithmeticInstruction DNEG = new DNEG(); - public static final ArithmeticInstruction ISHL = new ISHL(); - public static final ArithmeticInstruction LSHL = new LSHL(); - public static final ArithmeticInstruction ISHR = new ISHR(); - public static final ArithmeticInstruction LSHR = new LSHR(); - public static final ArithmeticInstruction IUSHR = new IUSHR(); - public static final ArithmeticInstruction LUSHR = new LUSHR(); - public static final ArithmeticInstruction IAND = new IAND(); - public static final ArithmeticInstruction LAND = new LAND(); - public static final ArithmeticInstruction IOR = new IOR(); - public static final ArithmeticInstruction LOR = new LOR(); - public static final ArithmeticInstruction IXOR = new IXOR(); - public static final ArithmeticInstruction LXOR = new LXOR(); - public static final ConversionInstruction I2L = new I2L(); - public static final ConversionInstruction I2F = new I2F(); - public static final ConversionInstruction I2D = new I2D(); - public static final ConversionInstruction L2I = new L2I(); - public static final ConversionInstruction L2F = new L2F(); - public static final ConversionInstruction L2D = new L2D(); - public static final ConversionInstruction F2I = new F2I(); - public static final ConversionInstruction F2L = new F2L(); - public static final ConversionInstruction F2D = new F2D(); - public static final ConversionInstruction D2I = new D2I(); - public static final ConversionInstruction D2L = new D2L(); - public static final ConversionInstruction D2F = new D2F(); - public static final ConversionInstruction I2B = new I2B(); - public static final ConversionInstruction I2C = new I2C(); - public static final ConversionInstruction I2S = new I2S(); - public static final Instruction LCMP = new LCMP(); - public static final Instruction FCMPL = new FCMPL(); - public static final Instruction FCMPG = new FCMPG(); - public static final Instruction DCMPL = new DCMPL(); - public static final Instruction DCMPG = new DCMPG(); - public static final ReturnInstruction IRETURN = new IRETURN(); - public static final ReturnInstruction LRETURN = new LRETURN(); - public static final ReturnInstruction FRETURN = new FRETURN(); - public static final ReturnInstruction DRETURN = new DRETURN(); - public static final ReturnInstruction ARETURN = new ARETURN(); - public static final ReturnInstruction RETURN = new RETURN(); - public static final Instruction ARRAYLENGTH = new ARRAYLENGTH(); - public static final Instruction ATHROW = new ATHROW(); - public static final Instruction MONITORENTER = new MONITORENTER(); - public static final Instruction MONITOREXIT = new MONITOREXIT(); - - /** You can use these constants in multiple places safely, if you can guarantee - * that you will never alter their internal values, e.g. call setIndex(). - */ - public static final LocalVariableInstruction THIS = new ALOAD(0); - public static final LocalVariableInstruction ALOAD_0 = THIS; - public static final LocalVariableInstruction ALOAD_1 = new ALOAD(1); - public static final LocalVariableInstruction ALOAD_2 = new ALOAD(2); - public static final LocalVariableInstruction ILOAD_0 = new ILOAD(0); - public static final LocalVariableInstruction ILOAD_1 = new ILOAD(1); - public static final LocalVariableInstruction ILOAD_2 = new ILOAD(2); - public static final LocalVariableInstruction ASTORE_0 = new ASTORE(0); - public static final LocalVariableInstruction ASTORE_1 = new ASTORE(1); - public static final LocalVariableInstruction ASTORE_2 = new ASTORE(2); - public static final LocalVariableInstruction ISTORE_0 = new ISTORE(0); - public static final LocalVariableInstruction ISTORE_1 = new ISTORE(1); - public static final LocalVariableInstruction ISTORE_2 = new ISTORE(2); - - - /** Get object via its opcode, for immutable instructions like - * branch instructions entries are set to null. - */ - public static final Instruction[] INSTRUCTIONS = new Instruction[256]; - - /** Interfaces may have no static initializers, so we simulate this - * with an inner class. - */ - static final Clinit bla = new Clinit(); - - static class Clinit { - Clinit() { - INSTRUCTIONS[Constants.NOP] = NOP; - INSTRUCTIONS[Constants.ACONST_NULL] = ACONST_NULL; - INSTRUCTIONS[Constants.ICONST_M1] = ICONST_M1; - INSTRUCTIONS[Constants.ICONST_0] = ICONST_0; - INSTRUCTIONS[Constants.ICONST_1] = ICONST_1; - INSTRUCTIONS[Constants.ICONST_2] = ICONST_2; - INSTRUCTIONS[Constants.ICONST_3] = ICONST_3; - INSTRUCTIONS[Constants.ICONST_4] = ICONST_4; - INSTRUCTIONS[Constants.ICONST_5] = ICONST_5; - INSTRUCTIONS[Constants.LCONST_0] = LCONST_0; - INSTRUCTIONS[Constants.LCONST_1] = LCONST_1; - INSTRUCTIONS[Constants.FCONST_0] = FCONST_0; - INSTRUCTIONS[Constants.FCONST_1] = FCONST_1; - INSTRUCTIONS[Constants.FCONST_2] = FCONST_2; - INSTRUCTIONS[Constants.DCONST_0] = DCONST_0; - INSTRUCTIONS[Constants.DCONST_1] = DCONST_1; - INSTRUCTIONS[Constants.IALOAD] = IALOAD; - INSTRUCTIONS[Constants.LALOAD] = LALOAD; - INSTRUCTIONS[Constants.FALOAD] = FALOAD; - INSTRUCTIONS[Constants.DALOAD] = DALOAD; - INSTRUCTIONS[Constants.AALOAD] = AALOAD; - INSTRUCTIONS[Constants.BALOAD] = BALOAD; - INSTRUCTIONS[Constants.CALOAD] = CALOAD; - INSTRUCTIONS[Constants.SALOAD] = SALOAD; - INSTRUCTIONS[Constants.IASTORE] = IASTORE; - INSTRUCTIONS[Constants.LASTORE] = LASTORE; - INSTRUCTIONS[Constants.FASTORE] = FASTORE; - INSTRUCTIONS[Constants.DASTORE] = DASTORE; - INSTRUCTIONS[Constants.AASTORE] = AASTORE; - INSTRUCTIONS[Constants.BASTORE] = BASTORE; - INSTRUCTIONS[Constants.CASTORE] = CASTORE; - INSTRUCTIONS[Constants.SASTORE] = SASTORE; - INSTRUCTIONS[Constants.POP] = POP; - INSTRUCTIONS[Constants.POP2] = POP2; - INSTRUCTIONS[Constants.DUP] = DUP; - INSTRUCTIONS[Constants.DUP_X1] = DUP_X1; - INSTRUCTIONS[Constants.DUP_X2] = DUP_X2; - INSTRUCTIONS[Constants.DUP2] = DUP2; - INSTRUCTIONS[Constants.DUP2_X1] = DUP2_X1; - INSTRUCTIONS[Constants.DUP2_X2] = DUP2_X2; - INSTRUCTIONS[Constants.SWAP] = SWAP; - INSTRUCTIONS[Constants.IADD] = IADD; - INSTRUCTIONS[Constants.LADD] = LADD; - INSTRUCTIONS[Constants.FADD] = FADD; - INSTRUCTIONS[Constants.DADD] = DADD; - INSTRUCTIONS[Constants.ISUB] = ISUB; - INSTRUCTIONS[Constants.LSUB] = LSUB; - INSTRUCTIONS[Constants.FSUB] = FSUB; - INSTRUCTIONS[Constants.DSUB] = DSUB; - INSTRUCTIONS[Constants.IMUL] = IMUL; - INSTRUCTIONS[Constants.LMUL] = LMUL; - INSTRUCTIONS[Constants.FMUL] = FMUL; - INSTRUCTIONS[Constants.DMUL] = DMUL; - INSTRUCTIONS[Constants.IDIV] = IDIV; - INSTRUCTIONS[Constants.LDIV] = LDIV; - INSTRUCTIONS[Constants.FDIV] = FDIV; - INSTRUCTIONS[Constants.DDIV] = DDIV; - INSTRUCTIONS[Constants.IREM] = IREM; - INSTRUCTIONS[Constants.LREM] = LREM; - INSTRUCTIONS[Constants.FREM] = FREM; - INSTRUCTIONS[Constants.DREM] = DREM; - INSTRUCTIONS[Constants.INEG] = INEG; - INSTRUCTIONS[Constants.LNEG] = LNEG; - INSTRUCTIONS[Constants.FNEG] = FNEG; - INSTRUCTIONS[Constants.DNEG] = DNEG; - INSTRUCTIONS[Constants.ISHL] = ISHL; - INSTRUCTIONS[Constants.LSHL] = LSHL; - INSTRUCTIONS[Constants.ISHR] = ISHR; - INSTRUCTIONS[Constants.LSHR] = LSHR; - INSTRUCTIONS[Constants.IUSHR] = IUSHR; - INSTRUCTIONS[Constants.LUSHR] = LUSHR; - INSTRUCTIONS[Constants.IAND] = IAND; - INSTRUCTIONS[Constants.LAND] = LAND; - INSTRUCTIONS[Constants.IOR] = IOR; - INSTRUCTIONS[Constants.LOR] = LOR; - INSTRUCTIONS[Constants.IXOR] = IXOR; - INSTRUCTIONS[Constants.LXOR] = LXOR; - INSTRUCTIONS[Constants.I2L] = I2L; - INSTRUCTIONS[Constants.I2F] = I2F; - INSTRUCTIONS[Constants.I2D] = I2D; - INSTRUCTIONS[Constants.L2I] = L2I; - INSTRUCTIONS[Constants.L2F] = L2F; - INSTRUCTIONS[Constants.L2D] = L2D; - INSTRUCTIONS[Constants.F2I] = F2I; - INSTRUCTIONS[Constants.F2L] = F2L; - INSTRUCTIONS[Constants.F2D] = F2D; - INSTRUCTIONS[Constants.D2I] = D2I; - INSTRUCTIONS[Constants.D2L] = D2L; - INSTRUCTIONS[Constants.D2F] = D2F; - INSTRUCTIONS[Constants.I2B] = I2B; - INSTRUCTIONS[Constants.I2C] = I2C; - INSTRUCTIONS[Constants.I2S] = I2S; - INSTRUCTIONS[Constants.LCMP] = LCMP; - INSTRUCTIONS[Constants.FCMPL] = FCMPL; - INSTRUCTIONS[Constants.FCMPG] = FCMPG; - INSTRUCTIONS[Constants.DCMPL] = DCMPL; - INSTRUCTIONS[Constants.DCMPG] = DCMPG; - INSTRUCTIONS[Constants.IRETURN] = IRETURN; - INSTRUCTIONS[Constants.LRETURN] = LRETURN; - INSTRUCTIONS[Constants.FRETURN] = FRETURN; - INSTRUCTIONS[Constants.DRETURN] = DRETURN; - INSTRUCTIONS[Constants.ARETURN] = ARETURN; - INSTRUCTIONS[Constants.RETURN] = RETURN; - INSTRUCTIONS[Constants.ARRAYLENGTH] = ARRAYLENGTH; - INSTRUCTIONS[Constants.ATHROW] = ATHROW; - INSTRUCTIONS[Constants.MONITORENTER] = MONITORENTER; - INSTRUCTIONS[Constants.MONITOREXIT] = MONITOREXIT; - } - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java index 7deb0eceaa3..f108e79cca4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java @@ -17,573 +17,731 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; /** - * Instances of this class may be used, e.g., to generate typed - * versions of instructions. Its main purpose is to be used as the - * byte code generating backend of a compiler. You can subclass it to - * add your own create methods. + * Instances of this class may be used, e.g., to generate typed versions of + * instructions. Its main purpose is to be used as the byte code generating + * backend of a compiler. You can subclass it to add your own create methods. + *

    + * Note: The static createXXX methods return singleton instances from the + * {@link InstructionConst} class. * - * @author M. Dahm - * @see Constants + * @version $Id: InstructionFactory.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see Const + * @see InstructionConst */ -public class InstructionFactory - implements InstructionConstants, java.io.Serializable -{ - protected ClassGen cg; - protected ConstantPoolGen cp; +public class InstructionFactory { - public InstructionFactory(ClassGen cg, ConstantPoolGen cp) { - this.cg = cg; - this.cp = cp; - } + // N.N. These must agree with the order of Constants.T_CHAR through T_LONG + private static final String[] short_names = { + "C", "F", "D", "B", "S", "I", "L" + }; - /** Initialize with ClassGen object - */ - public InstructionFactory(ClassGen cg) { - this(cg, cg.getConstantPool()); - } + private ClassGen cg; + private ConstantPoolGen cp; - /** Initialize just with ConstantPoolGen object - */ - public InstructionFactory(ConstantPoolGen cp) { - this(null, cp); - } - - /** Create an invoke instruction. - * - * @param class_name name of the called class - * @param name name of the called method - * @param ret_type return type of method - * @param arg_types argument types of method - * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, - * or INVOKESPECIAL - * @see Constants - */ - public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, - Type[] arg_types, short kind) { - int index; - int nargs = 0; - String signature = Type.getMethodSignature(ret_type, arg_types); - - for(int i=0; i < arg_types.length; i++) // Count size of arguments - nargs += arg_types[i].getSize(); - - if(kind == Constants.INVOKEINTERFACE) - index = cp.addInterfaceMethodref(class_name, name, signature); - else - index = cp.addMethodref(class_name, name, signature); - - switch(kind) { - case Constants.INVOKESPECIAL: return new INVOKESPECIAL(index); - case Constants.INVOKEVIRTUAL: return new INVOKEVIRTUAL(index); - case Constants.INVOKESTATIC: return new INVOKESTATIC(index); - case Constants.INVOKEINTERFACE: return new INVOKEINTERFACE(index, nargs + 1); - default: - throw new RuntimeException("Oops: Unknown invoke kind:" + kind); + public InstructionFactory(final ClassGen cg, final ConstantPoolGen cp) { + this.cg = cg; + this.cp = cp; } - } - /** Create a call to the most popular System.out.println() method. - * - * @param s the string to print - */ - public InstructionList createPrintln(String s) { - InstructionList il = new InstructionList(); - int out = cp.addFieldref("java.lang.System", "out", - "Ljava/io/PrintStream;"); - int println = cp.addMethodref("java.io.PrintStream", "println", - "(Ljava/lang/String;)V"); - - il.append(new GETSTATIC(out)); - il.append(new PUSH(cp, s)); - il.append(new INVOKEVIRTUAL(println)); - - return il; - } - - /** Uses PUSH to push a constant value onto the stack. - * @param value must be of type Number, Boolean, Character or String - */ - public Instruction createConstant(Object value) { - PUSH push; - - if(value instanceof Number) - push = new PUSH(cp, (Number)value); - else if(value instanceof String) - push = new PUSH(cp, (String)value); - else if(value instanceof Boolean) - push = new PUSH(cp, (Boolean)value); - else if(value instanceof Character) - push = new PUSH(cp, (Character)value); - else - throw new ClassGenException("Illegal type: " + value.getClass()); - - return push.getInstruction(); - } - - private static class MethodObject { - Type[] arg_types; - Type result_type; - String[] arg_names; - String class_name; - String name; - int access; - - MethodObject(String c, String n, Type r, Type[] a, int acc) { - class_name = c; - name = n; - result_type = r; - arg_types = a; - access = acc; + /** + * Initialize with ClassGen object + */ + public InstructionFactory(final ClassGen cg) { + this(cg, cg.getConstantPool()); } - } - private InvokeInstruction createInvoke(MethodObject m, short kind) { - return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind); - } - - private static MethodObject[] append_mos = { - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.STRING }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.OBJECT }, Constants.ACC_PUBLIC), - null, null, // indices 2, 3 - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.BOOLEAN }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.CHAR }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.FLOAT }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.DOUBLE }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.INT }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte) - new Type[] { Type.INT }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short) - new Type[] { Type.INT }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.LONG }, Constants.ACC_PUBLIC) - }; - - private static final boolean isString(Type type) { - return ((type instanceof ObjectType) && - ((ObjectType)type).getClassName().equals("java.lang.String")); - } - - public Instruction createAppend(Type type) { - byte t = type.getType(); - - if(isString(type)) - return createInvoke(append_mos[0], Constants.INVOKEVIRTUAL); - - switch(t) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_FLOAT: - case Constants.T_DOUBLE: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - case Constants.T_LONG - : return createInvoke(append_mos[t], Constants.INVOKEVIRTUAL); - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return createInvoke(append_mos[1], Constants.INVOKEVIRTUAL); - default: - throw new RuntimeException("Oops: No append for this type? " + type); + /** + * Initialize just with ConstantPoolGen object + */ + public InstructionFactory(final ConstantPoolGen cp) { + this(null, cp); } - } - /** Create a field instruction. - * - * @param class_name name of the accessed class - * @param name name of the referenced field - * @param type type of field - * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC - * @see Constants - */ - public FieldInstruction createFieldAccess(String class_name, String name, Type type, short kind) { - int index; - String signature = type.getSignature(); - - index = cp.addFieldref(class_name, name, signature); - - switch(kind) { - case Constants.GETFIELD: return new GETFIELD(index); - case Constants.PUTFIELD: return new PUTFIELD(index); - case Constants.GETSTATIC: return new GETSTATIC(index); - case Constants.PUTSTATIC: return new PUTSTATIC(index); - - default: - throw new RuntimeException("Oops: Unknown getfield kind:" + kind); + /** + * Create an invoke instruction. (Except for invokedynamic.) + * + * @param class_name name of the called class + * @param name name of the called method + * @param ret_type return type of method + * @param arg_types argument types of method + * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, + * INVOKEVIRTUAL, or INVOKESPECIAL + * @see Const + */ + public InvokeInstruction createInvoke(final String class_name, final String name, final Type ret_type, + final Type[] arg_types, final short kind) { + int index; + int nargs = 0; + final String signature = Type.getMethodSignature(ret_type, arg_types); + for (final Type arg_type : arg_types) { + nargs += arg_type.getSize(); + } + if (kind == Const.INVOKEINTERFACE) { + index = cp.addInterfaceMethodref(class_name, name, signature); + } else { + index = cp.addMethodref(class_name, name, signature); + } + switch (kind) { + case Const.INVOKESPECIAL: + return new INVOKESPECIAL(index); + case Const.INVOKEVIRTUAL: + return new INVOKEVIRTUAL(index); + case Const.INVOKESTATIC: + return new INVOKESTATIC(index); + case Const.INVOKEINTERFACE: + return new INVOKEINTERFACE(index, nargs + 1); + case Const.INVOKEDYNAMIC: + return new INVOKEDYNAMIC(index); + default: + throw new RuntimeException("Oops: Unknown invoke kind: " + kind); + } } - } - /** Create reference to `this' - */ - public static Instruction createThis() { - return new ALOAD(0); - } - - /** Create typed return - */ - public static ReturnInstruction createReturn(Type type) { - switch(type.getType()) { - case Constants.T_ARRAY: - case Constants.T_OBJECT: return ARETURN; - case Constants.T_INT: - case Constants.T_SHORT: - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: return IRETURN; - case Constants.T_FLOAT: return FRETURN; - case Constants.T_DOUBLE: return DRETURN; - case Constants.T_LONG: return LRETURN; - case Constants.T_VOID: return RETURN; - - default: - throw new RuntimeException("Invalid type: " + type); + /** + * Create an invokedynamic instruction. + * + * @param bootstrap_index index into the bootstrap_methods array + * @param name name of the called method + * @param ret_type return type of method + * @param arg_types argument types of method + * @see Constants + */ + /* + * createInvokeDynamic only needed if instrumention code wants to generate + * a new invokedynamic instruction. I don't think we need. (markro) + * + public InvokeInstruction createInvokeDynamic( int bootstrap_index, String name, Type ret_type, + Type[] arg_types) { + int index; + int nargs = 0; + String signature = Type.getMethodSignature(ret_type, arg_types); + for (int i = 0; i < arg_types.length; i++) { + nargs += arg_types[i].getSize(); + } + // UNDONE - needs to be added to ConstantPoolGen + //index = cp.addInvokeDynamic(bootstrap_index, name, signature); + index = 0; + return new INVOKEDYNAMIC(index); + } + */ + /** + * Create a call to the most popular System.out.println() method. + * + * @param s the string to print + */ + public InstructionList createPrintln(final String s) { + final InstructionList il = new InstructionList(); + final int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;"); + final int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V"); + il.append(new GETSTATIC(out)); + il.append(new PUSH(cp, s)); + il.append(new INVOKEVIRTUAL(println)); + return il; } - } - private static final ArithmeticInstruction createBinaryIntOp(char first, String op) { - switch(first) { - case '-' : return ISUB; - case '+' : return IADD; - case '%' : return IREM; - case '*' : return IMUL; - case '/' : return IDIV; - case '&' : return IAND; - case '|' : return IOR; - case '^' : return IXOR; - case '<' : return ISHL; - case '>' : return op.equals(">>>")? (ArithmeticInstruction)IUSHR : - (ArithmeticInstruction)ISHR; - default: throw new RuntimeException("Invalid operand " + op); + /** + * Uses PUSH to push a constant value onto the stack. + * + * @param value must be of type Number, Boolean, Character or String + */ + public Instruction createConstant(final Object value) { + PUSH push; + if (value instanceof Number) { + push = new PUSH(cp, (Number) value); + } else if (value instanceof String) { + push = new PUSH(cp, (String) value); + } else if (value instanceof Boolean) { + push = new PUSH(cp, (Boolean) value); + } else if (value instanceof Character) { + push = new PUSH(cp, (Character) value); + } else { + throw new ClassGenException("Illegal type: " + value.getClass()); + } + return push.getInstruction(); } - } - private static final ArithmeticInstruction createBinaryLongOp(char first, String op) { - switch(first) { - case '-' : return LSUB; - case '+' : return LADD; - case '%' : return LREM; - case '*' : return LMUL; - case '/' : return LDIV; - case '&' : return LAND; - case '|' : return LOR; - case '^' : return LXOR; - case '<' : return LSHL; - case '>' : return op.equals(">>>")? (ArithmeticInstruction)LUSHR : - (ArithmeticInstruction)LSHR; - default: throw new RuntimeException("Invalid operand " + op); + private static class MethodObject { + + final Type[] arg_types; + final Type result_type; + final String class_name; + final String name; + + MethodObject(final String c, final String n, final Type r, final Type[] a) { + class_name = c; + name = n; + result_type = r; + arg_types = a; + } } - } - private static final ArithmeticInstruction createBinaryFloatOp(char op) { - switch(op) { - case '-' : return FSUB; - case '+' : return FADD; - case '*' : return FMUL; - case '/' : return FDIV; - default: throw new RuntimeException("Invalid operand " + op); + private InvokeInstruction createInvoke(final MethodObject m, final short kind) { + return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind); } - } - private static final ArithmeticInstruction createBinaryDoubleOp(char op) { - switch(op) { - case '-' : return DSUB; - case '+' : return DADD; - case '*' : return DMUL; - case '/' : return DDIV; - default: throw new RuntimeException("Invalid operand " + op); + private static final MethodObject[] append_mos = { + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.STRING + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.OBJECT + }), + null, + null, // indices 2, 3 + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.BOOLEAN + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.CHAR + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.FLOAT + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.DOUBLE + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.INT + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte) + new Type[]{ + Type.INT + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short) + new Type[]{ + Type.INT + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.LONG + }) + }; + + private static boolean isString(final Type type) { + return (type instanceof ObjectType) + && ((ObjectType) type).getClassName().equals("java.lang.String"); } - } - /** - * Create binary operation for simple basic types, such as int and float. - * - * @param op operation, such as "+", "*", "<<", etc. - */ - public static ArithmeticInstruction createBinaryOperation(String op, Type type) { - char first = op.toCharArray()[0]; - - switch(type.getType()) { - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - case Constants.T_CHAR: return createBinaryIntOp(first, op); - case Constants.T_LONG: return createBinaryLongOp(first, op); - case Constants.T_FLOAT: return createBinaryFloatOp(first); - case Constants.T_DOUBLE: return createBinaryDoubleOp(first); - default: throw new RuntimeException("Invalid type " + type); + public Instruction createAppend(final Type type) { + final byte t = type.getType(); + if (isString(type)) { + return createInvoke(append_mos[0], Const.INVOKEVIRTUAL); + } + switch (t) { + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_FLOAT: + case Const.T_DOUBLE: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + case Const.T_LONG: + return createInvoke(append_mos[t], Const.INVOKEVIRTUAL); + case Const.T_ARRAY: + case Const.T_OBJECT: + return createInvoke(append_mos[1], Const.INVOKEVIRTUAL); + default: + throw new RuntimeException("Oops: No append for this type? " + type); + } } - } - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createPop(int size) { - return (size == 2)? (StackInstruction)POP2 : - (StackInstruction)POP; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup(int size) { - return (size == 2)? (StackInstruction)DUP2 : - (StackInstruction)DUP; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup_2(int size) { - return (size == 2)? (StackInstruction)DUP2_X2 : - (StackInstruction)DUP_X2; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup_1(int size) { - return (size == 2)? (StackInstruction)DUP2_X1 : - (StackInstruction)DUP_X1; - } - - /** - * @param index index of local variable - */ - public static LocalVariableInstruction createStore(Type type, int index) { - switch(type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: return new ISTORE(index); - case Constants.T_FLOAT: return new FSTORE(index); - case Constants.T_DOUBLE: return new DSTORE(index); - case Constants.T_LONG: return new LSTORE(index); - case Constants.T_ARRAY: - case Constants.T_OBJECT: return new ASTORE(index); - default: throw new RuntimeException("Invalid type " + type); + /** + * Create a field instruction. + * + * @param class_name name of the accessed class + * @param name name of the referenced field + * @param type type of field + * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC + * @see Const + */ + public FieldInstruction createFieldAccess(final String class_name, final String name, final Type type, final short kind) { + int index; + final String signature = type.getSignature(); + index = cp.addFieldref(class_name, name, signature); + switch (kind) { + case Const.GETFIELD: + return new GETFIELD(index); + case Const.PUTFIELD: + return new PUTFIELD(index); + case Const.GETSTATIC: + return new GETSTATIC(index); + case Const.PUTSTATIC: + return new PUTSTATIC(index); + default: + throw new RuntimeException("Oops: Unknown getfield kind:" + kind); + } } - } - /** - * @param index index of local variable - */ - public static LocalVariableInstruction createLoad(Type type, int index) { - switch(type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: return new ILOAD(index); - case Constants.T_FLOAT: return new FLOAD(index); - case Constants.T_DOUBLE: return new DLOAD(index); - case Constants.T_LONG: return new LLOAD(index); - case Constants.T_ARRAY: - case Constants.T_OBJECT: return new ALOAD(index); - default: throw new RuntimeException("Invalid type " + type); + /** + * Create reference to `this' + */ + public static Instruction createThis() { + return new ALOAD(0); } - } - /** - * @param type type of elements of array, i.e., array.getElementType() - */ - public static ArrayInstruction createArrayLoad(Type type) { - switch(type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_BYTE: return BALOAD; - case Constants.T_CHAR: return CALOAD; - case Constants.T_SHORT: return SALOAD; - case Constants.T_INT: return IALOAD; - case Constants.T_FLOAT: return FALOAD; - case Constants.T_DOUBLE: return DALOAD; - case Constants.T_LONG: return LALOAD; - case Constants.T_ARRAY: - case Constants.T_OBJECT: return AALOAD; - default: throw new RuntimeException("Invalid type " + type); + /** + * Create typed return + */ + public static ReturnInstruction createReturn(final Type type) { + switch (type.getType()) { + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.ARETURN; + case Const.T_INT: + case Const.T_SHORT: + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + return InstructionConst.IRETURN; + case Const.T_FLOAT: + return InstructionConst.FRETURN; + case Const.T_DOUBLE: + return InstructionConst.DRETURN; + case Const.T_LONG: + return InstructionConst.LRETURN; + case Const.T_VOID: + return InstructionConst.RETURN; + default: + throw new RuntimeException("Invalid type: " + type); + } } - } - /** - * @param type type of elements of array, i.e., array.getElementType() - */ - public static ArrayInstruction createArrayStore(Type type) { - switch(type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_BYTE: return BASTORE; - case Constants.T_CHAR: return CASTORE; - case Constants.T_SHORT: return SASTORE; - case Constants.T_INT: return IASTORE; - case Constants.T_FLOAT: return FASTORE; - case Constants.T_DOUBLE: return DASTORE; - case Constants.T_LONG: return LASTORE; - case Constants.T_ARRAY: - case Constants.T_OBJECT: return AASTORE; - default: throw new RuntimeException("Invalid type " + type); + private static ArithmeticInstruction createBinaryIntOp(final char first, final String op) { + switch (first) { + case '-': + return InstructionConst.ISUB; + case '+': + return InstructionConst.IADD; + case '%': + return InstructionConst.IREM; + case '*': + return InstructionConst.IMUL; + case '/': + return InstructionConst.IDIV; + case '&': + return InstructionConst.IAND; + case '|': + return InstructionConst.IOR; + case '^': + return InstructionConst.IXOR; + case '<': + return InstructionConst.ISHL; + case '>': + return op.equals(">>>") ? InstructionConst.IUSHR : InstructionConst.ISHR; + default: + throw new RuntimeException("Invalid operand " + op); + } } - } - - /** Create conversion operation for two stack operands, this may be an I2C, instruction, e.g., - * if the operands are basic types and CHECKCAST if they are reference types. - */ - public Instruction createCast(Type src_type, Type dest_type) { - if((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { - byte dest = dest_type.getType(); - byte src = src_type.getType(); - - if(dest == Constants.T_LONG && (src == Constants.T_CHAR || src == Constants.T_BYTE || - src == Constants.T_SHORT)) - src = Constants.T_INT; - - String[] short_names = { "C", "F", "D", "B", "S", "I", "L" }; - - String name = "com.sun.org.apache.bcel.internal.generic." + short_names[src - Constants.T_CHAR] + - "2" + short_names[dest - Constants.T_CHAR]; - - Instruction i = null; - try { - i = (Instruction)java.lang.Class.forName(name).getConstructor().newInstance(); - } catch(Exception e) { - throw new RuntimeException("Could not find instruction: " + name); - } - - return i; - } else if((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { - if(dest_type instanceof ArrayType) - return new CHECKCAST(cp.addArrayClass((ArrayType)dest_type)); - else - return new CHECKCAST(cp.addClass(((ObjectType)dest_type).getClassName())); + private static ArithmeticInstruction createBinaryLongOp(final char first, final String op) { + switch (first) { + case '-': + return InstructionConst.LSUB; + case '+': + return InstructionConst.LADD; + case '%': + return InstructionConst.LREM; + case '*': + return InstructionConst.LMUL; + case '/': + return InstructionConst.LDIV; + case '&': + return InstructionConst.LAND; + case '|': + return InstructionConst.LOR; + case '^': + return InstructionConst.LXOR; + case '<': + return InstructionConst.LSHL; + case '>': + return op.equals(">>>") ? InstructionConst.LUSHR : InstructionConst.LSHR; + default: + throw new RuntimeException("Invalid operand " + op); + } } - else - throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); - } - public GETFIELD createGetField(String class_name, String name, Type t) { - return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); - } - - public GETSTATIC createGetStatic(String class_name, String name, Type t) { - return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); - } - - public PUTFIELD createPutField(String class_name, String name, Type t) { - return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); - } - - public PUTSTATIC createPutStatic(String class_name, String name, Type t) { - return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); - } - - public CHECKCAST createCheckCast(ReferenceType t) { - if(t instanceof ArrayType) - return new CHECKCAST(cp.addArrayClass((ArrayType)t)); - else - return new CHECKCAST(cp.addClass((ObjectType)t)); - } - - public INSTANCEOF createInstanceOf(ReferenceType t) { - if(t instanceof ArrayType) - return new INSTANCEOF(cp.addArrayClass((ArrayType)t)); - else - return new INSTANCEOF(cp.addClass((ObjectType)t)); - } - - public NEW createNew(ObjectType t) { - return new NEW(cp.addClass(t)); - } - - public NEW createNew(String s) { - return createNew(new ObjectType(s)); - } - - /** Create new array of given size and type. - * @return an instruction that creates the corresponding array at runtime, i.e. is an AllocationInstruction - */ - public Instruction createNewArray(Type t, short dim) { - if(dim == 1) { - if(t instanceof ObjectType) - return new ANEWARRAY(cp.addClass((ObjectType)t)); - else if(t instanceof ArrayType) - return new ANEWARRAY(cp.addArrayClass((ArrayType)t)); - else - return new NEWARRAY(((BasicType)t).getType()); - } else { - ArrayType at; - - if(t instanceof ArrayType) - at = (ArrayType)t; - else - at = new ArrayType(t, dim); - - return new MULTIANEWARRAY(cp.addArrayClass(at), dim); + private static ArithmeticInstruction createBinaryFloatOp(final char op) { + switch (op) { + case '-': + return InstructionConst.FSUB; + case '+': + return InstructionConst.FADD; + case '*': + return InstructionConst.FMUL; + case '/': + return InstructionConst.FDIV; + case '%': + return InstructionConst.FREM; + default: + throw new RuntimeException("Invalid operand " + op); + } } - } - /** Create "null" value for reference types, 0 for basic types like int - */ - public static Instruction createNull(Type type) { - switch(type.getType()) { - case Constants.T_ARRAY: - case Constants.T_OBJECT: return ACONST_NULL; - case Constants.T_INT: - case Constants.T_SHORT: - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: return ICONST_0; - case Constants.T_FLOAT: return FCONST_0; - case Constants.T_DOUBLE: return DCONST_0; - case Constants.T_LONG: return LCONST_0; - case Constants.T_VOID: return NOP; - - default: - throw new RuntimeException("Invalid type: " + type); + private static ArithmeticInstruction createBinaryDoubleOp(final char op) { + switch (op) { + case '-': + return InstructionConst.DSUB; + case '+': + return InstructionConst.DADD; + case '*': + return InstructionConst.DMUL; + case '/': + return InstructionConst.DDIV; + case '%': + return InstructionConst.DREM; + default: + throw new RuntimeException("Invalid operand " + op); + } } - } - /** Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH. - * For those you should use the SWITCH compound instruction. - */ - public static BranchInstruction createBranchInstruction(short opcode, InstructionHandle target) { - switch(opcode) { - case Constants.IFEQ: return new IFEQ(target); - case Constants.IFNE: return new IFNE(target); - case Constants.IFLT: return new IFLT(target); - case Constants.IFGE: return new IFGE(target); - case Constants.IFGT: return new IFGT(target); - case Constants.IFLE: return new IFLE(target); - case Constants.IF_ICMPEQ: return new IF_ICMPEQ(target); - case Constants.IF_ICMPNE: return new IF_ICMPNE(target); - case Constants.IF_ICMPLT: return new IF_ICMPLT(target); - case Constants.IF_ICMPGE: return new IF_ICMPGE(target); - case Constants.IF_ICMPGT: return new IF_ICMPGT(target); - case Constants.IF_ICMPLE: return new IF_ICMPLE(target); - case Constants.IF_ACMPEQ: return new IF_ACMPEQ(target); - case Constants.IF_ACMPNE: return new IF_ACMPNE(target); - case Constants.GOTO: return new GOTO(target); - case Constants.JSR: return new JSR(target); - case Constants.IFNULL: return new IFNULL(target); - case Constants.IFNONNULL: return new IFNONNULL(target); - case Constants.GOTO_W: return new GOTO_W(target); - case Constants.JSR_W: return new JSR_W(target); - default: - throw new RuntimeException("Invalid opcode: " + opcode); + /** + * Create binary operation for simple basic types, such as int and float. + * + * @param op operation, such as "+", "*", "<<", etc. + */ + public static ArithmeticInstruction createBinaryOperation(final String op, final Type type) { + final char first = op.charAt(0); + switch (type.getType()) { + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + case Const.T_CHAR: + return createBinaryIntOp(first, op); + case Const.T_LONG: + return createBinaryLongOp(first, op); + case Const.T_FLOAT: + return createBinaryFloatOp(first); + case Const.T_DOUBLE: + return createBinaryDoubleOp(first); + default: + throw new RuntimeException("Invalid type " + type); + } } - } - public void setClassGen(ClassGen c) { cg = c; } - public ClassGen getClassGen() { return cg; } - public void setConstantPool(ConstantPoolGen c) { cp = c; } - public ConstantPoolGen getConstantPool() { return cp; } + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createPop(final int size) { + return (size == 2) ? InstructionConst.POP2 : InstructionConst.POP; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup(final int size) { + return (size == 2) ? InstructionConst.DUP2 : InstructionConst.DUP; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup_2(final int size) { + return (size == 2) ? InstructionConst.DUP2_X2 : InstructionConst.DUP_X2; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup_1(final int size) { + return (size == 2) ? InstructionConst.DUP2_X1 : InstructionConst.DUP_X1; + } + + /** + * @param index index of local variable + */ + public static LocalVariableInstruction createStore(final Type type, final int index) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + return new ISTORE(index); + case Const.T_FLOAT: + return new FSTORE(index); + case Const.T_DOUBLE: + return new DSTORE(index); + case Const.T_LONG: + return new LSTORE(index); + case Const.T_ARRAY: + case Const.T_OBJECT: + return new ASTORE(index); + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param index index of local variable + */ + public static LocalVariableInstruction createLoad(final Type type, final int index) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + return new ILOAD(index); + case Const.T_FLOAT: + return new FLOAD(index); + case Const.T_DOUBLE: + return new DLOAD(index); + case Const.T_LONG: + return new LLOAD(index); + case Const.T_ARRAY: + case Const.T_OBJECT: + return new ALOAD(index); + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param type type of elements of array, i.e., array.getElementType() + */ + public static ArrayInstruction createArrayLoad(final Type type) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_BYTE: + return InstructionConst.BALOAD; + case Const.T_CHAR: + return InstructionConst.CALOAD; + case Const.T_SHORT: + return InstructionConst.SALOAD; + case Const.T_INT: + return InstructionConst.IALOAD; + case Const.T_FLOAT: + return InstructionConst.FALOAD; + case Const.T_DOUBLE: + return InstructionConst.DALOAD; + case Const.T_LONG: + return InstructionConst.LALOAD; + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.AALOAD; + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param type type of elements of array, i.e., array.getElementType() + */ + public static ArrayInstruction createArrayStore(final Type type) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_BYTE: + return InstructionConst.BASTORE; + case Const.T_CHAR: + return InstructionConst.CASTORE; + case Const.T_SHORT: + return InstructionConst.SASTORE; + case Const.T_INT: + return InstructionConst.IASTORE; + case Const.T_FLOAT: + return InstructionConst.FASTORE; + case Const.T_DOUBLE: + return InstructionConst.DASTORE; + case Const.T_LONG: + return InstructionConst.LASTORE; + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.AASTORE; + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * Create conversion operation for two stack operands, this may be an I2C, + * instruction, e.g., if the operands are basic types and CHECKCAST if they + * are reference types. + */ + public Instruction createCast(final Type src_type, final Type dest_type) { + if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { + final byte dest = dest_type.getType(); + byte src = src_type.getType(); + if (dest == Const.T_LONG + && (src == Const.T_CHAR || src == Const.T_BYTE || src == Const.T_SHORT)) { + src = Const.T_INT; + } + final String name = "com.sun.org.apache.bcel.internal.generic." + short_names[src - Const.T_CHAR] + "2" + + short_names[dest - Const.T_CHAR]; + Instruction i = null; + try { + i = (Instruction) java.lang.Class.forName(name).newInstance(); + } catch (final Exception e) { + throw new RuntimeException("Could not find instruction: " + name, e); + } + return i; + } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { + if (dest_type instanceof ArrayType) { + return new CHECKCAST(cp.addArrayClass((ArrayType) dest_type)); + } + return new CHECKCAST(cp.addClass(((ObjectType) dest_type).getClassName())); + } else { + throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); + } + } + + public GETFIELD createGetField(final String class_name, final String name, final Type t) { + return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); + } + + public GETSTATIC createGetStatic(final String class_name, final String name, final Type t) { + return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); + } + + public PUTFIELD createPutField(final String class_name, final String name, final Type t) { + return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); + } + + public PUTSTATIC createPutStatic(final String class_name, final String name, final Type t) { + return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); + } + + public CHECKCAST createCheckCast(final ReferenceType t) { + if (t instanceof ArrayType) { + return new CHECKCAST(cp.addArrayClass((ArrayType) t)); + } + return new CHECKCAST(cp.addClass((ObjectType) t)); + } + + public INSTANCEOF createInstanceOf(final ReferenceType t) { + if (t instanceof ArrayType) { + return new INSTANCEOF(cp.addArrayClass((ArrayType) t)); + } + return new INSTANCEOF(cp.addClass((ObjectType) t)); + } + + public NEW createNew(final ObjectType t) { + return new NEW(cp.addClass(t)); + } + + public NEW createNew(final String s) { + return createNew(ObjectType.getInstance(s)); + } + + /** + * Create new array of given size and type. + * + * @return an instruction that creates the corresponding array at runtime, + * i.e. is an AllocationInstruction + */ + public Instruction createNewArray(final Type t, final short dim) { + if (dim == 1) { + if (t instanceof ObjectType) { + return new ANEWARRAY(cp.addClass((ObjectType) t)); + } else if (t instanceof ArrayType) { + return new ANEWARRAY(cp.addArrayClass((ArrayType) t)); + } else { + return new NEWARRAY(t.getType()); + } + } + ArrayType at; + if (t instanceof ArrayType) { + at = (ArrayType) t; + } else { + at = new ArrayType(t, dim); + } + return new MULTIANEWARRAY(cp.addArrayClass(at), dim); + } + + /** + * Create "null" value for reference types, 0 for basic types like int + */ + public static Instruction createNull(final Type type) { + switch (type.getType()) { + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.ACONST_NULL; + case Const.T_INT: + case Const.T_SHORT: + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + return InstructionConst.ICONST_0; + case Const.T_FLOAT: + return InstructionConst.FCONST_0; + case Const.T_DOUBLE: + return InstructionConst.DCONST_0; + case Const.T_LONG: + return InstructionConst.LCONST_0; + case Const.T_VOID: + return InstructionConst.NOP; + default: + throw new RuntimeException("Invalid type: " + type); + } + } + + /** + * Create branch instruction by given opcode, except LOOKUPSWITCH and + * TABLESWITCH. For those you should use the SWITCH compound instruction. + */ + public static BranchInstruction createBranchInstruction(final short opcode, final InstructionHandle target) { + switch (opcode) { + case Const.IFEQ: + return new IFEQ(target); + case Const.IFNE: + return new IFNE(target); + case Const.IFLT: + return new IFLT(target); + case Const.IFGE: + return new IFGE(target); + case Const.IFGT: + return new IFGT(target); + case Const.IFLE: + return new IFLE(target); + case Const.IF_ICMPEQ: + return new IF_ICMPEQ(target); + case Const.IF_ICMPNE: + return new IF_ICMPNE(target); + case Const.IF_ICMPLT: + return new IF_ICMPLT(target); + case Const.IF_ICMPGE: + return new IF_ICMPGE(target); + case Const.IF_ICMPGT: + return new IF_ICMPGT(target); + case Const.IF_ICMPLE: + return new IF_ICMPLE(target); + case Const.IF_ACMPEQ: + return new IF_ACMPEQ(target); + case Const.IF_ACMPNE: + return new IF_ACMPNE(target); + case Const.GOTO: + return new GOTO(target); + case Const.JSR: + return new JSR(target); + case Const.IFNULL: + return new IFNULL(target); + case Const.IFNONNULL: + return new IFNONNULL(target); + case Const.GOTO_W: + return new GOTO_W(target); + case Const.JSR_W: + return new JSR_W(target); + default: + throw new RuntimeException("Invalid opcode: " + opcode); + } + } + + public void setClassGen(final ClassGen c) { + cg = c; + } + + public ClassGen getClassGen() { + return cg; + } + + public void setConstantPool(final ConstantPoolGen c) { + cp = c; + } + + public ConstantPoolGen getConstantPool() { + return cp; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java index c490f3550f3..85a7dadcb84 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,234 +17,298 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.classfile.Utility; -import java.util.HashSet; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Instances of this class give users a handle to the instructions contained in * an InstructionList. Instruction objects may be used more than once within a * list, this is useful because it saves memory and may be much faster. * - * Within an InstructionList an InstructionHandle object is wrapped - * around all instructions, i.e., it implements a cell in a - * doubly-linked list. From the outside only the next and the - * previous instruction (handle) are accessible. One - * can traverse the list via an Enumeration returned by + * Within an InstructionList an InstructionHandle object is wrapped around all + * instructions, i.e., it implements a cell in a doubly-linked list. From the + * outside only the next and the previous instruction (handle) are accessible. + * One can traverse the list via an Enumeration returned by * InstructionList.elements(). * - * @author M. Dahm + * @version $Id: InstructionHandle.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Instruction * @see BranchHandle * @see InstructionList */ -public class InstructionHandle implements java.io.Serializable { - InstructionHandle next, prev; // Will be set from the outside - Instruction instruction; - protected int i_position = -1; // byte code offset of instruction - private HashSet targeters; - private HashMap attributes; +public class InstructionHandle { - public final InstructionHandle getNext() { return next; } - public final InstructionHandle getPrev() { return prev; } - public final Instruction getInstruction() { return instruction; } + private InstructionHandle next; + private InstructionHandle prev; + private Instruction instruction; - /** - * Replace current instruction contained in this handle. - * Old instruction is disposed using Instruction.dispose(). - */ - public void setInstruction(Instruction i) { // Overridden in BranchHandle - if(i == null) - throw new ClassGenException("Assigning null to handle"); + private int i_position = -1; // byte code offset of instruction - if((this.getClass() != BranchHandle.class) && (i instanceof BranchInstruction)) - throw new ClassGenException("Assigning branch instruction " + i + " to plain handle"); + private Set targeters; + private Map attributes; - if(instruction != null) - instruction.dispose(); - - instruction = i; - } - - /** - * Temporarily swap the current instruction, without disturbing - * anything. Meant to be used by a debugger, implementing - * breakpoints. Current instruction is returned. - */ - public Instruction swapInstruction(Instruction i) { - Instruction oldInstruction = instruction; - instruction = i; - return oldInstruction; - } - - /*private*/ protected InstructionHandle(Instruction i) { - setInstruction(i); - } - - private static InstructionHandle ih_list = null; // List of reusable handles - - /** Factory method. - */ - static final InstructionHandle getInstructionHandle(Instruction i) { - if(ih_list == null) - return new InstructionHandle(i); - else { - InstructionHandle ih = ih_list; - ih_list = ih.next; - - ih.setInstruction(i); - - return ih; + public final InstructionHandle getNext() { + return next; } - } - /** - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions()' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition(int offset, int max_offset) { - i_position += offset; - return 0; - } + public final InstructionHandle getPrev() { + return prev; + } - /** @return the position, i.e., the byte code offset of the contained - * instruction. This is accurate only after - * InstructionList.setPositions() has been called. - */ - public int getPosition() { return i_position; } + public final Instruction getInstruction() { + return instruction; + } - /** Set the position, i.e., the byte code offset of the contained - * instruction. - */ - void setPosition(int pos) { i_position = pos; } + /** + * Replace current instruction contained in this handle. Old instruction is + * disposed using Instruction.dispose(). + */ + public void setInstruction(final Instruction i) { // Overridden in BranchHandle TODO could be package-protected? + if (i == null) { + throw new ClassGenException("Assigning null to handle"); + } + if ((this.getClass() != BranchHandle.class) && (i instanceof BranchInstruction)) { + throw new ClassGenException("Assigning branch instruction " + i + " to plain handle"); + } + if (instruction != null) { + instruction.dispose(); + } + instruction = i; + } - /** Overridden in BranchHandle - */ - protected void addHandle() { - next = ih_list; - ih_list = this; - } + /** + * Temporarily swap the current instruction, without disturbing anything. + * Meant to be used by a debugger, implementing breakpoints. Current + * instruction is returned. + *

    + * Warning: if this is used on a BranchHandle then some methods such as + * getPosition() will still refer to the original cached instruction, + * whereas other BH methods may affect the cache and the replacement + * instruction. + */ + // See BCEL-273 + // TODO remove this method in any redesign of BCEL + public Instruction swapInstruction(final Instruction i) { + final Instruction oldInstruction = instruction; + instruction = i; + return oldInstruction; + } - /** - * Delete contents, i.e., remove user access and make handle reusable. - */ - void dispose() { - next = prev = null; - instruction.dispose(); - instruction = null; - i_position = -1; - attributes = null; - removeAllTargeters(); - addHandle(); - } - /** Remove all targeters, if any. - */ - public void removeAllTargeters() { - if(targeters != null) - targeters.clear(); - } + /*private*/ + protected InstructionHandle(final Instruction i) { + setInstruction(i); + } - /** - * Denote this handle isn't referenced anymore by t. - */ - public void removeTargeter(InstructionTargeter t) { - targeters.remove(t); - } + private static InstructionHandle ih_list = null; // List of reusable handles - /** - * Denote this handle is being referenced by t. - */ - public void addTargeter(InstructionTargeter t) { - if(targeters == null) - targeters = new HashSet(); + /** + * Factory method. + */ + static InstructionHandle getInstructionHandle(final Instruction i) { + if (ih_list == null) { + return new InstructionHandle(i); + } + final InstructionHandle ih = ih_list; + ih_list = ih.next; + ih.setInstruction(i); + return ih; + } - //if(!targeters.contains(t)) - targeters.add(t); - } + /** + * Called by InstructionList.setPositions when setting the position for + * every instruction. In the presence of variable length instructions + * `setPositions()' performs multiple passes over the instruction list to + * calculate the correct (byte) positions and offsets by calling this + * function. + * + * @param offset additional offset caused by preceding (variable length) + * instructions + * @param max_offset the maximum offset that may be caused by these + * instructions + * @return additional offset caused by possible change of this instruction's + * length + */ + protected int updatePosition(final int offset, final int max_offset) { + i_position += offset; + return 0; + } - public boolean hasTargeters() { - return (targeters != null) && (targeters.size() > 0); - } + /** + * @return the position, i.e., the byte code offset of the contained + * instruction. This is accurate only after InstructionList.setPositions() + * has been called. + */ + public int getPosition() { + return i_position; + } - /** - * @return null, if there are no targeters - */ - public InstructionTargeter[] getTargeters() { - if(!hasTargeters()) - return null; + /** + * Set the position, i.e., the byte code offset of the contained + * instruction. + */ + void setPosition(final int pos) { + i_position = pos; + } - InstructionTargeter[] t = new InstructionTargeter[targeters.size()]; - targeters.toArray(t); - return t; - } + /** + * Overridden in BranchHandle + */ + protected void addHandle() { + next = ih_list; + ih_list = this; + } - /** @return a (verbose) string representation of the contained instruction. - */ - public String toString(boolean verbose) { - return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose); - } + /** + * Delete contents, i.e., remove user access and make handle reusable. + */ + void dispose() { + next = prev = null; + instruction.dispose(); + instruction = null; + i_position = -1; + attributes = null; + removeAllTargeters(); + addHandle(); + } - /** @return a string representation of the contained instruction. - */ - public String toString() { - return toString(true); - } + /** + * Remove all targeters, if any. + */ + public void removeAllTargeters() { + if (targeters != null) { + targeters.clear(); + } + } - /** Add an attribute to an instruction handle. - * - * @param key the key object to store/retrieve the attribute - * @param attr the attribute to associate with this handle - */ - public void addAttribute(Object key, Object attr) { - if(attributes == null) - attributes = new HashMap(3); + /** + * Denote this handle isn't referenced anymore by t. + */ + public void removeTargeter(final InstructionTargeter t) { + if (targeters != null) { + targeters.remove(t); + } + } - attributes.put(key, attr); - } + /** + * Denote this handle is being referenced by t. + */ + public void addTargeter(final InstructionTargeter t) { + if (targeters == null) { + targeters = new HashSet<>(); + } + //if(!targeters.contains(t)) + targeters.add(t); + } - /** Delete an attribute of an instruction handle. - * - * @param key the key object to retrieve the attribute - */ - public void removeAttribute(Object key) { - if(attributes != null) - attributes.remove(key); - } + public boolean hasTargeters() { + return (targeters != null) && (targeters.size() > 0); + } - /** Get attribute of an instruction handle. - * - * @param key the key object to store/retrieve the attribute - */ - public Object getAttribute(Object key) { - if(attributes != null) - return attributes.get(key); + /** + * @return null, if there are no targeters + */ + public InstructionTargeter[] getTargeters() { + if (!hasTargeters()) { + return new InstructionTargeter[0]; + } + final InstructionTargeter[] t = new InstructionTargeter[targeters.size()]; + targeters.toArray(t); + return t; + } - return null; - } + /** + * @return a (verbose) string representation of the contained instruction. + */ + public String toString(final boolean verbose) { + return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose); + } - /** @return all attributes associated with this handle - */ - public Collection getAttributes() { - return attributes.values(); - } + /** + * @return a string representation of the contained instruction. + */ + @Override + public String toString() { + return toString(true); + } - /** Convenience method, simply calls accept() on the contained instruction. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - instruction.accept(v); - } + /** + * Add an attribute to an instruction handle. + * + * @param key the key object to store/retrieve the attribute + * @param attr the attribute to associate with this handle + */ + public void addAttribute(final Object key, final Object attr) { + if (attributes == null) { + attributes = new HashMap<>(3); + } + attributes.put(key, attr); + } + + /** + * Delete an attribute of an instruction handle. + * + * @param key the key object to retrieve the attribute + */ + public void removeAttribute(final Object key) { + if (attributes != null) { + attributes.remove(key); + } + } + + /** + * Get attribute of an instruction handle. + * + * @param key the key object to store/retrieve the attribute + */ + public Object getAttribute(final Object key) { + if (attributes != null) { + return attributes.get(key); + } + return null; + } + + /** + * @return all attributes associated with this handle + */ + public Collection getAttributes() { + if (attributes == null) { + attributes = new HashMap<>(3); + } + return attributes.values(); + } + + /** + * Convenience method, simply calls accept() on the contained instruction. + * + * @param v Visitor object + */ + public void accept(final Visitor v) { + instruction.accept(v); + } + + /** + * @param next the next to set + * @ since 6.0 + */ + final InstructionHandle setNext(final InstructionHandle next) { + this.next = next; + return next; + } + + /** + * @param prev the prev to set + * @ since 6.0 + */ + final InstructionHandle setPrev(final InstructionHandle prev) { + this.prev = prev; + return prev; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java index c5bf9b46555..1e5fa2f5771 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,1236 +17,1239 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.Constant; import com.sun.org.apache.bcel.internal.util.ByteSequence; -import java.io.*; -import java.util.Iterator; -import java.util.HashMap; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; /** * This class is a container for a list of Instruction objects. Instructions can - * be appended, inserted, moved, deleted, etc.. Instructions are being - * wrapped into InstructionHandles objects that - * are returned upon append/insert operations. They give the user - * (read only) access to the list structure, such that it can be traversed and - * manipulated in a controlled way. + * href="Instruction.html">Instruction objects. Instructions can be + * appended, inserted, moved, deleted, etc.. Instructions are being wrapped into + * InstructionHandles objects that are + * returned upon append/insert operations. They give the user (read only) access + * to the list structure, such that it can be traversed and manipulated in a + * controlled way. * * A list is finally dumped to a byte code array with getByteCode. * - * @author M. Dahm - * @see Instruction - * @see InstructionHandle + * @version $Id: InstructionList.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see Instruction + * @see InstructionHandle * @see BranchHandle */ -public class InstructionList implements Serializable { - private InstructionHandle start = null, end = null; - private int length = 0; // number of elements in list - private int[] byte_positions; // byte code offsets corresponding to instructions +public class InstructionList implements Iterable { + private InstructionHandle start = null; + private InstructionHandle end = null; + private int length = 0; // number of elements in list + private int[] byte_positions; // byte code offsets corresponding to instructions - /** - * Create (empty) instruction list. - */ - public InstructionList() {} - - /** - * Create instruction list containing one instruction. - * @param i initial instruction - */ - public InstructionList(Instruction i) { - append(i); - } - - /** - * Create instruction list containing one instruction. - * @param i initial instruction - */ - public InstructionList(BranchInstruction i) { - append(i); - } - - /** - * Initialize list with (nonnull) compound instruction. Consumes argument - * list, i.e., it becomes empty. - * - * @param c compound instruction (list) - */ - public InstructionList(CompoundInstruction c) { - append(c.getInstructionList()); - } - - /** - * Test for empty list. - */ - public boolean isEmpty() { return start == null; } // && end == null - - /** - * Find the target instruction (handle) that corresponds to the given target - * position (byte code offset). - * - * @param ihs array of instruction handles, i.e. il.getInstructionHandles() - * @param pos array of positions corresponding to ihs, i.e. il.getInstructionPositions() - * @param count length of arrays - * @param target target position to search for - * @return target position's instruction handle if available - */ - public static InstructionHandle findHandle(InstructionHandle[] ihs, - int[] pos, int count, - int target) { - int l=0, r = count - 1; - - /* Do a binary search since the pos array is orderd. + /** + * Create (empty) instruction list. */ - do { - int i = (l + r) / 2; - int j = pos[i]; + public InstructionList() { + } - if(j == target) // target found - return ihs[i]; - else if(target < j) // else constrain search area - r = i - 1; - else // target > j - l = i + 1; - } while(l <= r); - - return null; - } - - /** - * Get instruction handle for instruction at byte code position pos. - * This only works properly, if the list is freshly initialized from a byte array or - * setPositions() has been called before this method. - * - * @param pos byte code position to search for - * @return target position's instruction handle if available - */ - public InstructionHandle findHandle(int pos) { - InstructionHandle[] ihs = getInstructionHandles(); - return findHandle(ihs, byte_positions, length, pos); - } - - /** - * Initialize instruction list from byte array. - * - * @param code byte array containing the instructions - */ - public InstructionList(byte[] code) { - ByteSequence bytes = new ByteSequence(code); - InstructionHandle[] ihs = new InstructionHandle[code.length]; - int[] pos = new int[code.length]; // Can't be more than that - int count = 0; // Contains actual length - - /* Pass 1: Create an object for each byte code and append them - * to the list. + /** + * Create instruction list containing one instruction. + * + * @param i initial instruction */ - try { - while(bytes.available() > 0) { - // Remember byte offset and associate it with the instruction - int off = bytes.getIndex(); - pos[count] = off; + public InstructionList(final Instruction i) { + append(i); + } - /* Read one instruction from the byte stream, the byte position is set - * accordingly. + /** + * Create instruction list containing one instruction. + * + * @param i initial instruction + */ + public InstructionList(final BranchInstruction i) { + append(i); + } + + /** + * Initialize list with (nonnull) compound instruction. Consumes argument + * list, i.e., it becomes empty. + * + * @param c compound instruction (list) + */ + public InstructionList(final CompoundInstruction c) { + append(c.getInstructionList()); + } + + /** + * Test for empty list. + */ + public boolean isEmpty() { + return start == null; + } // && end == null + + /** + * Find the target instruction (handle) that corresponds to the given target + * position (byte code offset). + * + * @param ihs array of instruction handles, i.e. il.getInstructionHandles() + * @param pos array of positions corresponding to ihs, i.e. + * il.getInstructionPositions() + * @param count length of arrays + * @param target target position to search for + * @return target position's instruction handle if available + */ + public static InstructionHandle findHandle(final InstructionHandle[] ihs, final int[] pos, final int count, final int target) { + int l = 0; + int r = count - 1; + /* + * Do a binary search since the pos array is orderd. */ - Instruction i = Instruction.readInstruction(bytes); - InstructionHandle ih; - if(i instanceof BranchInstruction) // Use proper append() method - ih = append((BranchInstruction)i); - else - ih = append(i); - - ih.setPosition(off); - ihs[count] = ih; - - count++; - } - } catch(IOException e) { throw new ClassGenException(e.toString()); } - - byte_positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, byte_positions, 0, count); - - /* Pass 2: Look for BranchInstruction and update their targets, i.e., - * convert offsets to instruction handles. - */ - for(int i=0; i < count; i++) { - if(ihs[i] instanceof BranchHandle) { - BranchInstruction bi = (BranchInstruction)ihs[i].instruction; - int target = bi.position + bi.getIndex(); /* Byte code position: - * relative -> absolute. */ - // Search for target position - InstructionHandle ih = findHandle(ihs, pos, count, target); - - if(ih == null) // Search failed - throw new ClassGenException("Couldn't find target for branch: " + bi); - - bi.setTarget(ih); // Update target - - // If it is a Select instruction, update all branch targets - if(bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - Select s = (Select)bi; - int[] indices = s.getIndices(); - - for(int j=0; j < indices.length; j++) { - target = bi.position + indices[j]; - ih = findHandle(ihs, pos, count, target); - - if(ih == null) // Search failed - throw new ClassGenException("Couldn't find target for switch: " + bi); - - s.setTarget(j, ih); // Update target - } - } - } - } - } - - /** - * Append another list after instruction (handle) ih contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param ih where to append the instruction list - * @param il Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(InstructionHandle ih, InstructionList il) { - if(il == null) - throw new ClassGenException("Appending null InstructionList"); - - if(il.isEmpty()) // Nothing to do - return ih; - - InstructionHandle next = ih.next, ret = il.start; - - ih.next = il.start; - il.start.prev = ih; - - il.end.next = next; - - if(next != null) // i == end ? - next.prev = il.end; - else - end = il.end; // Update end ... - - length += il.length; // Update length - - il.clear(); - - return ret; - } - - /** - * Append another list after instruction i contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(Instruction i, InstructionList il) { - InstructionHandle ih; - - if((ih = findInstruction2(i)) == null) // Also applies for empty list - throw new ClassGenException("Instruction " + i + - " is not contained in this list."); - - return append(ih, il); - } - - /** - * Append another list to this one. - * Consumes argument list, i.e., it becomes empty. - * - * @param il list to append to end of this list - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(InstructionList il) { - if(il == null) - throw new ClassGenException("Appending null InstructionList"); - - if(il.isEmpty()) // Nothing to do - return null; - - if(isEmpty()) { - start = il.start; - end = il.end; - length = il.length; - - il.clear(); - - return start; - } else - return append(end, il); // was end.instruction - } - - /** - * Append an instruction to the end of this list. - * - * @param ih instruction to append - */ - private void append(InstructionHandle ih) { - if(isEmpty()) { - start = end = ih; - ih.next = ih.prev = null; - } - else { - end.next = ih; - ih.prev = end; - ih.next = null; - end = ih; - } - - length++; // Update length - } - - /** - * Append an instruction to the end of this list. - * - * @param i instruction to append - * @return instruction handle of the appended instruction - */ - public InstructionHandle append(Instruction i) { - InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - append(ih); - - return ih; - } - - /** - * Append a branch instruction to the end of this list. - * - * @param i branch instruction to append - * @return branch instruction handle of the appended instruction - */ - public BranchHandle append(BranchInstruction i) { - BranchHandle ih = BranchHandle.getBranchHandle(i); - append(ih); - - return ih; - } - - /** - * Append a single instruction j after another instruction i, which - * must be in this list of course! - * - * @param i Instruction in list - * @param j Instruction to append after i in list - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(Instruction i, Instruction j) { - return append(i, new InstructionList(j)); - } - - /** - * Append a compound instruction, after instruction i. - * - * @param i Instruction in list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(Instruction i, CompoundInstruction c) { - return append(i, c.getInstructionList()); - } - - /** - * Append a compound instruction. - * - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(CompoundInstruction c) { - return append(c.getInstructionList()); - } - - /** - * Append a compound instruction. - * - * @param ih where to append the instruction list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(InstructionHandle ih, CompoundInstruction c) { - return append(ih, c.getInstructionList()); - } - - /** - * Append an instruction after instruction (handle) ih contained in this list. - * - * @param ih where to append the instruction list - * @param i Instruction to append - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(InstructionHandle ih, Instruction i) { - return append(ih, new InstructionList(i)); - } - - /** - * Append an instruction after instruction (handle) ih contained in this list. - * - * @param ih where to append the instruction list - * @param i Instruction to append - * @return instruction handle pointing to the first appended instruction - */ - public BranchHandle append(InstructionHandle ih, BranchInstruction i) { - BranchHandle bh = BranchHandle.getBranchHandle(i); - InstructionList il = new InstructionList(); - il.append(bh); - - append(ih, il); - - return bh; - } - - /** - * Insert another list before Instruction handle ih contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to insert - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionHandle ih, InstructionList il) { - if(il == null) - throw new ClassGenException("Inserting null InstructionList"); - - if(il.isEmpty()) // Nothing to do - return ih; - - InstructionHandle prev = ih.prev, ret = il.start; - - ih.prev = il.end; - il.end.next = ih; - - il.start.prev = prev; - - if(prev != null) // ih == start ? - prev.next = il.start; - else - start = il.start; // Update start ... - - length += il.length; // Update length - - il.clear(); - - return ret; - } - - /** - * Insert another list. - * - * @param il list to insert before start of this list - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionList il) { - if(isEmpty()) { - append(il); // Code is identical for this case - return start; - } - else - return insert(start, il); - } - - /** - * Insert an instruction at start of this list. - * - * @param ih instruction to insert - */ - private void insert(InstructionHandle ih) { - if(isEmpty()) { - start = end = ih; - ih.next = ih.prev = null; - } else { - start.prev = ih; - ih.next = start; - ih.prev = null; - start = ih; - } - - length++; - } - - /** - * Insert another list before Instruction i contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to insert - * @return instruction handle pointing to the first inserted instruction, - * i.e., il.getStart() - */ - public InstructionHandle insert(Instruction i, InstructionList il) { - InstructionHandle ih; - - if((ih = findInstruction1(i)) == null) - throw new ClassGenException("Instruction " + i + - " is not contained in this list."); - - return insert(ih, il); - } - - /** - * Insert an instruction at start of this list. - * - * @param i instruction to insert - * @return instruction handle of the inserted instruction - */ - public InstructionHandle insert(Instruction i) { - InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - insert(ih); - - return ih; - } - - /** - * Insert a branch instruction at start of this list. - * - * @param i branch instruction to insert - * @return branch instruction handle of the appended instruction - */ - public BranchHandle insert(BranchInstruction i) { - BranchHandle ih = BranchHandle.getBranchHandle(i); - insert(ih); - return ih; - } - - /** - * Insert a single instruction j before another instruction i, which - * must be in this list of course! - * - * @param i Instruction in list - * @param j Instruction to insert before i in list - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(Instruction i, Instruction j) { - return insert(i, new InstructionList(j)); - } - - /** - * Insert a compound instruction before instruction i. - * - * @param i Instruction in list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(Instruction i, CompoundInstruction c) { - return insert(i, c.getInstructionList()); - } - - /** - * Insert a compound instruction. - * - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(CompoundInstruction c) { - return insert(c.getInstructionList()); - } - - /** - * Insert an instruction before instruction (handle) ih contained in this list. - * - * @param ih where to insert to the instruction list - * @param i Instruction to insert - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionHandle ih, Instruction i) { - return insert(ih, new InstructionList(i)); - } - - /** - * Insert a compound instruction. - * - * @param ih where to insert the instruction list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionHandle ih, CompoundInstruction c) { - return insert(ih, c.getInstructionList()); - } - - /** - * Insert an instruction before instruction (handle) ih contained in this list. - * - * @param ih where to insert to the instruction list - * @param i Instruction to insert - * @return instruction handle of the first inserted instruction - */ - public BranchHandle insert(InstructionHandle ih, BranchInstruction i) { - BranchHandle bh = BranchHandle.getBranchHandle(i); - InstructionList il = new InstructionList(); - il.append(bh); - - insert(ih, il); - - return bh; - } - - /** - * Take all instructions (handles) from "start" to "end" and append them after the - * new location "target". Of course, "end" must be after "start" and target must - * not be located withing this range. If you want to move something to the start of - * the list use null as value for target.
    - * Any instruction targeters pointing to handles within the block, keep their targets. - * - * @param start of moved block - * @param end of moved block - * @param target of moved block - */ - public void move(InstructionHandle start, InstructionHandle end, InstructionHandle target) { - // Step 1: Check constraints - - if((start == null) || (end == null)) - throw new ClassGenException("Invalid null handle: From " + start + " to " + end); - - if((target == start) || (target == end)) - throw new ClassGenException("Invalid range: From " + start + " to " + end + - " contains target " + target); - - for(InstructionHandle ih = start; ih != end.next; ih = ih.next) { - if(ih == null) // At end of list, end not found yet - throw new ClassGenException("Invalid range: From " + start + " to " + end); - else if(ih == target) // target may be null - throw new ClassGenException("Invalid range: From " + start + " to " + end + - " contains target " + target); - } - - // Step 2: Temporarily remove the given instructions from the list - - InstructionHandle prev = start.prev, next = end.next; - - if(prev != null) - prev.next = next; - else // start == this.start! - this.start = next; - - if(next != null) - next.prev = prev; - else // end == this.end! - this.end = prev; - - start.prev = end.next = null; - - // Step 3: append after target - - if(target == null) { // append to start of list - end.next = this.start; - this.start = start; - } else { - next = target.next; - - target.next = start; - start.prev = target; - end.next = next; - - if(next != null) - next.prev = end; - } - } - - /** - * Move a single instruction (handle) to a new location. - * - * @param ih moved instruction - * @param target new location of moved instruction - */ - public void move(InstructionHandle ih, InstructionHandle target) { - move(ih, ih, target); - } - - /** - * Remove from instruction `prev' to instruction `next' both contained - * in this list. Throws TargetLostException when one of the removed instruction handles - * is still being targeted. - * - * @param prev where to start deleting (predecessor, exclusive) - * @param next where to end deleting (successor, exclusive) - */ - private void remove(InstructionHandle prev, InstructionHandle next) - throws TargetLostException - { - InstructionHandle first, last; // First and last deleted instruction - - if((prev == null) && (next == null)) { // singleton list - first = last = start; - start = end = null; - } else { - if(prev == null) { // At start of list - first = start; - start = next; - } else { - first = prev.next; - prev.next = next; - } - - if(next == null) { // At end of list - last = end; - end = prev; - } else { - last = next.prev; - next.prev = prev; - } - } - - first.prev = null; // Completely separated from rest of list - last.next = null; - - ArrayList target_vec = new ArrayList(); - - for(InstructionHandle ih=first; ih != null; ih = ih.next) - ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets - - StringBuffer buf = new StringBuffer("{ "); - for(InstructionHandle ih=first; ih != null; ih = next) { - next = ih.next; - length--; - - if(ih.hasTargeters()) { // Still got targeters? - target_vec.add(ih); - buf.append(ih.toString(true) + " "); - ih.next = ih.prev = null; - } else - ih.dispose(); - } - - buf.append("}"); - - if(!target_vec.isEmpty()) { - InstructionHandle[] targeted = new InstructionHandle[target_vec.size()]; - target_vec.toArray(targeted); - throw new TargetLostException(targeted, buf.toString()); - } - } - - /** - * Remove instruction from this list. The corresponding Instruction - * handles must not be reused! - * - * @param ih instruction (handle) to remove - */ - public void delete(InstructionHandle ih) throws TargetLostException { - remove(ih.prev, ih.next); - } - - /** - * Remove instruction from this list. The corresponding Instruction - * handles must not be reused! - * - * @param i instruction to remove - */ - public void delete(Instruction i) throws TargetLostException { - InstructionHandle ih; - - if((ih = findInstruction1(i)) == null) - throw new ClassGenException("Instruction " + i + - " is not contained in this list."); - delete(ih); - } - - /** - * Remove instructions from instruction `from' to instruction `to' contained - * in this list. The user must ensure that `from' is an instruction before - * `to', or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from where to start deleting (inclusive) - * @param to where to end deleting (inclusive) - */ - public void delete(InstructionHandle from, InstructionHandle to) - throws TargetLostException - { - remove(from.prev, to.next); - } - - /** - * Remove instructions from instruction `from' to instruction `to' contained - * in this list. The user must ensure that `from' is an instruction before - * `to', or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from where to start deleting (inclusive) - * @param to where to end deleting (inclusive) - */ - public void delete(Instruction from, Instruction to) throws TargetLostException { - InstructionHandle from_ih, to_ih; - - if((from_ih = findInstruction1(from)) == null) - throw new ClassGenException("Instruction " + from + - " is not contained in this list."); - - if((to_ih = findInstruction2(to)) == null) - throw new ClassGenException("Instruction " + to + - " is not contained in this list."); - delete(from_ih, to_ih); - } - - /** - * Search for given Instruction reference, start at beginning of list. - * - * @param i instruction to search for - * @return instruction found on success, null otherwise - */ - private InstructionHandle findInstruction1(Instruction i) { - for(InstructionHandle ih=start; ih != null; ih = ih.next) - if(ih.instruction == i) - return ih; - - return null; - } - - /** - * Search for given Instruction reference, start at end of list - * - * @param i instruction to search for - * @return instruction found on success, null otherwise - */ - private InstructionHandle findInstruction2(Instruction i) { - for(InstructionHandle ih=end; ih != null; ih = ih.prev) - if(ih.instruction == i) - return ih; - - return null; - } - - public boolean contains(InstructionHandle i) { - if(i == null) - return false; - - for(InstructionHandle ih=start; ih != null; ih = ih.next) - if(ih == i) - return true; - - return false; - } - - public boolean contains(Instruction i) { - return findInstruction1(i) != null; - } - - public void setPositions() { - setPositions(false); - } - - /** - * Give all instructions their position number (offset in byte stream), i.e., - * make the list ready to be dumped. - * - * @param check Perform sanity checks, e.g. if all targeted instructions really belong - * to this list - */ - public void setPositions(boolean check) { - int max_additional_bytes = 0, additional_bytes = 0; - int index = 0, count = 0; - int[] pos = new int[length]; - - /* Pass 0: Sanity checks - */ - if(check) { - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - - if(i instanceof BranchInstruction) { // target instruction within list? - Instruction inst = ((BranchInstruction)i).getTarget().instruction; - if(!contains(inst)) - throw new ClassGenException("Branch target of " + - Constants.OPCODE_NAMES[i.opcode] + ":" + - inst + " not in instruction list"); - - if(i instanceof Select) { - InstructionHandle[] targets = ((Select)i).getTargets(); - - for(int j=0; j < targets.length; j++) { - inst = targets[j].instruction; - if(!contains(inst)) - throw new ClassGenException("Branch target of " + - Constants.OPCODE_NAMES[i.opcode] + ":" + - inst + " not in instruction list"); + do { + final int i = (l + r) / 2; + final int j = pos[i]; + if (j == target) { + return ihs[i]; + } else if (target < j) { + r = i - 1; + } else { + l = i + 1; } - } + } while (l <= r); + return null; + } - if(!(ih instanceof BranchHandle)) - throw new ClassGenException("Branch instruction " + - Constants.OPCODE_NAMES[i.opcode] + ":" + + /** + * Get instruction handle for instruction at byte code position pos. This + * only works properly, if the list is freshly initialized from a byte array + * or setPositions() has been called before this method. + * + * @param pos byte code position to search for + * @return target position's instruction handle if available + */ + public InstructionHandle findHandle(final int pos) { + final int[] positions = byte_positions; + InstructionHandle ih = start; + for (int i = 0; i < length; i++) { + if (positions[i] == pos) { + return ih; + } + ih = ih.getNext(); + } + return null; + } + + /** + * Initialize instruction list from byte array. + * + * @param code byte array containing the instructions + */ + public InstructionList(final byte[] code) { + int count = 0; // Contains actual length + int[] pos; + InstructionHandle[] ihs; + try (ByteSequence bytes = new ByteSequence(code)) { + ihs = new InstructionHandle[code.length]; + pos = new int[code.length]; // Can't be more than that + /* + * Pass 1: Create an object for each byte code and append them to the list. + */ + while (bytes.available() > 0) { + // Remember byte offset and associate it with the instruction + final int off = bytes.getIndex(); + pos[count] = off; + /* + * Read one instruction from the byte stream, the byte position is set accordingly. + */ + final Instruction i = Instruction.readInstruction(bytes); + InstructionHandle ih; + if (i instanceof BranchInstruction) { + ih = append((BranchInstruction) i); + } else { + ih = append(i); + } + ih.setPosition(off); + ihs[count] = ih; + count++; + } + } catch (final IOException e) { + throw new ClassGenException(e.toString(), e); + } + byte_positions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, byte_positions, 0, count); + /* + * Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles. + */ + for (int i = 0; i < count; i++) { + if (ihs[i] instanceof BranchHandle) { + final BranchInstruction bi = (BranchInstruction) ihs[i].getInstruction(); + int target = bi.getPosition() + bi.getIndex(); /* + * Byte code position: relative -> absolute. + */ + + // Search for target position + + InstructionHandle ih = findHandle(ihs, pos, count, target); + if (ih == null) { + throw new ClassGenException("Couldn't find target for branch: " + bi); + } + bi.setTarget(ih); // Update target + // If it is a Select instruction, update all branch targets + if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + final Select s = (Select) bi; + final int[] indices = s.getIndices(); + for (int j = 0; j < indices.length; j++) { + target = bi.getPosition() + indices[j]; + ih = findHandle(ihs, pos, count, target); + if (ih == null) { + throw new ClassGenException("Couldn't find target for switch: " + bi); + } + s.setTarget(j, ih); // Update target + } + } + } + } + } + + /** + * Append another list after instruction (handle) ih contained in this list. + * Consumes argument list, i.e., it becomes empty. + * + * @param ih where to append the instruction list + * @param il Instruction list to append to this one + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(final InstructionHandle ih, final InstructionList il) { + if (il == null) { + throw new ClassGenException("Appending null InstructionList"); + } + if (il.isEmpty()) { + return ih; + } + final InstructionHandle next = ih.getNext(); + final InstructionHandle ret = il.start; + ih.setNext(il.start); + il.start.setPrev(ih); + il.end.setNext(next); + if (next != null) { + next.setPrev(il.end); + } else { + end = il.end; // Update end ... + } + length += il.length; // Update length + il.clear(); + return ret; + } + + /** + * Append another list after instruction i contained in this list. Consumes + * argument list, i.e., it becomes empty. + * + * @param i where to append the instruction list + * @param il Instruction list to append to this one + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(final Instruction i, final InstructionList il) { + InstructionHandle ih; + if ((ih = findInstruction2(i)) == null) { + throw new ClassGenException("Instruction " + i + " is not contained in this list."); + } + return append(ih, il); + } + + /** + * Append another list to this one. Consumes argument list, i.e., it becomes + * empty. + * + * @param il list to append to end of this list + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final InstructionList il) { + if (il == null) { + throw new ClassGenException("Appending null InstructionList"); + } + if (il.isEmpty()) { + return null; + } + if (isEmpty()) { + start = il.start; + end = il.end; + length = il.length; + il.clear(); + return start; + } + return append(end, il); // was end.instruction + } + + /** + * Append an instruction to the end of this list. + * + * @param ih instruction to append + */ + private void append(final InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.setNext(ih.setPrev(null)); + } else { + end.setNext(ih); + ih.setPrev(end); + ih.setNext(null); + end = ih; + } + + length++; // Update length + } + + /** + * Append an instruction to the end of this list. + * + * @param i instruction to append + * @return instruction handle of the appended instruction + */ + public InstructionHandle append(final Instruction i) { + final InstructionHandle ih = InstructionHandle.getInstructionHandle(i); + append(ih); + return ih; + } + + /** + * Append a branch instruction to the end of this list. + * + * @param i branch instruction to append + * @return branch instruction handle of the appended instruction + */ + public BranchHandle append(final BranchInstruction i) { + final BranchHandle ih = BranchHandle.getBranchHandle(i); + append(ih); + return ih; + } + + /** + * Append a single instruction j after another instruction i, which must be + * in this list of course! + * + * @param i Instruction in list + * @param j Instruction to append after i in list + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final Instruction i, final Instruction j) { + return append(i, new InstructionList(j)); + } + + /** + * Append a compound instruction, after instruction i. + * + * @param i Instruction in list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final Instruction i, final CompoundInstruction c) { + return append(i, c.getInstructionList()); + } + + /** + * Append a compound instruction. + * + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final CompoundInstruction c) { + return append(c.getInstructionList()); + } + + /** + * Append a compound instruction. + * + * @param ih where to append the instruction list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final InstructionHandle ih, final CompoundInstruction c) { + return append(ih, c.getInstructionList()); + } + + /** + * Append an instruction after instruction (handle) ih contained in this + * list. + * + * @param ih where to append the instruction list + * @param i Instruction to append + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(final InstructionHandle ih, final Instruction i) { + return append(ih, new InstructionList(i)); + } + + /** + * Append an instruction after instruction (handle) ih contained in this + * list. + * + * @param ih where to append the instruction list + * @param i Instruction to append + * @return instruction handle pointing to the first appended + * instruction + */ + public BranchHandle append(final InstructionHandle ih, final BranchInstruction i) { + final BranchHandle bh = BranchHandle.getBranchHandle(i); + final InstructionList il = new InstructionList(); + il.append(bh); + append(ih, il); + return bh; + } + + /** + * Insert another list before Instruction handle ih contained in this list. + * Consumes argument list, i.e., it becomes empty. + * + * @param ih where to append the instruction list + * @param il Instruction list to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final InstructionList il) { + if (il == null) { + throw new ClassGenException("Inserting null InstructionList"); + } + if (il.isEmpty()) { + return ih; + } + final InstructionHandle prev = ih.getPrev(); + final InstructionHandle ret = il.start; + ih.setPrev(il.end); + il.end.setNext(ih); + il.start.setPrev(prev); + if (prev != null) { + prev.setNext(il.start); + } else { + start = il.start; // Update start ... + } + + length += il.length; // Update length + il.clear(); + return ret; + } + + /** + * Insert another list. + * + * @param il list to insert before start of this list + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionList il) { + if (isEmpty()) { + append(il); // Code is identical for this case + return start; + } + return insert(start, il); + } + + /** + * Insert an instruction at start of this list. + * + * @param ih instruction to insert + */ + private void insert(final InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.setNext(ih.setPrev(null)); + } else { + start.setPrev(ih); + ih.setNext(start); + ih.setPrev(null); + start = ih; + } + + length++; + } + + /** + * Insert another list before Instruction i contained in this list. Consumes + * argument list, i.e., it becomes empty. + * + * @param i where to append the instruction list + * @param il Instruction list to insert + * @return instruction handle pointing to the first inserted instruction, + * i.e., il.getStart() + */ + public InstructionHandle insert(final Instruction i, final InstructionList il) { + InstructionHandle ih; + if ((ih = findInstruction1(i)) == null) { + throw new ClassGenException("Instruction " + i + " is not contained in this list."); + } + return insert(ih, il); + } + + /** + * Insert an instruction at start of this list. + * + * @param i instruction to insert + * @return instruction handle of the inserted instruction + */ + public InstructionHandle insert(final Instruction i) { + final InstructionHandle ih = InstructionHandle.getInstructionHandle(i); + insert(ih); + return ih; + } + + /** + * Insert a branch instruction at start of this list. + * + * @param i branch instruction to insert + * @return branch instruction handle of the appended instruction + */ + public BranchHandle insert(final BranchInstruction i) { + final BranchHandle ih = BranchHandle.getBranchHandle(i); + insert(ih); + return ih; + } + + /** + * Insert a single instruction j before another instruction i, which must be + * in this list of course! + * + * @param i Instruction in list + * @param j Instruction to insert before i in list + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final Instruction i, final Instruction j) { + return insert(i, new InstructionList(j)); + } + + /** + * Insert a compound instruction before instruction i. + * + * @param i Instruction in list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final Instruction i, final CompoundInstruction c) { + return insert(i, c.getInstructionList()); + } + + /** + * Insert a compound instruction. + * + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final CompoundInstruction c) { + return insert(c.getInstructionList()); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this + * list. + * + * @param ih where to insert to the instruction list + * @param i Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final Instruction i) { + return insert(ih, new InstructionList(i)); + } + + /** + * Insert a compound instruction. + * + * @param ih where to insert the instruction list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final CompoundInstruction c) { + return insert(ih, c.getInstructionList()); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this + * list. + * + * @param ih where to insert to the instruction list + * @param i Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public BranchHandle insert(final InstructionHandle ih, final BranchInstruction i) { + final BranchHandle bh = BranchHandle.getBranchHandle(i); + final InstructionList il = new InstructionList(); + il.append(bh); + insert(ih, il); + return bh; + } + + /** + * Take all instructions (handles) from "start" to "end" and append them + * after the new location "target". Of course, "end" must be after "start" + * and target must not be located withing this range. If you want to move + * something to the start of the list use null as value for target.
    + * Any instruction targeters pointing to handles within the block, keep + * their targets. + * + * @param start of moved block + * @param end of moved block + * @param target of moved block + */ + public void move(final InstructionHandle start, final InstructionHandle end, final InstructionHandle target) { + // Step 1: Check constraints + if ((start == null) || (end == null)) { + throw new ClassGenException("Invalid null handle: From " + start + " to " + end); + } + if ((target == start) || (target == end)) { + throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target); + } + for (InstructionHandle ih = start; ih != end.getNext(); ih = ih.getNext()) { + if (ih == null) { + throw new ClassGenException("Invalid range: From " + start + " to " + end); + } else if (ih == target) { + throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target); + } + } + // Step 2: Temporarily remove the given instructions from the list + final InstructionHandle prev = start.getPrev(); + InstructionHandle next = end.getNext(); + if (prev != null) { + prev.setNext(next); + } else { + this.start = next; + } + if (next != null) { + next.setPrev(prev); + } else { + this.end = prev; + } + start.setPrev(end.setNext(null)); + // Step 3: append after target + if (target == null) { // append to start of list + if (this.start != null) { + this.start.setPrev(end); + } + end.setNext(this.start); + this.start = start; + } else { + next = target.getNext(); + target.setNext(start); + start.setPrev(target); + end.setNext(next); + if (next != null) { + next.setPrev(end); + } else { + this.end = end; + } + } + } + + /** + * Move a single instruction (handle) to a new location. + * + * @param ih moved instruction + * @param target new location of moved instruction + */ + public void move(final InstructionHandle ih, final InstructionHandle target) { + move(ih, ih, target); + } + + /** + * Remove from instruction `prev' to instruction `next' both contained in + * this list. Throws TargetLostException when one of the removed instruction + * handles is still being targeted. + * + * @param prev where to start deleting (predecessor, exclusive) + * @param next where to end deleting (successor, exclusive) + */ + private void remove(final InstructionHandle prev, InstructionHandle next) throws TargetLostException { + InstructionHandle first; + InstructionHandle last; // First and last deleted instruction + if ((prev == null) && (next == null)) { + first = start; + last = end; + start = end = null; + } else { + if (prev == null) { // At start of list + first = start; + start = next; + } else { + first = prev.getNext(); + prev.setNext(next); + } + if (next == null) { // At end of list + last = end; + end = prev; + } else { + last = next.getPrev(); + next.setPrev(prev); + } + } + first.setPrev(null); // Completely separated from rest of list + last.setNext(null); + final List target_vec = new ArrayList<>(); + for (InstructionHandle ih = first; ih != null; ih = ih.getNext()) { + ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets + } + final StringBuilder buf = new StringBuilder("{ "); + for (InstructionHandle ih = first; ih != null; ih = next) { + next = ih.getNext(); + length--; + if (ih.hasTargeters()) { // Still got targeters? + target_vec.add(ih); + buf.append(ih.toString(true)).append(" "); + ih.setNext(ih.setPrev(null)); + } else { + ih.dispose(); + } + } + buf.append("}"); + if (!target_vec.isEmpty()) { + final InstructionHandle[] targeted = new InstructionHandle[target_vec.size()]; + target_vec.toArray(targeted); + throw new TargetLostException(targeted, buf.toString()); + } + } + + /** + * Remove instruction from this list. The corresponding Instruction handles + * must not be reused! + * + * @param ih instruction (handle) to remove + */ + public void delete(final InstructionHandle ih) throws TargetLostException { + remove(ih.getPrev(), ih.getNext()); + } + + /** + * Remove instruction from this list. The corresponding Instruction handles + * must not be reused! + * + * @param i instruction to remove + */ + public void delete(final Instruction i) throws TargetLostException { + InstructionHandle ih; + if ((ih = findInstruction1(i)) == null) { + throw new ClassGenException("Instruction " + i + " is not contained in this list."); + } + delete(ih); + } + + /** + * Remove instructions from instruction `from' to instruction `to' contained + * in this list. The user must ensure that `from' is an instruction before + * `to', or risk havoc. The corresponding Instruction handles must not be + * reused! + * + * @param from where to start deleting (inclusive) + * @param to where to end deleting (inclusive) + */ + public void delete(final InstructionHandle from, final InstructionHandle to) throws TargetLostException { + remove(from.getPrev(), to.getNext()); + } + + /** + * Remove instructions from instruction `from' to instruction `to' contained + * in this list. The user must ensure that `from' is an instruction before + * `to', or risk havoc. The corresponding Instruction handles must not be + * reused! + * + * @param from where to start deleting (inclusive) + * @param to where to end deleting (inclusive) + */ + public void delete(final Instruction from, final Instruction to) throws TargetLostException { + InstructionHandle from_ih; + InstructionHandle to_ih; + if ((from_ih = findInstruction1(from)) == null) { + throw new ClassGenException("Instruction " + from + " is not contained in this list."); + } + if ((to_ih = findInstruction2(to)) == null) { + throw new ClassGenException("Instruction " + to + " is not contained in this list."); + } + delete(from_ih, to_ih); + } + + /** + * Search for given Instruction reference, start at beginning of list. + * + * @param i instruction to search for + * @return instruction found on success, null otherwise + */ + private InstructionHandle findInstruction1(final Instruction i) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + if (ih.getInstruction() == i) { + return ih; + } + } + return null; + } + + /** + * Search for given Instruction reference, start at end of list + * + * @param i instruction to search for + * @return instruction found on success, null otherwise + */ + private InstructionHandle findInstruction2(final Instruction i) { + for (InstructionHandle ih = end; ih != null; ih = ih.getPrev()) { + if (ih.getInstruction() == i) { + return ih; + } + } + return null; + } + + public boolean contains(final InstructionHandle i) { + if (i == null) { + return false; + } + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + if (ih == i) { + return true; + } + } + return false; + } + + public boolean contains(final Instruction i) { + return findInstruction1(i) != null; + } + + public void setPositions() { // TODO could be package-protected? (some test code would need to be repackaged) + setPositions(false); + } + + /** + * Give all instructions their position number (offset in byte stream), + * i.e., make the list ready to be dumped. + * + * @param check Perform sanity checks, e.g. if all targeted instructions + * really belong to this list + */ + public void setPositions(final boolean check) { // called by code in other packages + int max_additional_bytes = 0; + int additional_bytes = 0; + int index = 0; + int count = 0; + final int[] pos = new int[length]; + /* + * Pass 0: Sanity checks + */ + if (check) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { // target instruction within list? + Instruction inst = ((BranchInstruction) i).getTarget().getInstruction(); + if (!contains(inst)) { + throw new ClassGenException("Branch target of " + + Const.getOpcodeName(i.getOpcode()) + ":" + + inst + " not in instruction list"); + } + if (i instanceof Select) { + final InstructionHandle[] targets = ((Select) i).getTargets(); + for (final InstructionHandle target : targets) { + inst = target.getInstruction(); + if (!contains(inst)) { + throw new ClassGenException("Branch target of " + + Const.getOpcodeName(i.getOpcode()) + ":" + + inst + " not in instruction list"); + } + } + } + if (!(ih instanceof BranchHandle)) { + throw new ClassGenException( + "Branch instruction " + + Const.getOpcodeName(i.getOpcode()) + ":" + inst + " not contained in BranchHandle."); - + } + } + } } - } - } + /* + * Pass 1: Set position numbers and sum up the maximum number of bytes an instruction may be shifted. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - /* Pass 1: Set position numbers and sum up the maximum number of bytes an - * instruction may be shifted. - */ - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; + final Instruction i = ih.getInstruction(); + ih.setPosition(index); + pos[count++] = index; - ih.setPosition(index); - pos[count++] = index; - - /* Get an estimate about how many additional bytes may be added, because - * BranchInstructions may have variable length depending on the target - * offset (short vs. int) or alignment issues (TABLESWITCH and - * LOOKUPSWITCH). - */ - switch(i.getOpcode()) { - case Constants.JSR: case Constants.GOTO: - max_additional_bytes += 2; - break; - - case Constants.TABLESWITCH: case Constants.LOOKUPSWITCH: - max_additional_bytes += 3; - break; - } - - index += i.getLength(); - } - - /* Pass 2: Expand the variable-length (Branch)Instructions depending on - * the target offset (short or int) and ensure that branch targets are - * within this list. - */ - for(InstructionHandle ih=start; ih != null; ih = ih.next) - additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes); - - /* Pass 3: Update position numbers (which may have changed due to the - * preceding expansions), like pass 1. - */ - index=count=0; - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - - ih.setPosition(index); - pos[count++] = index; - index += i.getLength(); - } - - byte_positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, byte_positions, 0, count); - } - - /** - * When everything is finished, use this method to convert the instruction - * list into an array of bytes. - * - * @return the byte code ready to be dumped - */ - public byte[] getByteCode() { - // Update position indices of instructions - setPositions(); - - ByteArrayOutputStream b = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(b); - - try { - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - i.dump(out); // Traverse list - } - } catch(IOException e) { - System.err.println(e); - return null; - } - - return b.toByteArray(); - } - - /** - * @return an array of instructions without target information for branch instructions. - */ - public Instruction[] getInstructions() { - ByteSequence bytes = new ByteSequence(getByteCode()); - ArrayList instructions = new ArrayList(); - - try { - while(bytes.available() > 0) { - instructions.add(Instruction.readInstruction(bytes)); - } - } catch(IOException e) { throw new ClassGenException(e.toString()); } - - Instruction[] result = new Instruction[instructions.size()]; - instructions.toArray(result); - return result; - } - - public String toString() { - return toString(true); - } - - /** - * @param verbose toggle output format - * @return String containing all instructions in this list. - */ - public String toString(boolean verbose) { - StringBuffer buf = new StringBuffer(); - - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - buf.append(ih.toString(verbose) + "\n"); - } - - return buf.toString(); - } - - /** - * @return Enumeration that lists all instructions (handles) - */ - public Iterator iterator() { - return new Iterator() { - private InstructionHandle ih = start; - - public Object next() { - InstructionHandle i = ih; - ih = ih.next; - return i; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public boolean hasNext() { return ih != null; } - }; - } - - /** - * @return array containing all instructions (handles) - */ - public InstructionHandle[] getInstructionHandles() { - InstructionHandle[] ihs = new InstructionHandle[length]; - InstructionHandle ih = start; - - for(int i=0; i < length; i++) { - ihs[i] = ih; - ih = ih.next; - } - - return ihs; - } - - /** - * Get positions (offsets) of all instructions in the list. This relies on that - * the list has been freshly created from an byte code array, or that setPositions() - * has been called. Otherwise this may be inaccurate. - * - * @return array containing all instruction's offset in byte code - */ - public int[] getInstructionPositions() { return byte_positions; } - - /** - * @return complete, i.e., deep copy of this list - */ - public InstructionList copy() { - HashMap map = new HashMap(); - InstructionList il = new InstructionList(); - - /* Pass 1: Make copies of all instructions, append them to the new list - * and associate old instruction references with the new ones, i.e., - * a 1:1 mapping. - */ - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - Instruction c = i.copy(); // Use clone for shallow copy - - if(c instanceof BranchInstruction) - map.put(ih, il.append((BranchInstruction)c)); - else - map.put(ih, il.append(c)); - } - - /* Pass 2: Update branch targets. - */ - InstructionHandle ih=start; - InstructionHandle ch=il.start; - - while(ih != null) { - Instruction i = ih.instruction; - Instruction c = ch.instruction; - - if(i instanceof BranchInstruction) { - BranchInstruction bi = (BranchInstruction)i; - BranchInstruction bc = (BranchInstruction)c; - InstructionHandle itarget = bi.getTarget(); // old target - - // New target is in hash map - bc.setTarget((InstructionHandle)map.get(itarget)); - - if(bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionHandle[] itargets = ((Select)bi).getTargets(); - InstructionHandle[] ctargets = ((Select)bc).getTargets(); - - for(int j=0; j < itargets.length; j++) { // Update all targets - ctargets[j] = (InstructionHandle)map.get(itargets[j]); - } + /* + * Get an estimate about how many additional bytes may be added, + * because BranchInstructions may have variable length depending on the target offset + * (short vs. int) or alignment issues (TABLESWITCH and LOOKUPSWITCH). + */ + switch (i.getOpcode()) { + case Const.JSR: + case Const.GOTO: + max_additional_bytes += 2; + break; + case Const.TABLESWITCH: + case Const.LOOKUPSWITCH: + max_additional_bytes += 3; + break; + } + index += i.getLength(); } - } - ih = ih.next; - ch = ch.next; - } - - return il; - } - - /** Replace all references to the old constant pool with references to the new - * constant pool - */ - public void replaceConstantPool(ConstantPoolGen old_cp, ConstantPoolGen new_cp) { - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - - if(i instanceof CPInstruction) { - CPInstruction ci = (CPInstruction)i; - Constant c = old_cp.getConstant(ci.getIndex()); - ci.setIndex(new_cp.addConstant(c, old_cp)); - } - } - } - - private void clear() { - start = end = null; - length = 0; - } - - /** - * Delete contents of list. Provides besser memory utilization, - * because the system then may reuse the instruction handles. This - * method is typically called right after - * MethodGen.getMethod(). - */ - public void dispose() { - // Traverse in reverse order, because ih.next is overwritten - for(InstructionHandle ih=end; ih != null; ih = ih.prev) - /* Causes BranchInstructions to release target and targeters, because it - * calls dispose() on the contained instruction. - */ - ih.dispose(); - - clear(); - } - - /** - * @return start of list - */ - public InstructionHandle getStart() { return start; } - - /** - * @return end of list - */ - public InstructionHandle getEnd() { return end; } - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int getLength() { return length; } - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int size() { return length; } - - /** - * Redirect all references from old_target to new_target, i.e., update targets - * of branch instructions. - * - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - */ - public void redirectBranches(InstructionHandle old_target, - InstructionHandle new_target) { - for(InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.getInstruction(); - - if(i instanceof BranchInstruction) { - BranchInstruction b = (BranchInstruction)i; - InstructionHandle target = b.getTarget(); - - if(target == old_target) - b.setTarget(new_target); - - if(b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionHandle[] targets = ((Select)b).getTargets(); - - for(int j=0; j < targets.length; j++) // Update targets - if(targets[j] == old_target) - ((Select)b).setTarget(j, new_target); + /* Pass 2: Expand the variable-length (Branch)Instructions depending on + * the target offset (short or int) and ensure that branch targets are + * within this list. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes); + } + /* + * Pass 3: Update position numbers (which may have changed due to the + * preceding expansions), like pass 1. + */ + index = count = 0; + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + + ih.setPosition(index); + pos[count++] = index; + index += i.getLength(); + } + if (length == count) { + byte_positions = pos; + } else { + byte_positions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, byte_positions, 0, count); } - } } - } - /** - * Redirect all references of local variables from old_target to new_target. - * - * @param lg array of local variables - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - * @see MethodGen - */ - public void redirectLocalVariables(LocalVariableGen[] lg, - InstructionHandle old_target, - InstructionHandle new_target) { - for(int i=0; i < lg.length; i++) { - InstructionHandle start = lg[i].getStart(); - InstructionHandle end = lg[i].getEnd(); - - if(start == old_target) - lg[i].setStart(new_target); - - if(end == old_target) - lg[i].setEnd(new_target); + /** + * When everything is finished, use this method to convert the instruction + * list into an array of bytes. + * + * @return the byte code ready to be dumped + */ + public byte[] getByteCode() { + // Update position indices of instructions + setPositions(); + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + final DataOutputStream out = new DataOutputStream(b); + try { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + i.dump(out); // Traverse list + } + out.flush(); + } catch (final IOException e) { + System.err.println(e); + return new byte[0]; + } + return b.toByteArray(); } - } - /** - * Redirect all references of exception handlers from old_target to new_target. - * - * @param exceptions array of exception handlers - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - * @see MethodGen - */ - public void redirectExceptionHandlers(CodeExceptionGen[] exceptions, - InstructionHandle old_target, - InstructionHandle new_target) { - for(int i=0; i < exceptions.length; i++) { - if(exceptions[i].getStartPC() == old_target) - exceptions[i].setStartPC(new_target); - - if(exceptions[i].getEndPC() == old_target) - exceptions[i].setEndPC(new_target); - - if(exceptions[i].getHandlerPC() == old_target) - exceptions[i].setHandlerPC(new_target); + /** + * @return an array of instructions without target information for branch + * instructions. + */ + public Instruction[] getInstructions() { + final List instructions = new ArrayList<>(); + try (ByteSequence bytes = new ByteSequence(getByteCode())) { + while (bytes.available() > 0) { + instructions.add(Instruction.readInstruction(bytes)); + } + } catch (final IOException e) { + throw new ClassGenException(e.toString(), e); + } + return instructions.toArray(new Instruction[instructions.size()]); } - } - private ArrayList observers; + @Override + public String toString() { + return toString(true); + } - /** Add observer for this object. - */ - public void addObserver(InstructionListObserver o) { - if(observers == null) - observers = new ArrayList(); + /** + * @param verbose toggle output format + * @return String containing all instructions in this list. + */ + public String toString(final boolean verbose) { + final StringBuilder buf = new StringBuilder(); + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + buf.append(ih.toString(verbose)).append("\n"); + } + return buf.toString(); + } - observers.add(o); - } + /** + * @return iterator that lists all instructions (handles) + */ + @Override + public Iterator iterator() { + return new Iterator() { - /** Remove observer for this object. - */ - public void removeObserver(InstructionListObserver o) { - if(observers != null) - observers.remove(o); - } + private InstructionHandle ih = start; - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if(observers != null) - for(Iterator e = observers.iterator(); e.hasNext(); ) - ((InstructionListObserver)e.next()).notify(this); - } + @Override + public InstructionHandle next() throws NoSuchElementException { + if (ih == null) { + throw new NoSuchElementException(); + } + final InstructionHandle i = ih; + ih = ih.getNext(); + return i; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasNext() { + return ih != null; + } + }; + } + + /** + * @return array containing all instructions (handles) + */ + public InstructionHandle[] getInstructionHandles() { + final InstructionHandle[] ihs = new InstructionHandle[length]; + InstructionHandle ih = start; + for (int i = 0; i < length; i++) { + ihs[i] = ih; + ih = ih.getNext(); + } + return ihs; + } + + /** + * Get positions (offsets) of all instructions in the list. This relies on + * that the list has been freshly created from an byte code array, or that + * setPositions() has been called. Otherwise this may be inaccurate. + * + * @return array containing all instruction's offset in byte code + */ + public int[] getInstructionPositions() { + return byte_positions; + } + + /** + * @return complete, i.e., deep copy of this list + */ + public InstructionList copy() { + final Map map = new HashMap<>(); + final InstructionList il = new InstructionList(); + /* + * Pass 1: Make copies of all instructions, append them to the new list and associate old instruction references with the new ones, i.e., a 1:1 mapping. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + final Instruction c = i.copy(); // Use clone for shallow copy + if (c instanceof BranchInstruction) { + map.put(ih, il.append((BranchInstruction) c)); + } else { + map.put(ih, il.append(c)); + } + } + /* + * Pass 2: Update branch targets. + */ + InstructionHandle ih = start; + InstructionHandle ch = il.start; + while (ih != null) { + final Instruction i = ih.getInstruction(); + final Instruction c = ch.getInstruction(); + if (i instanceof BranchInstruction) { + final BranchInstruction bi = (BranchInstruction) i; + final BranchInstruction bc = (BranchInstruction) c; + final InstructionHandle itarget = bi.getTarget(); // old target + // New target is in hash map + bc.setTarget(map.get(itarget)); + if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + final InstructionHandle[] itargets = ((Select) bi).getTargets(); + final InstructionHandle[] ctargets = ((Select) bc).getTargets(); + for (int j = 0; j < itargets.length; j++) { // Update all targets + ctargets[j] = map.get(itargets[j]); + } + } + } + ih = ih.getNext(); + ch = ch.getNext(); + } + return il; + } + + /** + * Replace all references to the old constant pool with references to the + * new constant pool + */ + public void replaceConstantPool(final ConstantPoolGen old_cp, final ConstantPoolGen new_cp) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof CPInstruction) { + final CPInstruction ci = (CPInstruction) i; + final Constant c = old_cp.getConstant(ci.getIndex()); + ci.setIndex(new_cp.addConstant(c, old_cp)); + } + } + } + + private void clear() { + start = end = null; + length = 0; + } + + /** + * Delete contents of list. Provides better memory utilization, because the + * system then may reuse the instruction handles. This method is typically + * called right after {@link MethodGen#getMethod()}. + */ + public void dispose() { + // Traverse in reverse order, because ih.next is overwritten + for (InstructionHandle ih = end; ih != null; ih = ih.getPrev()) { + /* + * Causes BranchInstructions to release target and targeters, + * because it calls dispose() on the contained instruction. + */ + ih.dispose(); + } + clear(); + } + + /** + * @return start of list + */ + public InstructionHandle getStart() { + return start; + } + + /** + * @return end of list + */ + public InstructionHandle getEnd() { + return end; + } + + /** + * @return length of list (Number of instructions, not bytes) + */ + public int getLength() { + return length; + } + + /** + * @return length of list (Number of instructions, not bytes) + */ + public int size() { + return length; + } + + /** + * Redirect all references from old_target to new_target, i.e., update + * targets of branch instructions. + * + * @param old_target the old target instruction handle + * @param new_target the new target instruction handle + */ + public void redirectBranches(final InstructionHandle old_target, + final InstructionHandle new_target) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { + final BranchInstruction b = (BranchInstruction) i; + final InstructionHandle target = b.getTarget(); + if (target == old_target) { + b.setTarget(new_target); + } + if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + final InstructionHandle[] targets = ((Select) b).getTargets(); + for (int j = 0; j < targets.length; j++) { + if (targets[j] == old_target) { + ((Select) b).setTarget(j, new_target); + } + } + } + } + } + } + + /** + * Redirect all references of local variables from old_target to new_target. + * + * @param lg array of local variables + * @param old_target the old target instruction handle + * @param new_target the new target instruction handle + * @see MethodGen + */ + public void redirectLocalVariables(final LocalVariableGen[] lg, + final InstructionHandle old_target, final InstructionHandle new_target) { + for (final LocalVariableGen element : lg) { + final InstructionHandle start = element.getStart(); + final InstructionHandle end = element.getEnd(); + if (start == old_target) { + element.setStart(new_target); + } + if (end == old_target) { + element.setEnd(new_target); + } + } + } + + /** + * Redirect all references of exception handlers from old_target to + * new_target. + * + * @param exceptions array of exception handlers + * @param old_target the old target instruction handle + * @param new_target the new target instruction handle + * @see MethodGen + */ + public void redirectExceptionHandlers(final CodeExceptionGen[] exceptions, + final InstructionHandle old_target, final InstructionHandle new_target) { + for (final CodeExceptionGen exception : exceptions) { + if (exception.getStartPC() == old_target) { + exception.setStartPC(new_target); + } + if (exception.getEndPC() == old_target) { + exception.setEndPC(new_target); + } + if (exception.getHandlerPC() == old_target) { + exception.setHandlerPC(new_target); + } + } + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(final InstructionListObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(final InstructionListObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (final InstructionListObserver observer : observers) { + observer.notify(this); + } + } + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java index e9721ed6c42..3038ba5a8d5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Implement this interface if you're interested in changes to an InstructionList object * and register yourself with addObserver(). * - * @author M. Dahm + * @version $Id: InstructionListObserver.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface InstructionListObserver { - public void notify(InstructionList list); + + void notify( InstructionList list ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java index 1d8d25a6a68..6ff6aef3cab 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java @@ -21,7 +21,6 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote that a class targets InstructionHandles within an InstructionList. Namely * the following implementers: @@ -29,9 +28,21 @@ package com.sun.org.apache.bcel.internal.generic; * @see BranchHandle * @see LocalVariableGen * @see CodeExceptionGen - * @author M. Dahm + * @version $Id: InstructionTargeter.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface InstructionTargeter { - public boolean containsTarget(InstructionHandle ih); - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih); + + /** + * Checks whether this targeter targets the specified instruction handle. + */ + boolean containsTarget(InstructionHandle ih); + + /** + * Replaces the target of this targeter from this old handle to the new handle. + * + * @param old_ih the old handle + * @param new_ih the new handle + * @throws ClassGenException if old_ih is not targeted by this object + */ + void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) throws ClassGenException; } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java index 592d11d6ecc..57fc9204d51 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java @@ -21,93 +21,124 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.StringTokenizer; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantCP; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; + /** * Super class for the INVOKExxx family of instructions. * - * @author M. Dahm + * @version $Id: InvokeInstruction.java 1752106 2016-07-10 20:02:39Z britter $ */ -public abstract class InvokeInstruction extends FieldOrMethod - implements ExceptionThrower, TypedInstruction, StackConsumer, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - InvokeInstruction() {} +public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower, + StackConsumer, StackProducer { - /** - * @param index to constant pool - */ - protected InvokeInstruction(short opcode, int index) { - super(opcode, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + InvokeInstruction() { + } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - Constant c = cp.getConstant(index); - StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); - return Constants.OPCODE_NAMES[opcode] + " " + - tok.nextToken().replace('.', '/') + tok.nextToken(); - } + /** + * @param index to constant pool + */ + protected InvokeInstruction(final short opcode, final int index) { + super(opcode, index); + } - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words consumed from stack by this instruction - */ - public int consumeStack(ConstantPoolGen cpg) { - String signature = getSignature(cpg); - Type[] args = Type.getArgumentTypes(signature); - int sum; - if(opcode == Constants.INVOKESTATIC) - sum = 0; - else - sum = 1; // this reference + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + final Constant c = cp.getConstant(super.getIndex()); + final StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); + return Const.getOpcodeName(super.getOpcode()) + " " + tok.nextToken().replace('.', '/') + + tok.nextToken(); + } - int n = args.length; - for (int i = 0; i < n; i++) - sum += args[i].getSize(); - return sum; - } + /** + * Also works for instructions whose stack effect depends on the + * constant pool entry they reference. + * @return Number of words consumed from stack by this instruction + */ + @Override + public int consumeStack( final ConstantPoolGen cpg ) { + int sum; + if ((super.getOpcode() == Const.INVOKESTATIC) || (super.getOpcode() == Const.INVOKEDYNAMIC)) { + sum = 0; + } else { + sum = 1; // this reference + } - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words produced onto stack by this instruction - */ - public int produceStack(ConstantPoolGen cpg) { - return getReturnType(cpg).getSize(); - } + final String signature = getSignature(cpg); + sum += Type.getArgumentTypesSize(signature); + return sum; + } - /** @return return type of referenced method. - */ - public Type getType(ConstantPoolGen cpg) { - return getReturnType(cpg); - } - /** @return name of referenced method. - */ - public String getMethodName(ConstantPoolGen cpg) { - return getName(cpg); - } + /** + * Also works for instructions whose stack effect depends on the + * constant pool entry they reference. + * @return Number of words produced onto stack by this instruction + */ + @Override + public int produceStack( final ConstantPoolGen cpg ) { + final String signature = getSignature(cpg); + return Type.getReturnTypeSize(signature); + } - /** @return return type of referenced method. - */ - public Type getReturnType(ConstantPoolGen cpg) { - return Type.getReturnType(getSignature(cpg)); - } + /** + * This overrides the deprecated version as we know here that the referenced class + * may legally be an array. + * + * @deprecated in FieldOrMethod + * + * @return name of the referenced class/interface + * @throws IllegalArgumentException if the referenced class is an array (this should not happen) + */ + @Override + @Deprecated + public String getClassName( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class); + return className.replace('/', '.'); + } + + /** @return return type of referenced method. + */ + @Override + public Type getType( final ConstantPoolGen cpg ) { + return getReturnType(cpg); + } + + + /** @return name of referenced method. + */ + public String getMethodName( final ConstantPoolGen cpg ) { + return getName(cpg); + } + + + /** @return return type of referenced method. + */ + public Type getReturnType( final ConstantPoolGen cpg ) { + return Type.getReturnType(getSignature(cpg)); + } + + + /** @return argument types of referenced method. + */ + public Type[] getArgumentTypes( final ConstantPoolGen cpg ) { + return Type.getArgumentTypes(getSignature(cpg)); + } - /** @return argument types of referenced method. - */ - public Type[] getArgumentTypes(ConstantPoolGen cpg) { - return Type.getArgumentTypes(getSignature(cpg)); - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java index babfc422dba..fa32244b4b1 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java @@ -21,66 +21,74 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; /** * JSR - Jump to subroutine * - * @author M. Dahm + * @version $Id: JSR.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class JSR extends JsrInstruction implements VariableLengthInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JSR() {} - public JSR(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.JSR, target); - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - index = getTargetOffset(); - if(opcode == com.sun.org.apache.bcel.internal.Constants.JSR) - super.dump(out); - else { // JSR_W - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - } - - protected int updatePosition(int offset, int max_offset) { - int i = getTargetOffset(); // Depending on old position value - - position += offset; // Position may be shifted by preceding expansions - - if(Math.abs(i) >= (32767 - max_offset)) { // to large for short (estimate) - opcode = com.sun.org.apache.bcel.internal.Constants.JSR_W; - length = 5; - return 2; // 5 - 3 + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JSR() { } - return 0; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitVariableLengthInstruction(this); - v.visitBranchInstruction(this); - v.visitJsrInstruction(this); - v.visitJSR(this); - } + public JSR(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.JSR, target); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.setIndex(getTargetOffset()); + if (super.getOpcode() == com.sun.org.apache.bcel.internal.Const.JSR) { + super.dump(out); + } else { // JSR_W + super.setIndex(getTargetOffset()); + out.writeByte(super.getOpcode()); + out.writeInt(super.getIndex()); + } + } + + + @Override + protected int updatePosition( final int offset, final int max_offset ) { + final int i = getTargetOffset(); // Depending on old position value + setPosition(getPosition() + offset); // Position may be shifted by preceding expansions + if (Math.abs(i) >= (Short.MAX_VALUE - max_offset)) { // to large for short (estimate) + super.setOpcode(com.sun.org.apache.bcel.internal.Const.JSR_W); + final short old_length = (short) super.getLength(); + super.setLength(5); + return super.getLength() - old_length; + } + return 0; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitVariableLengthInstruction(this); + v.visitBranchInstruction(this); + v.visitJsrInstruction(this); + v.visitJSR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java index 2776c513e5f..69fd91afaf2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java @@ -21,57 +21,67 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * JSR_W - Jump to subroutine * - * @author M. Dahm + * @version $Id: JSR_W.java 1747278 2016-06-07 17:28:43Z britter $ */ public class JSR_W extends JsrInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JSR_W() {} - public JSR_W(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.JSR_W, target); - length = 5; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JSR_W() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - index = bytes.readInt(); - length = 5; - } + public JSR_W(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.JSR_W, target); + super.setLength(5); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitJsrInstruction(this); - v.visitJSR_W(this); - } + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.setIndex(getTargetOffset()); + out.writeByte(super.getOpcode()); + out.writeInt(super.getIndex()); + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.setIndex(bytes.readInt()); + super.setLength(5); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitBranchInstruction(this); + v.visitJsrInstruction(this); + v.visitJSR_W(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java index a67702e7aa0..39228c4afeb 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java @@ -21,62 +21,64 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Super class for JSR - Jump to subroutine * - * @author M. Dahm + * @version $Id: JsrInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public abstract class JsrInstruction extends BranchInstruction - implements UnconditionalBranch, TypedInstruction, StackProducer -{ - JsrInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } +public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch, + TypedInstruction, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JsrInstruction(){} - - /** @return return address type - */ - public Type getType(ConstantPoolGen cp) { - return new ReturnaddressType(physicalSuccessor()); - } - - /** - * Returns an InstructionHandle to the physical successor - * of this JsrInstruction. For this method to work, - * this JsrInstruction object must not be shared between - * multiple InstructionHandle objects! - * Formally, there must not be InstructionHandle objects - * i, j where i != j and i.getInstruction() == this == - * j.getInstruction(). - * @return an InstructionHandle to the "next" instruction that - * will be executed when RETurned from a subroutine. - */ - public InstructionHandle physicalSuccessor(){ - InstructionHandle ih = this.target; - - // Rewind! - while(ih.getPrev() != null) - ih = ih.getPrev(); - - // Find the handle for "this" JsrInstruction object. - while(ih.getInstruction() != this) - ih = ih.getNext(); - - InstructionHandle toThis = ih; - - while(ih != null){ - ih = ih.getNext(); - if ((ih != null) && (ih.getInstruction() == this)) - throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction."); + JsrInstruction(final short opcode, final InstructionHandle target) { + super(opcode, target); } - // Return the physical successor - return toThis.getNext(); - } + + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JsrInstruction() { + } + + + /** @return return address type + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return new ReturnaddressType(physicalSuccessor()); + } + + + /** + * Returns an InstructionHandle to the physical successor + * of this JsrInstruction. For this method to work, + * this JsrInstruction object must not be shared between + * multiple InstructionHandle objects! + * Formally, there must not be InstructionHandle objects + * i, j where i != j and i.getInstruction() == this == + * j.getInstruction(). + * @return an InstructionHandle to the "next" instruction that + * will be executed when RETurned from a subroutine. + */ + public InstructionHandle physicalSuccessor() { + InstructionHandle ih = super.getTarget(); + // Rewind! + while (ih.getPrev() != null) { + ih = ih.getPrev(); + } + // Find the handle for "this" JsrInstruction object. + while (ih.getInstruction() != this) { + ih = ih.getNext(); + } + final InstructionHandle toThis = ih; + while (ih != null) { + ih = ih.getNext(); + if ((ih != null) && (ih.getInstruction() == this)) { + throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction."); + } + } + // Return the physical successor + return toThis.getNext(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java index fb0926faa9f..93894dc7741 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * L2D - Convert long to double *
    Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: L2D.java 1747278 2016-06-07 17:28:43Z britter $ */ public class L2D extends ConversionInstruction { - public L2D() { - super(com.sun.org.apache.bcel.internal.Constants.L2D); - } + + public L2D() { + super(com.sun.org.apache.bcel.internal.Const.L2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2D(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2D(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java index afc5b0016b5..0ce9f52285d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * L2F - Convert long to float *
    Stack: ..., value.word1, value.word2 -> ..., result
    * - * @author M. Dahm + * @version $Id: L2F.java 1747278 2016-06-07 17:28:43Z britter $ */ public class L2F extends ConversionInstruction { - public L2F() { - super(com.sun.org.apache.bcel.internal.Constants.L2F); - } + + public L2F() { + super(com.sun.org.apache.bcel.internal.Const.L2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2F(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2F(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java index be9615f20dd..a1bc7cc2397 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * L2I - Convert long to int *
    Stack: ..., value.word1, value.word2 -> ..., result
    * - * @author M. Dahm + * @version $Id: L2I.java 1747278 2016-06-07 17:28:43Z britter $ */ public class L2I extends ConversionInstruction { - public L2I() { - super(com.sun.org.apache.bcel.internal.Constants.L2I); - } + + public L2I() { + super(com.sun.org.apache.bcel.internal.Const.L2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2I(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2I(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java index 999c39c77f8..e3176d3eac3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LADD - Add longs *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LADD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LADD extends ArithmeticInstruction { - public LADD() { - super(com.sun.org.apache.bcel.internal.Constants.LADD); - } + + public LADD() { + super(com.sun.org.apache.bcel.internal.Const.LADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLADD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLADD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java index 7068be8f28e..0c7750506bd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LALOAD - Load long from array *
    Stack: ..., arrayref, index -> ..., value1, value2
    * - * @author M. Dahm + * @version $Id: LALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LALOAD extends ArrayInstruction implements StackProducer { - /** Load long from array - */ - public LALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.LALOAD); - } + + /** Load long from array + */ + public LALOAD() { + super(com.sun.org.apache.bcel.internal.Const.LALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitLALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitLALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java index a5fa96c1b17..62af531f524 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LAND - Bitwise AND longs *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LAND.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LAND extends ArithmeticInstruction { - public LAND() { - super(com.sun.org.apache.bcel.internal.Constants.LAND); - } + + public LAND() { + super(com.sun.org.apache.bcel.internal.Const.LAND); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLAND(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLAND(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java index 04d25d20181..cbb9a992c71 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LASTORE - Store into long array *
    Stack: ..., arrayref, index, value.word1, value.word2 -> ...
    * - * @author M. Dahm + * @version $Id: LASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LASTORE extends ArrayInstruction implements StackConsumer { - /** Store long into array - */ - public LASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.LASTORE); - } + + /** Store long into array + */ + public LASTORE() { + super(com.sun.org.apache.bcel.internal.Const.LASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitLASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitLASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java index cb2fb4f8404..b46ed10f4dd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java @@ -21,39 +21,41 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LCMP - Compare longs: - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result <= -1, 0, 1> + *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result <= -1, 0, 1>
    * - * @author M. Dahm + * + * @version $Id: LCMP.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class LCMP extends Instruction - implements TypedInstruction, StackProducer, StackConsumer -{ - public LCMP() { - super(com.sun.org.apache.bcel.internal.Constants.LCMP, (short)1); - } +public class LCMP extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - /** @return Type.LONG - */ - public Type getType(ConstantPoolGen cp) { - return Type.LONG; - } + public LCMP() { + super(com.sun.org.apache.bcel.internal.Const.LCMP, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitLCMP(this); - } + + /** @return Type.LONG + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.LONG; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitLCMP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java index dcc2383877c..3c278c40c70 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java @@ -20,58 +20,67 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LCONST - Push 0 or 1, other values cause an exception * *
    Stack: ... -> ..., 
    * - * @author M. Dahm + * @version $Id: LCONST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class LCONST extends Instruction - implements ConstantPushInstruction, TypedInstruction { - private long value; +public class LCONST extends Instruction implements ConstantPushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LCONST() {} + private long value; - public LCONST(long l) { - super(com.sun.org.apache.bcel.internal.Constants.LCONST_0, (short)1); - if(l == 0) - opcode = com.sun.org.apache.bcel.internal.Constants.LCONST_0; - else if(l == 1) - opcode = com.sun.org.apache.bcel.internal.Constants.LCONST_1; - else - throw new ClassGenException("LCONST can be used only for 0 and 1: " + l); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LCONST() { + } - value = l; - } - public Number getValue() { return Long.valueOf(value); } + public LCONST(final long l) { + super(com.sun.org.apache.bcel.internal.Const.LCONST_0, (short) 1); + if (l == 0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LCONST_0); + } else if (l == 1) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LCONST_1); + } else { + throw new ClassGenException("LCONST can be used only for 0 and 1: " + l); + } + value = l; + } - /** @return Type.LONG - */ - public Type getType(ConstantPoolGen cp) { - return Type.LONG; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitLCONST(this); - } + @Override + public Number getValue() { + return Long.valueOf(value); + } + + + /** @return Type.LONG + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.LONG; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitLCONST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java index 80899e77d95..3803fe85fb2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java @@ -20,7 +20,10 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.ExceptionConst; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -28,111 +31,130 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; * *
    Stack: ... -> ..., item
    * - * @author M. Dahm + * @version $Id: LDC.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public class LDC extends CPInstruction - implements PushInstruction, ExceptionThrower, TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC() {} +public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower { - public LDC(int index) { - super(com.sun.org.apache.bcel.internal.Constants.LDC_W, index); - setSize(); - } - - // Adjust to proper size - protected final void setSize() { - if(index <= com.sun.org.apache.bcel.internal.Constants.MAX_BYTE) { // Fits in one byte? - opcode = com.sun.org.apache.bcel.internal.Constants.LDC; - length = 2; - } else { - opcode = com.sun.org.apache.bcel.internal.Constants.LDC_W; - length = 3; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC() { } - } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - if(length == 2) - out.writeByte(index); - else // Applies for LDC_W - out.writeShort(index); - } - - /** - * Set the index to constant pool and adjust size. - */ - public final void setIndex(int index) { - super.setIndex(index); - setSize(); - } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - length = 2; - index = bytes.readUnsignedByte(); - } - - public Object getValue(ConstantPoolGen cpg) { - com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(index); - - switch(c.getTag()) { - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_String: - int i = ((com.sun.org.apache.bcel.internal.classfile.ConstantString)c).getStringIndex(); - c = cpg.getConstantPool().getConstant(i); - return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8)c).getBytes(); - - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Float: - return Float.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantFloat)c).getBytes()); - - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Integer: - return Integer.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantInteger)c).getBytes()); - - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } - - public Type getType(ConstantPoolGen cpg) { - switch(cpg.getConstantPool().getConstant(index).getTag()) { - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_String: return Type.STRING; - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Float: return Type.FLOAT; - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Integer: return Type.INT; - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); + public LDC(final int index) { + super(com.sun.org.apache.bcel.internal.Const.LDC_W, index); + setSize(); } - } - public Class[] getExceptions() { - return com.sun.org.apache.bcel.internal.ExceptionConstants.EXCS_STRING_RESOLUTION; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitLDC(this); - } + // Adjust to proper size + protected final void setSize() { + if (super.getIndex() <= com.sun.org.apache.bcel.internal.Const.MAX_BYTE) { // Fits in one byte? + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC); + super.setLength(2); + } else { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC_W); + super.setLength(3); + } + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + if (super.getLength() == 2) { // TODO useless check? + out.writeByte(super.getIndex()); + } else { + out.writeShort(super.getIndex()); + } + } + + + /** + * Set the index to constant pool and adjust size. + */ + @Override + public final void setIndex( final int index ) { + super.setIndex(index); + setSize(); + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.setLength(2); + super.setIndex(bytes.readUnsignedByte()); + } + + + public Object getValue( final ConstantPoolGen cpg ) { + com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex()); + switch (c.getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_String: + final int i = ((com.sun.org.apache.bcel.internal.classfile.ConstantString) c).getStringIndex(); + c = cpg.getConstantPool().getConstant(i); + return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes(); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: + return new Float(((com.sun.org.apache.bcel.internal.classfile.ConstantFloat) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: + return Integer.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantInteger) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: + final int nameIndex = ((com.sun.org.apache.bcel.internal.classfile.ConstantClass) c).getNameIndex(); + c = cpg.getConstantPool().getConstant(nameIndex); + return new ObjectType(((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes()); + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + } + } + + + @Override + public Type getType( final ConstantPoolGen cpg ) { + switch (cpg.getConstantPool().getConstant(super.getIndex()).getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_String: + return Type.STRING; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: + return Type.FLOAT; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: + return Type.INT; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: + return Type.CLASS; + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + } + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_STRING_RESOLUTION); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitLDC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java index 2279676c61a..561176c0d81 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java @@ -20,63 +20,68 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LDC2_W - Push long or double from constant pool * *
    Stack: ... -> ..., item.word1, item.word2
    * - * @author M. Dahm + * @version $Id: LDC2_W.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public class LDC2_W extends CPInstruction - implements PushInstruction, TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC2_W() {} +public class LDC2_W extends CPInstruction implements PushInstruction { - public LDC2_W(int index) { - super(com.sun.org.apache.bcel.internal.Constants.LDC2_W, index); - } - - public Type getType(ConstantPoolGen cpg) { - switch(cpg.getConstantPool().getConstant(index).getTag()) { - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Long: return Type.LONG; - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Double: return Type.DOUBLE; - default: // Never reached - throw new RuntimeException("Unknown constant type " + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC2_W() { } - } - public Number getValue(ConstantPoolGen cpg) { - com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(index); - switch(c.getTag()) { - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Long: - return Long.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantLong)c).getBytes()); + public LDC2_W(final int index) { + super(com.sun.org.apache.bcel.internal.Const.LDC2_W, index); + } - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Double: - return Double.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantDouble)c).getBytes()); - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } + @Override + public Type getType( final ConstantPoolGen cpg ) { + switch (cpg.getConstantPool().getConstant(super.getIndex()).getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: + return Type.LONG; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: + return Type.DOUBLE; + default: // Never reached + throw new RuntimeException("Unknown constant type " + super.getOpcode()); + } + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitLDC2_W(this); - } + + public Number getValue( final ConstantPoolGen cpg ) { + final com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex()); + switch (c.getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: + return Long.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantLong) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: + return new Double(((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes()); + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + } + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitLDC2_W(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java index be3f5693f0e..9651aaa09b4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java @@ -22,6 +22,7 @@ package com.sun.org.apache.bcel.internal.generic; import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -29,27 +30,31 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; * *
    Stack: ... -> ..., item.word1, item.word2
    * - * @author M. Dahm + * @version $Id: LDC_W.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LDC_W extends LDC { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC_W() {} - public LDC_W(int index) { - super(index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC_W() { + } - /** - * Read needed data (i.e., index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - setIndex(bytes.readUnsignedShort()); - // Override just in case it has been changed - opcode = com.sun.org.apache.bcel.internal.Constants.LDC_W; - } + + public LDC_W(final int index) { + super(index); + } + + + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + setIndex(bytes.readUnsignedShort()); + // Override just in case it has been changed + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC_W); + super.setLength(3); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java index 55f82cab10e..f3d104e8872 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java @@ -21,38 +21,45 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * LDIV - Divide longs *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LDIV.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class LDIV extends ArithmeticInstruction implements ExceptionThrower { - public LDIV() { - super(com.sun.org.apache.bcel.internal.Constants.LDIV); - } +public class LDIV extends ArithmeticInstruction implements ExceptionThrower { - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.ARITHMETIC_EXCEPTION }; - } + public LDIV() { + super(com.sun.org.apache.bcel.internal.Const.LDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLDIV(this); - } + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ARITHMETIC_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLDIV(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java index b36e57549e2..0e5deec7dfa 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java @@ -21,36 +21,39 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LLOAD - Load long from local variable - *
    Stack ... -> ..., result.word1, result.word2
    + *
    Stack ... -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: LLOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LLOAD() { - super(com.sun.org.apache.bcel.internal.Constants.LLOAD, com.sun.org.apache.bcel.internal.Constants.LLOAD_0); - } - public LLOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.LLOAD, com.sun.org.apache.bcel.internal.Constants.LLOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LLOAD() { + super(com.sun.org.apache.bcel.internal.Const.LLOAD, com.sun.org.apache.bcel.internal.Const.LLOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitLLOAD(this); - } + + public LLOAD(final int n) { + super(com.sun.org.apache.bcel.internal.Const.LLOAD, com.sun.org.apache.bcel.internal.Const.LLOAD_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitLLOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java index aa746fb623a..3290f093592 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LMUL - Multiply longs *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LMUL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LMUL extends ArithmeticInstruction { - public LMUL() { - super(com.sun.org.apache.bcel.internal.Constants.LMUL); - } + + public LMUL() { + super(com.sun.org.apache.bcel.internal.Const.LMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLMUL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java index b08f303bf55..698b52c486d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LNEG - Negate long *
    Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: LNEG.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LNEG extends ArithmeticInstruction { - public LNEG() { - super(com.sun.org.apache.bcel.internal.Constants.LNEG); - } + + public LNEG() { + super(com.sun.org.apache.bcel.internal.Const.LNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLNEG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java index 1b026df5289..b403ddebb54 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java @@ -21,80 +21,89 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * LOOKUPSWITCH - Switch with unordered set of values * - * @author M. Dahm + * @version $Id: LOOKUPSWITCH.java 1747278 2016-06-07 17:28:43Z britter $ * @see SWITCH */ public class LOOKUPSWITCH extends Select { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LOOKUPSWITCH() {} - public LOOKUPSWITCH(int[] match, InstructionHandle[] targets, - InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.LOOKUPSWITCH, match, targets, target); - - length = (short)(9 + match_length * 8); /* alignment remainder assumed - * 0 here, until dump time. */ - fixed_length = length; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - out.writeInt(match_length); // npairs - - for(int i=0; i < match_length; i++) { - out.writeInt(match[i]); // match-offset pairs - out.writeInt(indices[i] = getTargetOffset(targets[i])); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LOOKUPSWITCH() { } - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - super.initFromFile(bytes, wide); // reads padding - match_length = bytes.readInt(); - fixed_length = (short)(9 + match_length * 8); - length = (short)(fixed_length + padding); - - match = new int[match_length]; - indices = new int[match_length]; - targets = new InstructionHandle[match_length]; - - for(int i=0; i < match_length; i++) { - match[i] = bytes.readInt(); - indices[i] = bytes.readInt(); + public LOOKUPSWITCH(final int[] match, final InstructionHandle[] targets, + final InstructionHandle defaultTarget) { + super(com.sun.org.apache.bcel.internal.Const.LOOKUPSWITCH, match, targets, defaultTarget); + /* alignment remainder assumed 0 here, until dump time. */ + final short _length = (short) (9 + getMatch_length() * 8); + super.setLength(_length); + setFixed_length(_length); } - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitVariableLengthInstruction(this); - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitSelect(this); - v.visitLOOKUPSWITCH(this); - } + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.dump(out); + final int _match_length = getMatch_length(); + out.writeInt(_match_length); // npairs + for (int i = 0; i < _match_length; i++) { + out.writeInt(super.getMatch(i)); // match-offset pairs + out.writeInt(setIndices(i, getTargetOffset(super.getTarget(i)))); + } + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); // reads padding + final int _match_length = bytes.readInt(); + setMatch_length(_match_length); + final short _fixed_length = (short) (9 + _match_length * 8); + setFixed_length(_fixed_length); + final short _length = (short) (_match_length + super.getPadding()); + super.setLength(_length); + super.setMatches(new int[_match_length]); + super.setIndices(new int[_match_length]); + super.setTargets(new InstructionHandle[_match_length]); + for (int i = 0; i < _match_length; i++) { + super.setMatch(i, bytes.readInt()); + super.setIndices(i, bytes.readInt()); + } + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitVariableLengthInstruction(this); + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitSelect(this); + v.visitLOOKUPSWITCH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java index 19a25deaf8c..e5dbf97a80e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LOR - Bitwise OR long *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: LOR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LOR extends ArithmeticInstruction { - public LOR() { - super(com.sun.org.apache.bcel.internal.Constants.LOR); - } + + public LOR() { + super(com.sun.org.apache.bcel.internal.Const.LOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLOR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLOR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java index 7f2892d25e7..4f485c1cf73 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java @@ -21,35 +21,44 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * LREM - Remainder of long *
    Stack: ..., value1, value2 -> result
    * - * @author M. Dahm + * @version $Id: LREM.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LREM extends ArithmeticInstruction implements ExceptionThrower { - public LREM() { - super(com.sun.org.apache.bcel.internal.Constants.LREM); - } - public Class[] getExceptions() { return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.ARITHMETIC_EXCEPTION }; } + public LREM() { + super(com.sun.org.apache.bcel.internal.Const.LREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLREM(this); - } + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ARITHMETIC_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLREM(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java index b09344aee5d..b84c0ca0333 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LRETURN - Return long from method *
    Stack: ..., value.word1, value.word2 -> <empty>
    * - * @author M. Dahm + * @version $Id: LRETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LRETURN extends ReturnInstruction { - public LRETURN() { - super(com.sun.org.apache.bcel.internal.Constants.LRETURN); - } + + public LRETURN() { + super(com.sun.org.apache.bcel.internal.Const.LRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitLRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitLRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java index ae677302842..4eaa5a77dd6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LSHL - Arithmetic shift left long *
    Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: LSHL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LSHL extends ArithmeticInstruction { - public LSHL() { - super(com.sun.org.apache.bcel.internal.Constants.LSHL); - } + + public LSHL() { + super(com.sun.org.apache.bcel.internal.Const.LSHL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSHL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSHL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java index f6a520b2831..d5df3027aa6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LSHR - Arithmetic shift right long *
    Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
    * - * @author M. Dahm + * @version $Id: LSHR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LSHR extends ArithmeticInstruction { - public LSHR() { - super(com.sun.org.apache.bcel.internal.Constants.LSHR); - } + + public LSHR() { + super(com.sun.org.apache.bcel.internal.Const.LSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSHR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java index 3b560d28b03..1919c561c6a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java @@ -21,36 +21,39 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LSTORE - Store long into local variable *
    Stack: ..., value.word1, value.word2 -> ... 
    * - * @author M. Dahm + * @version $Id: LSTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LSTORE() { - super(com.sun.org.apache.bcel.internal.Constants.LSTORE, com.sun.org.apache.bcel.internal.Constants.LSTORE_0); - } - public LSTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.LSTORE, com.sun.org.apache.bcel.internal.Constants.LSTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LSTORE() { + super(com.sun.org.apache.bcel.internal.Const.LSTORE, com.sun.org.apache.bcel.internal.Const.LSTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitLSTORE(this); - } + + public LSTORE(final int n) { + super(com.sun.org.apache.bcel.internal.Const.LSTORE, com.sun.org.apache.bcel.internal.Const.LSTORE_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitLSTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java index 789c47fe143..2f0bcb3aedd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LSUB - Substract longs *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LSUB.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LSUB extends ArithmeticInstruction { - public LSUB() { - super(com.sun.org.apache.bcel.internal.Constants.LSUB); - } + + public LSUB() { + super(com.sun.org.apache.bcel.internal.Const.LSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSUB(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java index 19d83c8f7b7..5852db50e02 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LUSHR - Logical shift right long *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: LUSHR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LUSHR extends ArithmeticInstruction { - public LUSHR() { - super(com.sun.org.apache.bcel.internal.Constants.LUSHR); - } + + public LUSHR() { + super(com.sun.org.apache.bcel.internal.Const.LUSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLUSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLUSHR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java index 56f680125f6..5156d7d319e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LXOR - Bitwise XOR long *
    Stack: ..., value1, value2 -> ..., result
    * - * @author M. Dahm + * @version $Id: LXOR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LXOR extends ArithmeticInstruction { - public LXOR() { - super(com.sun.org.apache.bcel.internal.Constants.LXOR); - } + + public LXOR() { + super(com.sun.org.apache.bcel.internal.Const.LXOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLXOR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLXOR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java index ebda36320c0..e5e6d59875e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java @@ -21,80 +21,96 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.classfile.*; +import com.sun.org.apache.bcel.internal.classfile.LineNumber; /** * This class represents a line number within a method, i.e., give an instruction * a line number corresponding to the source code line. * - * @author M. Dahm + * @version $Id: LineNumberGen.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see LineNumber * @see MethodGen */ -public class LineNumberGen - implements InstructionTargeter, Cloneable, java.io.Serializable -{ - private InstructionHandle ih; - private int src_line; +public class LineNumberGen implements InstructionTargeter, Cloneable { - /** - * Create a line number. - * - * @param ih instruction handle to reference - */ - public LineNumberGen(InstructionHandle ih, int src_line) { - setInstruction(ih); - setSourceLine(src_line); - } + private InstructionHandle ih; + private int src_line; - /** - * @return true, if ih is target of this line number - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - return this.ih == ih; - } - /** - * @param old_ih old target - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - if(old_ih != ih) - throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); - else - setInstruction(new_ih); - } - - /** - * Get LineNumber attribute . - * - * This relies on that the instruction list has already been dumped to byte code or - * or that the `setPositions' methods has been called for the instruction list. - */ - public LineNumber getLineNumber() { - return new LineNumber(ih.getPosition(), src_line); - } - - public final void setInstruction(InstructionHandle ih) { - BranchInstruction.notifyTargetChanging(this.ih, this); - this.ih = ih; - BranchInstruction.notifyTargetChanged(this.ih, this); - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; + /** + * Create a line number. + * + * @param ih instruction handle to reference + */ + public LineNumberGen(final InstructionHandle ih, final int src_line) { + setInstruction(ih); + setSourceLine(src_line); } - } - public InstructionHandle getInstruction() { return ih; } - public void setSourceLine(int src_line) { this.src_line = src_line; } - public int getSourceLine() { return src_line; } + + /** + * @return true, if ih is target of this line number + */ + @Override + public boolean containsTarget( final InstructionHandle ih ) { + return this.ih == ih; + } + + + /** + * @param old_ih old target + * @param new_ih new target + */ + @Override + public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { + if (old_ih != ih) { + throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); + } + setInstruction(new_ih); + } + + + /** + * Get LineNumber attribute . + * + * This relies on that the instruction list has already been dumped to byte code or + * or that the `setPositions' methods has been called for the instruction list. + */ + public LineNumber getLineNumber() { + return new LineNumber(ih.getPosition(), src_line); + } + + + public void setInstruction( final InstructionHandle ih ) { // TODO could be package-protected? + if (ih == null) { + throw new NullPointerException("InstructionHandle may not be null"); + } + BranchInstruction.notifyTarget(this.ih, ih, this); + this.ih = ih; + } + + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + } + + + public InstructionHandle getInstruction() { + return ih; + } + + + public void setSourceLine( final int src_line ) { // TODO could be package-protected? + this.src_line = src_line; + } + + + public int getSourceLine() { + return src_line; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java index 0cf2b23509c..819b24a1cf9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes that an instruction may start the process of loading and resolving * the referenced class in the Virtual Machine. * - * @author M. Dahm + * @version $Id: LoadClass.java 1749597 2016-06-21 20:28:51Z ggregory $ */ public interface LoadClass { - /** - * Returns the ObjectType of the referenced class or interface - * that may be loaded and resolved. - * @return object type that may be loaded or null if a primitive is - * referenced - */ - public ObjectType getLoadClassType(ConstantPoolGen cpg); - /** - * Returns the type associated with this instruction. - * LoadClass instances are always typed, but this type - * does not always refer to the type of the class or interface - * that it possibly forces to load. For example, GETFIELD would - * return the type of the field and not the type of the class - * where the field is defined. - * If no class is forced to be loaded, null is returned. - * An example for this is an ANEWARRAY instruction that creates - * an int[][]. - * @see #getLoadClassType(ConstantPoolGen) - */ - public Type getType(ConstantPoolGen cpg); + /** + * Returns the ObjectType of the referenced class or interface + * that may be loaded and resolved. + * @return object type that may be loaded or null if a primitive is + * referenced + */ + ObjectType getLoadClassType( ConstantPoolGen cpg ); + + + /** + * Returns the type associated with this instruction. + * LoadClass instances are always typed, but this type + * does not always refer to the type of the class or interface + * that it possibly forces to load. For example, GETFIELD would + * return the type of the field and not the type of the class + * where the field is defined. + * If no class is forced to be loaded, null is returned. + * An example for this is an ANEWARRAY instruction that creates + * an int[][]. + * @see #getLoadClassType(ConstantPoolGen) + */ + Type getType( ConstantPoolGen cpg ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java index 6d663263e58..b125d245a09 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java @@ -21,47 +21,48 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an unparameterized instruction to load a value from a local * variable, e.g. ILOAD. * - * @author M. Dahm + * @version $Id: LoadInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class LoadInstruction extends LocalVariableInstruction - implements PushInstruction -{ - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - LoadInstruction(short canon_tag, short c_tag) { - super(canon_tag, c_tag); - } +public abstract class LoadInstruction extends LocalVariableInstruction implements PushInstruction { - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ALOAD_0, e.g. - * @param n local variable index (unsigned short) - */ - protected LoadInstruction(short opcode, short c_tag, int n) { - super(opcode, c_tag, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + * tag and length are defined in readInstruction and initFromFile, respectively. + */ + LoadInstruction(final short canon_tag, final short c_tag) { + super(canon_tag, c_tag); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitLocalVariableInstruction(this); - v.visitLoadInstruction(this); - } + + /** + * @param opcode Instruction opcode + * @param c_tag Instruction number for compact version, ALOAD_0, e.g. + * @param n local variable index (unsigned short) + */ + protected LoadInstruction(final short opcode, final short c_tag, final int n) { + super(opcode, c_tag, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitLocalVariableInstruction(this); + v.visitLoadInstruction(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java index 92ae424b8cc..1e2dcbf3d89 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java @@ -18,237 +18,197 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.util.Objects; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.LocalVariable; /** * This class represents a local variable within a method. It contains its - * scope, name and type. The generated LocalVariable object can be obtained - * with getLocalVariable which needs the instruction list and the constant - * pool as parameters. + * scope, name and type. The generated LocalVariable object can be obtained with + * getLocalVariable which needs the instruction list and the constant pool as + * parameters. * - * @author M. Dahm - * @see LocalVariable - * @see MethodGen + * @version $Id: LocalVariableGen.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see LocalVariable + * @see MethodGen */ -public class LocalVariableGen - implements InstructionTargeter, NamedAndTyped, Cloneable, - java.io.Serializable -{ - private final int index; - private String name; - private Type type; - private InstructionHandle start, end; +public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable { - /** - * Generate a local variable that with index `index'. Note that double and long - * variables need two indexs. Index indices have to be provided by the user. - * - * @param index index of local variable - * @param name its name - * @param type its type - * @param start from where the instruction is valid (null means from the start) - * @param end until where the instruction is valid (null means to the end) - */ - public LocalVariableGen(int index, String name, Type type, - InstructionHandle start, InstructionHandle end) { - if((index < 0) || (index > Constants.MAX_SHORT)) - throw new ClassGenException("Invalid index index: " + index); + private int index; + private String name; + private Type type; + private InstructionHandle start; + private InstructionHandle end; - this.name = name; - this.type = type; - this.index = index; - setStart(start); - setEnd(end); - } - - /** - * Get LocalVariable object. - * - * This relies on that the instruction list has already been dumped to byte code or - * or that the `setPositions' methods has been called for the instruction list. - * - * Note that for local variables whose scope end at the last - * instruction of the method's code, the JVM specification is ambiguous: - * both a start_pc+length ending at the last instruction and - * start_pc+length ending at first index beyond the end of the code are - * valid. - * - * @param il instruction list (byte code) which this variable belongs to - * @param cp constant pool - */ - public LocalVariable getLocalVariable(ConstantPoolGen cp) { - int start_pc = start.getPosition(); - int length = end.getPosition() - start_pc; - - if(length > 0) - length += end.getInstruction().getLength(); - - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(type.getSignature()); - - return new LocalVariable(start_pc, length, name_index, - signature_index, index, cp.getConstantPool()); - } - - public int getIndex() { return index; } - @Override - public void setName(String name) { this.name = name; } - @Override - public String getName() { return name; } - @Override - public void setType(Type type) { this.type = type; } - @Override - public Type getType() { return type; } - - public InstructionHandle getStart() { return start; } - public InstructionHandle getEnd() { return end; } - - /** - * Remove this from any known HashSet in which it might be registered. - */ - void notifyTargetChanging() { - // hashCode depends on 'index', 'start', and 'end'. - // Therefore before changing any of these values we - // need to unregister 'this' from any HashSet where - // this is registered, and then we need to add it - // back... - - // Unregister 'this' from the HashSet held by 'start'. - BranchInstruction.notifyTargetChanging(this.start, this); - if (this.end != this.start) { - // Since hashCode() is going to change we need to unregister - // 'this' both form 'start' and 'end'. - // Unregister 'this' from the HashSet held by 'end'. - BranchInstruction.notifyTargetChanging(this.end, this); - } - } - - /** - * Add back 'this' in all HashSet in which it should be registered. - **/ - void notifyTargetChanged() { - // hashCode depends on 'index', 'start', and 'end'. - // Therefore before changing any of these values we - // need to unregister 'this' from any HashSet where - // this is registered, and then we need to add it - // back... - - // Register 'this' in the HashSet held by start. - BranchInstruction.notifyTargetChanged(this.start, this); - if (this.end != this.start) { - // Since hashCode() has changed we need to register - // 'this' again in 'end'. - // Add back 'this' in the HashSet held by 'end'. - BranchInstruction.notifyTargetChanged(this.end, this); - } - } - - public final void setStart(InstructionHandle start) { - - // Call notifyTargetChanging *before* modifying this, - // as the code triggered by notifyTargetChanging - // depends on this pointing to the 'old' start. - notifyTargetChanging(); - - this.start = start; - - // call notifyTargetChanged *after* modifying this, - // as the code triggered by notifyTargetChanged - // depends on this pointing to the 'new' start. - notifyTargetChanged(); - } - - public final void setEnd(InstructionHandle end) { - // call notifyTargetChanging *before* modifying this, - // as the code triggered by notifyTargetChanging - // depends on this pointing to the 'old' end. - // Unregister 'this' from the HashSet held by the 'old' end. - notifyTargetChanging(); - - this.end = end; - - // call notifyTargetChanged *after* modifying this, - // as the code triggered by notifyTargetChanged - // depends on this pointing to the 'new' end. - // Register 'this' in the HashSet held by the 'new' end. - notifyTargetChanged(); - - } - - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if(start == old_ih) { - targeted = true; - setStart(new_ih); + /** + * Generate a local variable that with index `index'. Note that double and + * long variables need two indexs. Index indices have to be provided by the + * user. + * + * @param index index of local variable + * @param name its name + * @param type its type + * @param start from where the instruction is valid (null means from the + * start) + * @param end until where the instruction is valid (null means to the end) + */ + public LocalVariableGen(final int index, final String name, final Type type, + final InstructionHandle start, final InstructionHandle end) { + if ((index < 0) || (index > Const.MAX_SHORT)) { + throw new ClassGenException("Invalid index index: " + index); + } + this.name = name; + this.type = type; + this.index = index; + setStart(start); + setEnd(end); } - if(end == old_ih) { - targeted = true; - setEnd(new_ih); + /** + * Get LocalVariable object. + * + * This relies on that the instruction list has already been dumped to byte + * code or or that the `setPositions' methods has been called for the + * instruction list. + * + * Note that for local variables whose scope end at the last instruction of + * the method's code, the JVM specification is ambiguous: both a + * start_pc+length ending at the last instruction and start_pc+length ending + * at first index beyond the end of the code are valid. + * + * @param cp constant pool + */ + public LocalVariable getLocalVariable(final ConstantPoolGen cp) { + int start_pc = 0; + int length = 0; + if ((start != null) && (end != null)) { + start_pc = start.getPosition(); + length = end.getPosition() - start_pc; + if (end.getNext() == null) { + length += end.getInstruction().getLength(); + } + } + final int name_index = cp.addUtf8(name); + final int signature_index = cp.addUtf8(type.getSignature()); + return new LocalVariable(start_pc, length, name_index, signature_index, index, cp + .getConstantPool()); } - if(!targeted) - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + - end + "}"); - } - - /** - * @return true, if ih is target of this variable - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - return (start == ih) || (end == ih); - } - - /** - * We consider two local variables to be equal, if they use the same index and - * are valid in the same range. - */ - @Override - public boolean equals(Object o) { - if (o==this) - return true; - - if(!(o instanceof LocalVariableGen)) - return false; - - LocalVariableGen l = (LocalVariableGen)o; - return (l.index == index) && (l.start == start) && (l.end == end); - } - - @Override - public int hashCode() { - int hash = 7; - hash = 59 * hash + this.index; - hash = 59 * hash + Objects.hashCode(this.start); - hash = 59 * hash + Objects.hashCode(this.end); - return hash; - } - - @Override - public String toString() { - return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; + public void setIndex(final int index) { + this.index = index; + } + + public int getIndex() { + return index; + } + + @Override + public void setName(final String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setType(final Type type) { + this.type = type; + } + + @Override + public Type getType() { + return type; + } + + public InstructionHandle getStart() { + return start; + } + + public InstructionHandle getEnd() { + return end; + } + + public void setStart(final InstructionHandle start) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.start, start, this); + this.start = start; + } + + public void setEnd(final InstructionHandle end) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.end, end, this); + this.end = end; + } + + /** + * @param old_ih old target, either start or end + * @param new_ih new target + */ + @Override + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + boolean targeted = false; + if (start == old_ih) { + targeted = true; + setStart(new_ih); + } + if (end == old_ih) { + targeted = true; + setEnd(new_ih); + } + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + end + + "}"); + } + } + + /** + * Clear the references from and to this variable when it's removed. + */ + void dispose() { + setStart(null); + setEnd(null); + } + + /** + * @return true, if ih is target of this variable + */ + @Override + public boolean containsTarget(final InstructionHandle ih) { + return (start == ih) || (end == ih); + } + + @Override + public int hashCode() { + // If the user changes the name or type, problems with the targeter hashmap will occur. + // Note: index cannot be part of hash as it may be changed by the user. + return name.hashCode() ^ type.hashCode(); + } + + /** + * We consider to local variables to be equal, if the use the same index and + * are valid in the same range. + */ + @Override + public boolean equals(final Object o) { + if (!(o instanceof LocalVariableGen)) { + return false; + } + final LocalVariableGen l = (LocalVariableGen) o; + return (l.index == index) && (l.start == start) && (l.end == end); + } + + @Override + public String toString() { + return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java index 26e14a3787f..87eb80da82d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,176 +17,205 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.util.ByteSequence; -import com.sun.org.apache.bcel.internal.classfile.Utility; -import com.sun.org.apache.bcel.internal.Constants; /** * Abstract super class for instructions dealing with local variables. * - * @author M. Dahm + * @version $Id: LocalVariableInstruction.java 1747278 2016-06-07 17:28:43Z + * britter $ */ -public abstract class LocalVariableInstruction extends Instruction - implements TypedInstruction, IndexedInstruction { - protected int n = -1; // index of referenced variable - private short c_tag = -1; // compact version, such as ILOAD_0 - private short canon_tag = -1; // canonical tag such as ILOAD +public abstract class LocalVariableInstruction extends Instruction implements TypedInstruction, + IndexedInstruction { - private final boolean wide() { return n > Constants.MAX_BYTE; } + private int n = -1; // index of referenced variable + private short c_tag = -1; // compact version, such as ILOAD_0 + private short canon_tag = -1; // canonical tag such as ILOAD - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - LocalVariableInstruction(short canon_tag, short c_tag) { - super(); - this.canon_tag = canon_tag; - this.c_tag = c_tag; - } - - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Also used by IINC()! - */ - LocalVariableInstruction() { - } - - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ALOAD_0, e.g. - * @param n local variable index (unsigned short) - */ - protected LocalVariableInstruction(short opcode, short c_tag, int n) { - super(opcode, (short)2); - - this.c_tag = c_tag; - canon_tag = opcode; - - setIndex(n); - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - if(wide()) // Need WIDE prefix ? - out.writeByte(Constants.WIDE); - - out.writeByte(opcode); - - if(length > 1) { // Otherwise ILOAD_n, instruction, e.g. - if(wide()) - out.writeShort(n); - else - out.writeByte(n); + private boolean wide() { + return n > Const.MAX_BYTE; } - } - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" "<"< local variable index>">" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - if(((opcode >= Constants.ILOAD_0) && - (opcode <= Constants.ALOAD_3)) || - ((opcode >= Constants.ISTORE_0) && - (opcode <= Constants.ASTORE_3))) - return super.toString(verbose); - else - return super.toString(verbose) + " " + n; - } - - /** - * Read needed data (e.g. index) from file. - * PRE: (ILOAD <= tag <= ALOAD_3) || (ISTORE <= tag <= ASTORE_3) - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - if(wide) { - n = bytes.readUnsignedShort(); - length = 4; - } else if(((opcode >= Constants.ILOAD) && - (opcode <= Constants.ALOAD)) || - ((opcode >= Constants.ISTORE) && - (opcode <= Constants.ASTORE))) { - n = bytes.readUnsignedByte(); - length = 2; - } else if(opcode <= Constants.ALOAD_3) { // compact load instruction such as ILOAD_2 - n = (opcode - Constants.ILOAD_0) % 4; - length = 1; - } else { // Assert ISTORE_0 <= tag <= ASTORE_3 - n = (opcode - Constants.ISTORE_0) % 4; - length = 1; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. tag and length + * are defined in readInstruction and initFromFile, respectively. + */ + LocalVariableInstruction(final short canon_tag, final short c_tag) { + super(); + this.canon_tag = canon_tag; + this.c_tag = c_tag; } - } - /** - * @return local variable index referred by this instruction. - */ - public final int getIndex() { return n; } - - /** - * Set the local variable index - */ - public void setIndex(int n) { - if((n < 0) || (n > Constants.MAX_SHORT)) - throw new ClassGenException("Illegal value: " + n); - - this.n = n; - - if(n >= 0 && n <= 3) { // Use more compact instruction xLOAD_n - opcode = (short)(c_tag + n); - length = 1; - } else { - opcode = canon_tag; - - if(wide()) // Need WIDE prefix ? - length = 4; - else - length = 2; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Also used by IINC()! + */ + LocalVariableInstruction() { } - } - /** @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 - */ - public short getCanonicalTag() { - return canon_tag; - } - - /** - * Returns the type associated with the instruction - - * in case of ALOAD or ASTORE Type.OBJECT is returned. - * This is just a bit incorrect, because ALOAD and ASTORE - * may work on every ReferenceType (including Type.NULL) and - * ASTORE may even work on a ReturnaddressType . - * @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - switch(canon_tag) { - case Constants.ILOAD: case Constants.ISTORE: - return Type.INT; - case Constants.LLOAD: case Constants.LSTORE: - return Type.LONG; - case Constants.DLOAD: case Constants.DSTORE: - return Type.DOUBLE; - case Constants.FLOAD: case Constants.FSTORE: - return Type.FLOAT; - case Constants.ALOAD: case Constants.ASTORE: - return Type.OBJECT; - - default: throw new ClassGenException("Oops: unknown case in switch" + canon_tag); + /** + * @param opcode Instruction opcode + * @param c_tag Instruction number for compact version, ALOAD_0, e.g. + * @param n local variable index (unsigned short) + */ + protected LocalVariableInstruction(final short opcode, final short c_tag, final int n) { + super(opcode, (short) 2); + this.c_tag = c_tag; + canon_tag = opcode; + setIndex(n); + } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + if (wide()) { + out.writeByte(Const.WIDE); + } + out.writeByte(super.getOpcode()); + if (super.getLength() > 1) { // Otherwise ILOAD_n, instruction, e.g. + if (wide()) { + out.writeShort(n); + } else { + out.writeByte(n); + } + } + } + + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" "<"< local variable index>">" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + final short _opcode = super.getOpcode(); + if (((_opcode >= Const.ILOAD_0) && (_opcode <= Const.ALOAD_3)) + || ((_opcode >= Const.ISTORE_0) && (_opcode <= Const.ASTORE_3))) { + return super.toString(verbose); + } + return super.toString(verbose) + " " + n; + } + + /** + * Read needed data (e.g. index) from file. + *
    +     * (ILOAD <= tag <= ALOAD_3) || (ISTORE <= tag <= ASTORE_3)
    +     * 
    + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + if (wide) { + n = bytes.readUnsignedShort(); + super.setLength(4); + } else { + final short _opcode = super.getOpcode(); + if (((_opcode >= Const.ILOAD) && (_opcode <= Const.ALOAD)) + || ((_opcode >= Const.ISTORE) && (_opcode <= Const.ASTORE))) { + n = bytes.readUnsignedByte(); + super.setLength(2); + } else if (_opcode <= Const.ALOAD_3) { // compact load instruction such as ILOAD_2 + n = (_opcode - Const.ILOAD_0) % 4; + super.setLength(1); + } else { // Assert ISTORE_0 <= tag <= ASTORE_3 + n = (_opcode - Const.ISTORE_0) % 4; + super.setLength(1); + } + } + } + + /** + * @return local variable index (n) referred by this instruction. + */ + @Override + public final int getIndex() { + return n; + } + + /** + * Set the local variable index. also updates opcode and length TODO Why? + * + * @see #setIndexOnly(int) + */ + @Override + public void setIndex(final int n) { // TODO could be package-protected? + if ((n < 0) || (n > Const.MAX_SHORT)) { + throw new ClassGenException("Illegal value: " + n); + } + this.n = n; + // Cannot be < 0 as this is checked above + if (n <= 3) { // Use more compact instruction xLOAD_n + super.setOpcode((short) (c_tag + n)); + super.setLength(1); + } else { + super.setOpcode(canon_tag); + if (wide()) { + super.setLength(4); + } else { + super.setLength(2); + } + } + } + + /** + * @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 + */ + public short getCanonicalTag() { + return canon_tag; + } + + /** + * Returns the type associated with the instruction - in case of ALOAD or + * ASTORE Type.OBJECT is returned. This is just a bit incorrect, because + * ALOAD and ASTORE may work on every ReferenceType (including Type.NULL) + * and ASTORE may even work on a ReturnaddressType . + * + * @return type associated with the instruction + */ + @Override + public Type getType(final ConstantPoolGen cp) { + switch (canon_tag) { + case Const.ILOAD: + case Const.ISTORE: + return Type.INT; + case Const.LLOAD: + case Const.LSTORE: + return Type.LONG; + case Const.DLOAD: + case Const.DSTORE: + return Type.DOUBLE; + case Const.FLOAD: + case Const.FSTORE: + return Type.FLOAT; + case Const.ALOAD: + case Const.ASTORE: + return Type.OBJECT; + default: + throw new ClassGenException("Oops: unknown case in switch" + canon_tag); + } + } + + /** + * Sets the index of the referenced variable (n) only + * + * @since 6.0 + * @see #setIndex(int) + */ + final void setIndexOnly(final int n) { + this.n = n; } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java index 5fd6d61692c..7d5267ef471 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java @@ -21,35 +21,41 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * MONITORENTER - Enter monitor for object *
    Stack: ..., objectref -> ...
    * - * @author M. Dahm + * @version $Id: MONITORENTER.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class MONITORENTER extends Instruction - implements ExceptionThrower, StackConsumer { - public MONITORENTER() { - super(com.sun.org.apache.bcel.internal.Constants.MONITORENTER, (short)1); - } +public class MONITORENTER extends Instruction implements ExceptionThrower, StackConsumer { - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.NULL_POINTER_EXCEPTION }; - } + public MONITORENTER() { + super(com.sun.org.apache.bcel.internal.Const.MONITORENTER, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitMONITORENTER(this); - } + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.NULL_POINTER_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitMONITORENTER(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java index d6a87fd64b5..c1ec802c759 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java @@ -21,35 +21,41 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * MONITOREXIT - Exit monitor for object *
    Stack: ..., objectref -> ...
    * - * @author M. Dahm + * @version $Id: MONITOREXIT.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class MONITOREXIT extends Instruction - implements ExceptionThrower, StackConsumer { - public MONITOREXIT() { - super(com.sun.org.apache.bcel.internal.Constants.MONITOREXIT, (short)1); - } +public class MONITOREXIT extends Instruction implements ExceptionThrower, StackConsumer { - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.NULL_POINTER_EXCEPTION }; - } + public MONITOREXIT() { + super(com.sun.org.apache.bcel.internal.Const.MONITOREXIT, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitMONITOREXIT(this); - } + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.NULL_POINTER_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitMONITOREXIT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java index 54c9d8b11df..cc941ae7ae2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java @@ -21,119 +21,136 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; -import com.sun.org.apache.bcel.internal.util.ByteSequence; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.ExceptionConst; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * MULTIANEWARRAY - Create new mutidimensional array of references *
    Stack: ..., count1, [count2, ...] -> ..., arrayref
    * - * @author M. Dahm + * @version $Id: MULTIANEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, ExceptionThrower { - private short dimensions; +public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, + ExceptionThrower { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - MULTIANEWARRAY() {} + private short dimensions; - public MULTIANEWARRAY(int index, short dimensions) { - super(com.sun.org.apache.bcel.internal.Constants.MULTIANEWARRAY, index); - if(dimensions < 1) - throw new ClassGenException("Invalid dimensions value: " + dimensions); - - this.dimensions = dimensions; - length = 4; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - out.writeByte(dimensions); - } - - /** - * Read needed data (i.e., no. dimension) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - super.initFromFile(bytes, wide); - dimensions = bytes.readByte(); - length = 4; - } - - /** - * @return number of dimensions to be created - */ - public final short getDimensions() { return dimensions; } - - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + index + " " + dimensions; - } - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - return super.toString(cp) + " " + dimensions; - } - - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words consumed from stack by this instruction - */ - public int consumeStack(ConstantPoolGen cpg) { return dimensions; } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length+1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - - return cs; - } - - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - Type t = getType(cpg); - - if (t instanceof ArrayType){ - t = ((ArrayType) t).getBasicType(); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + MULTIANEWARRAY() { } - return (t instanceof ObjectType)? (ObjectType) t : null; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitMULTIANEWARRAY(this); - } + public MULTIANEWARRAY(final int index, final short dimensions) { + super(com.sun.org.apache.bcel.internal.Const.MULTIANEWARRAY, index); + if (dimensions < 1) { + throw new ClassGenException("Invalid dimensions value: " + dimensions); + } + this.dimensions = dimensions; + super.setLength(4); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + out.writeByte(dimensions); + } + + + /** + * Read needed data (i.e., no. dimension) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + dimensions = bytes.readByte(); + super.setLength(4); + } + + + /** + * @return number of dimensions to be created + */ + public final short getDimensions() { + return dimensions; + } + + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + super.getIndex() + " " + dimensions; + } + + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + return super.toString(cp) + " " + dimensions; + } + + + /** + * Also works for instructions whose stack effect depends on the + * constant pool entry they reference. + * @return Number of words consumed from stack by this instruction + */ + @Override + public int consumeStack( final ConstantPoolGen cpg ) { + return dimensions; + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, + ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION); + } + + + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitMULTIANEWARRAY(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java index 61a3daf61ea..81ed1c07f69 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,13 +17,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.util.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.Annotations; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Code; +import com.sun.org.apache.bcel.internal.classfile.CodeException; +import com.sun.org.apache.bcel.internal.classfile.ExceptionTable; +import com.sun.org.apache.bcel.internal.classfile.LineNumber; +import com.sun.org.apache.bcel.internal.classfile.LineNumberTable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariableTypeTable; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.ParameterAnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.ParameterAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleParameterAnnotations; +import com.sun.org.apache.bcel.internal.classfile.Utility; +import com.sun.org.apache.bcel.internal.util.BCELComparator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; /** * Template class for building up a method. This is done by defining exception @@ -33,1021 +52,1216 @@ import java.util.*; * automatically for the code. Use stripAttributes() if you don't like this. * * While generating code it may be necessary to insert NOP operations. You can - * use the `removeNOPs' method to get rid off them. - * The resulting method object can be obtained via the `getMethod()' method. + * use the `removeNOPs' method to get rid off them. The resulting method object + * can be obtained via the `getMethod()' method. * - * @author M. Dahm - * @author Patrick C. Beard [setMaxStack()] - * @see InstructionList - * @see Method + * @version $Id: MethodGen.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see InstructionList + * @see Method */ public class MethodGen extends FieldGenOrMethodGen { - private String class_name; - private Type[] arg_types; - private String[] arg_names; - private int max_locals; - private int max_stack; - private InstructionList il; - private boolean strip_attributes; - private ArrayList variable_vec = new ArrayList(); - private ArrayList type_vec = new ArrayList(); - private ArrayList line_number_vec = new ArrayList(); - private ArrayList exception_vec = new ArrayList(); - private ArrayList throws_vec = new ArrayList(); - private ArrayList code_attrs_vec = new ArrayList(); + private String class_name; + private Type[] arg_types; + private String[] arg_names; + private int max_locals; + private int max_stack; + private InstructionList il; + private boolean strip_attributes; + private final List variable_vec = new ArrayList<>(); + private final List type_vec = new ArrayList<>(); + private final List line_number_vec = new ArrayList<>(); + private final List exception_vec = new ArrayList<>(); + private final List throws_vec = new ArrayList<>(); + private final List code_attrs_vec = new ArrayList<>(); - /** - * Declare method. If the method is non-static the constructor - * automatically declares a local variable `$this' in slot 0. The - * actual code is contained in the `il' parameter, which may further - * manipulated by the user. But he must take care not to remove any - * instruction (handles) that are still referenced from this object. - * - * For example one may not add a local variable and later remove the - * instructions it refers to without causing havoc. It is safe - * however if you remove that local variable, too. - * - * @param access_flags access qualifiers - * @param return_type method type - * @param arg_types argument types - * @param arg_names argument names (if this is null, default names will be provided - * for them) - * @param method_name name of method - * @param class_name class name containing this method (may be null, if you don't care) - * @param il instruction list associated with this method, may be null only for - * abstract or native methods - * @param cp constant pool - */ - public MethodGen(int access_flags, Type return_type, Type[] arg_types, - String[] arg_names, String method_name, String class_name, - InstructionList il, ConstantPoolGen cp) { - setAccessFlags(access_flags); - setType(return_type); - setArgumentTypes(arg_types); - setArgumentNames(arg_names); - setName(method_name); - setClassName(class_name); - setInstructionList(il); - setConstantPool(cp); + private List[] param_annotations; // Array of lists containing AnnotationGen objects + private boolean hasParameterAnnotations = false; + private boolean haveUnpackedParameterAnnotations = false; - boolean abstract_ = isAbstract() || isNative(); - InstructionHandle start = null; - InstructionHandle end = null; + private static BCELComparator bcelComparator = new BCELComparator() { - if(!abstract_) { - start = il.getStart(); - end = il.getEnd(); - - /* Add local variables, namely the implicit `this' and the arguments - */ - if(!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0 - addLocalVariable("this", new ObjectType(class_name), start, end); - } - } - - if(arg_types != null) { - int size = arg_types.length; - - for(int i=0; i < size; i++) { - if(Type.VOID == arg_types[i]) { - throw new ClassGenException("'void' is an illegal argument type for a method"); + @Override + public boolean equals(final Object o1, final Object o2) { + final MethodGen THIS = (MethodGen) o1; + final MethodGen THAT = (MethodGen) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); } - } - if(arg_names != null) { // Names for variables provided? - if(size != arg_names.length) - throw new ClassGenException("Mismatch in argument array lengths: " + - size + " vs. " + arg_names.length); - } else { // Give them dummy names - arg_names = new String[size]; - - for(int i=0; i < size; i++) - arg_names[i] = "arg" + i; + @Override + public int hashCode(final Object o) { + final MethodGen THIS = (MethodGen) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; + /** + * Declare method. If the method is non-static the constructor automatically + * declares a local variable `$this' in slot 0. The actual code is contained + * in the `il' parameter, which may further manipulated by the user. But he + * must take care not to remove any instruction (handles) that are still + * referenced from this object. + * + * For example one may not add a local variable and later remove the + * instructions it refers to without causing havoc. It is safe however if + * you remove that local variable, too. + * + * @param access_flags access qualifiers + * @param return_type method type + * @param arg_types argument types + * @param arg_names argument names (if this is null, default names will be + * provided for them) + * @param method_name name of method + * @param class_name class name containing this method (may be null, if you + * don't care) + * @param il instruction list associated with this method, may be null only + * for abstract or native methods + * @param cp constant pool + */ + public MethodGen(final int access_flags, final Type return_type, final Type[] arg_types, String[] arg_names, + final String method_name, final String class_name, final InstructionList il, final ConstantPoolGen cp) { + super(access_flags); + setType(return_type); + setArgumentTypes(arg_types); setArgumentNames(arg_names); - } - - if(!abstract_) { - for(int i=0; i < size; i++) { - addLocalVariable(arg_names[i], arg_types[i], start, end); - } - } - } - } - - /** - * Instantiate from existing method. - * - * @param m method - * @param class_name class name containing this method - * @param cp constant pool - */ - public MethodGen(Method m, String class_name, ConstantPoolGen cp) { - this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), - Type.getArgumentTypes(m.getSignature()), null /* may be overridden anyway */, - m.getName(), class_name, - ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0)? - new InstructionList(m.getCode().getCode()) : null, - cp); - - Attribute[] attributes = m.getAttributes(); - for(int i=0; i < attributes.length; i++) { - Attribute a = attributes[i]; - - if(a instanceof Code) { - Code c = (Code)a; - setMaxStack(c.getMaxStack()); - setMaxLocals(c.getMaxLocals()); - - CodeException[] ces = c.getExceptionTable(); - - if(ces != null) { - for(int j=0; j < ces.length; j++) { - CodeException ce = ces[j]; - int type = ce.getCatchType(); - ObjectType c_type = null; - - if(type > 0) { - String cen = m.getConstantPool().getConstantString(type, Constants.CONSTANT_Class); - c_type = new ObjectType(cen); + setName(method_name); + setClassName(class_name); + setInstructionList(il); + setConstantPool(cp); + final boolean abstract_ = isAbstract() || isNative(); + InstructionHandle start = null; + InstructionHandle end = null; + if (!abstract_) { + start = il.getStart(); + end = il.getEnd(); + /* Add local variables, namely the implicit `this' and the arguments + */ + if (!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0 + addLocalVariable("this", ObjectType.getInstance(class_name), start, end); } + } + if (arg_types != null) { + final int size = arg_types.length; + for (final Type arg_type : arg_types) { + if (Type.VOID == arg_type) { + throw new ClassGenException("'void' is an illegal argument type for a method"); + } + } + if (arg_names != null) { // Names for variables provided? + if (size != arg_names.length) { + throw new ClassGenException("Mismatch in argument array lengths: " + size + + " vs. " + arg_names.length); + } + } else { // Give them dummy names + arg_names = new String[size]; + for (int i = 0; i < size; i++) { + arg_names[i] = "arg" + i; + } + setArgumentNames(arg_names); + } + if (!abstract_) { + for (int i = 0; i < size; i++) { + addLocalVariable(arg_names[i], arg_types[i], start, end); + } + } + } + } - int end_pc = ce.getEndPC(); - int length = m.getCode().getCode().length; - - InstructionHandle end; - - if(length == end_pc) { // May happen, because end_pc is exclusive - end = il.getEnd(); + /** + * Instantiate from existing method. + * + * @param m method + * @param class_name class name containing this method + * @param cp constant pool + */ + public MethodGen(final Method m, final String class_name, final ConstantPoolGen cp) { + this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), Type.getArgumentTypes(m + .getSignature()), null /* may be overridden anyway */, m.getName(), class_name, + ((m.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0) + ? new InstructionList(m.getCode().getCode()) + : null, cp); + final Attribute[] attributes = m.getAttributes(); + for (final Attribute attribute : attributes) { + Attribute a = attribute; + if (a instanceof Code) { + final Code c = (Code) a; + setMaxStack(c.getMaxStack()); + setMaxLocals(c.getMaxLocals()); + final CodeException[] ces = c.getExceptionTable(); + if (ces != null) { + for (final CodeException ce : ces) { + final int type = ce.getCatchType(); + ObjectType c_type = null; + if (type > 0) { + final String cen = m.getConstantPool().getConstantString(type, + Const.CONSTANT_Class); + c_type = ObjectType.getInstance(cen); + } + final int end_pc = ce.getEndPC(); + final int length = m.getCode().getCode().length; + InstructionHandle end; + if (length == end_pc) { // May happen, because end_pc is exclusive + end = il.getEnd(); + } else { + end = il.findHandle(end_pc); + end = end.getPrev(); // Make it inclusive + } + addExceptionHandler(il.findHandle(ce.getStartPC()), end, il.findHandle(ce + .getHandlerPC()), c_type); + } + } + final Attribute[] c_attributes = c.getAttributes(); + for (final Attribute c_attribute : c_attributes) { + a = c_attribute; + if (a instanceof LineNumberTable) { + final LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable(); + for (final LineNumber l : ln) { + final InstructionHandle ih = il.findHandle(l.getStartPC()); + if (ih != null) { + addLineNumber(ih, l.getLineNumber()); + } + } + } else if (a instanceof LocalVariableTable) { + final LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable(); + removeLocalVariables(); + repairHandles(lv, false); + } else if (a instanceof LocalVariableTypeTable) { + LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable(); + removeLocalVariableTypes(); + repairHandles(lv, true); + } else { + addCodeAttribute(a); + } + } + } else if (a instanceof ExceptionTable) { + final String[] names = ((ExceptionTable) a).getExceptionNames(); + for (final String name2 : names) { + addException(name2); + } + } else if (a instanceof Annotations) { + final Annotations runtimeAnnotations = (Annotations) a; + final AnnotationEntry[] aes = runtimeAnnotations.getAnnotationEntries(); + for (final AnnotationEntry element : aes) { + addAnnotationEntry(new AnnotationEntryGen(element, cp, false)); + } } else { - end = il.findHandle(end_pc); - end = end.getPrev(); // Make it inclusive + addAttribute(a); } - - addExceptionHandler(il.findHandle(ce.getStartPC()), end, - il.findHandle(ce.getHandlerPC()), c_type); - } } + } - Attribute[] c_attributes = c.getAttributes(); - for(int j=0; j < c_attributes.length; j++) { - a = c_attributes[j]; - - if(a instanceof LineNumberTable) { - LineNumber[] ln = ((LineNumberTable)a).getLineNumberTable(); - - for(int k=0; k < ln.length; k++) { - LineNumber l = ln[k]; - addLineNumber(il.findHandle(l.getStartPC()), l.getLineNumber()); - } - } else if(a instanceof LocalVariableTable) { - LocalVariable[] lv = ((LocalVariableTable)a).getLocalVariableTable(); - - removeLocalVariables(); - - for(int k=0; k < lv.length; k++) { - LocalVariable l = lv[k]; - InstructionHandle start = il.findHandle(l.getStartPC()); - InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); - - // Repair malformed handles - if(null == start) { + private void repairHandles(final LocalVariable[] lv, boolean isLVT) { + for (int k = 0; k < lv.length; k++) { + LocalVariable l = lv[k]; + InstructionHandle start = il.findHandle(l.getStartPC()); + InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); + // Repair malformed handles + if (null == start) { start = il.getStart(); - } - - if(null == end) { + } + if (null == end) { end = il.getEnd(); - } - - addLocalVariable(l.getName(), Type.getType(l.getSignature()), - l.getIndex(), start, end); } - } else if (a instanceof LocalVariableTypeTable) { - LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable(); - removeLocalVariableTypes(); - for (int k = 0; k < lv.length; k++) { - LocalVariable l = lv[k]; - InstructionHandle start = il.findHandle(l.getStartPC()); - InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); - // Repair malformed handles - if (null == start) { - start = il.getStart(); - } - if (null == end) { - end = il.getEnd(); - } - addLocalVariableType(l.getName(), Type.getType(l.getSignature()), l - .getIndex(), start, end); - } - } else - addCodeAttribute(a); - } - } else if(a instanceof ExceptionTable) { - String[] names = ((ExceptionTable)a).getExceptionNames(); - for(int j=0; j < names.length; j++) - addException(names[j]); - } else - addAttribute(a); - } - } - - /** - * Adds a local variable to this method. - * - * @param name variable name - * @param type variable type - * @param slot the index of the local variable, if type is long or double, the next available - * index is slot+2 - * @param start from where the variable is valid - * @param end until where the variable is valid - * @return new local variable object - * @see LocalVariable - */ - public LocalVariableGen addLocalVariable(String name, Type type, int slot, - InstructionHandle start, - InstructionHandle end) { - byte t = type.getType(); - - if(t != Constants.T_ADDRESS) { - int add = type.getSize(); - - if(slot + add > max_locals) - max_locals = slot + add; - - LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); - int i; - - if((i = variable_vec.indexOf(l)) >= 0) // Overwrite if necessary - variable_vec.set(i, l); - else - variable_vec.add(l); - - return l; - } else { - throw new IllegalArgumentException("Can not use " + type + - " as type for local variable"); - - } - } - - /** - * Adds a local variable to this method and assigns an index automatically. - * - * @param name variable name - * @param type variable type - * @param start from where the variable is valid, if this is null, - * it is valid from the start - * @param end until where the variable is valid, if this is null, - * it is valid to the end - * @return new local variable object - * @see LocalVariable - */ - public LocalVariableGen addLocalVariable(String name, Type type, - InstructionHandle start, - InstructionHandle end) { - return addLocalVariable(name, type, max_locals, start, end); - } - - /** - * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable - * with an explicit index argument. - */ - public void removeLocalVariable(LocalVariableGen l) { - variable_vec.remove(l); - } - - /** - * Remove all local variables. - */ - public void removeLocalVariables() { - variable_vec.clear(); - } - - /** - * Sort local variables by index - */ - private static final void sort(LocalVariableGen[] vars, int l, int r) { - int i = l, j = r; - int m = vars[(l + r) / 2].getIndex(); - LocalVariableGen h; - - do { - while(vars[i].getIndex() < m) i++; - while(m < vars[j].getIndex()) j--; - - if(i <= j) { - h=vars[i]; vars[i]=vars[j]; vars[j]=h; // Swap elements - i++; j--; - } - } while(i <= j); - - if(l < j) sort(vars, l, j); - if(i < r) sort(vars, i, r); - } - - /* - * If the range of the variable has not been set yet, it will be set to be valid from - * the start to the end of the instruction list. - * - * @return array of declared local variables sorted by index - */ - public LocalVariableGen[] getLocalVariables() { - int size = variable_vec.size(); - LocalVariableGen[] lg = new LocalVariableGen[size]; - variable_vec.toArray(lg); - - for(int i=0; i < size; i++) { - if(lg[i].getStart() == null) - lg[i].setStart(il.getStart()); - - if(lg[i].getEnd() == null) - lg[i].setEnd(il.getEnd()); - } - - if(size > 1) - sort(lg, 0, size - 1); - - return lg; - } - - /* - * If the range of the variable has not been set yet, it will be set to be - * val id from the start to the end of the instruction list. - * - * @return array of declared local variable types sorted by index - */ - private LocalVariableGen[] getLocalVariableTypes() { - int size = type_vec.size(); - LocalVariableGen[] lg = new LocalVariableGen[size]; - type_vec.toArray(lg); - - for(int i=0; i < size; i++) { - if(lg[i].getStart() == null) - lg[i].setStart(il.getStart()); - - if(lg[i].getEnd() == null) - lg[i].setEnd(il.getEnd()); - } - - if(size > 1) - sort(lg, 0, size - 1); - - return lg; - } - - /** - * @return `LocalVariableTable' attribute of all the local variables of this method. - */ - public LocalVariableTable getLocalVariableTable(ConstantPoolGen cp) { - LocalVariableGen[] lg = getLocalVariables(); - int size = lg.length; - LocalVariable[] lv = new LocalVariable[size]; - - for(int i=0; i < size; i++) - lv[i] = lg[i].getLocalVariable(cp); - - return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), - 2 + lv.length * 10, lv, cp.getConstantPool()); - } - - /** - * @return `LocalVariableTypeTable' attribute of all the local variable - * types of this method. - */ - public LocalVariableTypeTable getLocalVariableTypeTable(ConstantPoolGen cp) { - LocalVariableGen[] lg = getLocalVariableTypes(); - int size = lg.length; - LocalVariable[] lv = new LocalVariable[size]; - - for(int i=0; i < size; i++) - lv[i] = lg[i].getLocalVariable(cp); - - return new LocalVariableTypeTable(cp.addUtf8("LocalVariableTypeTable"), - 2 + lv.length * 10, lv, cp.getConstantPool()); - } - - /** - * Adds a local variable type to this method. - * - * @param name variable name - * @param type variable type - * @param slot the index of the local variable, if type is long or double, the next available - * index is slot+2 - * @param start from where the variable is valid - * @param end until where the variable is valid - * @return new local variable object - * @see LocalVariable - */ - private LocalVariableGen addLocalVariableType(String name, Type type, int slot, - InstructionHandle start, - InstructionHandle end) { - byte t = type.getType(); - - if(t != Constants.T_ADDRESS) { - int add = type.getSize(); - - if(slot + add > max_locals) - max_locals = slot + add; - - LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); - int i; - - if((i = type_vec.indexOf(l)) >= 0) // Overwrite if necessary - type_vec.set(i, l); - else - type_vec.add(l); - - return l; - } else { - throw new IllegalArgumentException("Can not use " + type + - " as type for local variable"); - - } - } - - /** - * Remove all local variable types. - */ - private void removeLocalVariableTypes() { - type_vec.clear(); - } - - /** - * Give an instruction a line number corresponding to the source code line. - * - * @param ih instruction to tag - * @return new line number object - * @see LineNumber - */ - public LineNumberGen addLineNumber(InstructionHandle ih, int src_line) { - LineNumberGen l = new LineNumberGen(ih, src_line); - line_number_vec.add(l); - return l; - } - - /** - * Remove a line number. - */ - public void removeLineNumber(LineNumberGen l) { - line_number_vec.remove(l); - } - - /** - * Remove all line numbers. - */ - public void removeLineNumbers() { - line_number_vec.clear(); - } - - /* - * @return array of line numbers - */ - public LineNumberGen[] getLineNumbers() { - LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()]; - line_number_vec.toArray(lg); - return lg; - } - - /** - * @return `LineNumberTable' attribute of all the local variables of this method. - */ - public LineNumberTable getLineNumberTable(ConstantPoolGen cp) { - int size = line_number_vec.size(); - LineNumber[] ln = new LineNumber[size]; - - try { - for(int i=0; i < size; i++) - ln[i] = ((LineNumberGen)line_number_vec.get(i)).getLineNumber(); - } catch(ArrayIndexOutOfBoundsException e) {} // Never occurs - - return new LineNumberTable(cp.addUtf8("LineNumberTable"), - 2 + ln.length * 4, ln, cp.getConstantPool()); - } - - /** - * Add an exception handler, i.e., specify region where a handler is active and an - * instruction where the actual handling is done. - * - * @param start_pc Start of region (inclusive) - * @param end_pc End of region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type class type of handled exception or null if any - * exception is handled - * @return new exception handler object - */ - public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc, - InstructionHandle end_pc, - InstructionHandle handler_pc, - ObjectType catch_type) { - if((start_pc == null) || (end_pc == null) || (handler_pc == null)) - throw new ClassGenException("Exception handler target is null instruction"); - - CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, - handler_pc, catch_type); - exception_vec.add(c); - return c; - } - - /** - * Remove an exception handler. - */ - public void removeExceptionHandler(CodeExceptionGen c) { - exception_vec.remove(c); - } - - /** - * Remove all line numbers. - */ - public void removeExceptionHandlers() { - exception_vec.clear(); - } - - /* - * @return array of declared exception handlers - */ - public CodeExceptionGen[] getExceptionHandlers() { - CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()]; - exception_vec.toArray(cg); - return cg; - } - - /** - * @return code exceptions for `Code' attribute - */ - private CodeException[] getCodeExceptions() { - int size = exception_vec.size(); - CodeException[] c_exc = new CodeException[size]; - - try { - for(int i=0; i < size; i++) { - CodeExceptionGen c = (CodeExceptionGen)exception_vec.get(i); - c_exc[i] = c.getCodeException(cp); - } - } catch(ArrayIndexOutOfBoundsException e) {} - - return c_exc; - } - - /** - * Add an exception possibly thrown by this method. - * - * @param class_name (fully qualified) name of exception - */ - public void addException(String class_name) { - throws_vec.add(class_name); - } - - /** - * Remove an exception. - */ - public void removeException(String c) { - throws_vec.remove(c); - } - - /** - * Remove all exceptions. - */ - public void removeExceptions() { - throws_vec.clear(); - } - - /* - * @return array of thrown exceptions - */ - public String[] getExceptions() { - String[] e = new String[throws_vec.size()]; - throws_vec.toArray(e); - return e; - } - - /** - * @return `Exceptions' attribute of all the exceptions thrown by this method. - */ - private ExceptionTable getExceptionTable(ConstantPoolGen cp) { - int size = throws_vec.size(); - int[] ex = new int[size]; - - try { - for(int i=0; i < size; i++) - ex[i] = cp.addClass((String)throws_vec.get(i)); - } catch(ArrayIndexOutOfBoundsException e) {} - - return new ExceptionTable(cp.addUtf8("Exceptions"), - 2 + 2 * size, ex, cp.getConstantPool()); - } - - /** - * Add an attribute to the code. Currently, the JVM knows about the - * LineNumberTable, LocalVariableTable and StackMap attributes, - * where the former two will be generated automatically and the - * latter is used for the MIDP only. Other attributes will be - * ignored by the JVM but do no harm. - * - * @param a attribute to be added - */ - public void addCodeAttribute(Attribute a) { code_attrs_vec.add(a); } - - /** - * Remove a code attribute. - */ - public void removeCodeAttribute(Attribute a) { code_attrs_vec.remove(a); } - - /** - * Remove all code attributes. - */ - public void removeCodeAttributes() { - code_attrs_vec.clear(); - } - - /** - * @return all attributes of this method. - */ - public Attribute[] getCodeAttributes() { - Attribute[] attributes = new Attribute[code_attrs_vec.size()]; - code_attrs_vec.toArray(attributes); - return attributes; - } - - /** - * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively, - * before calling this method (the same applies for max locals). - * - * @return method object - */ - public Method getMethod() { - String signature = getSignature(); - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(signature); - - /* Also updates positions of instructions, i.e., their indices - */ - byte[] byte_code = null; - - if(il != null) - byte_code = il.getByteCode(); - - LineNumberTable lnt = null; - LocalVariableTable lvt = null; - LocalVariableTypeTable lvtt = null; - - /* Create LocalVariableTable, LocalvariableTypeTable, and LineNumberTable - * attributes (for debuggers, e.g.) - */ - if((variable_vec.size() > 0) && !strip_attributes) - addCodeAttribute(lvt = getLocalVariableTable(cp)); - - if((type_vec.size() > 0) && !strip_attributes) - addCodeAttribute(lvtt = getLocalVariableTypeTable(cp)); - - if((line_number_vec.size() > 0) && !strip_attributes) - addCodeAttribute(lnt = getLineNumberTable(cp)); - - Attribute[] code_attrs = getCodeAttributes(); - - /* Each attribute causes 6 additional header bytes - */ - int attrs_len = 0; - for(int i=0; i < code_attrs.length; i++) - attrs_len += (code_attrs[i].getLength() + 6); - - CodeException[] c_exc = getCodeExceptions(); - int exc_len = c_exc.length * 8; // Every entry takes 8 bytes - - Code code = null; - - if((il != null) && !isAbstract()) { - // Remove any stale code attribute - Attribute[] attributes = getAttributes(); - for(int i=0; i < attributes.length; i++) { - Attribute a = attributes[i]; - - if(a instanceof Code) - removeAttribute(a); - } - - code = new Code(cp.addUtf8("Code"), - 8 + byte_code.length + // prologue byte code - 2 + exc_len + // exceptions - 2 + attrs_len, // attributes - max_stack, max_locals, - byte_code, c_exc, - code_attrs, - cp.getConstantPool()); - - addAttribute(code); - } - - ExceptionTable et = null; - - if(throws_vec.size() > 0) - addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses - - Method m = new Method(access_flags, name_index, signature_index, - getAttributes(), cp.getConstantPool()); - - // Undo effects of adding attributes - if(lvt != null) removeCodeAttribute(lvt); - if(lvtt != null) removeCodeAttribute(lvtt); - if(lnt != null) removeCodeAttribute(lnt); - if(code != null) removeAttribute(code); - if(et != null) removeAttribute(et); - - return m; - } - - /** - * Remove all NOPs from the instruction list (if possible) and update every - * object refering to them, i.e., branch instructions, local variables and - * exception handlers. - */ - public void removeNOPs() { - if(il != null) { - InstructionHandle next; - /* Check branch instructions. - */ - for(InstructionHandle ih = il.getStart(); ih != null; ih = next) { - next = ih.next; - - if((next != null) && (ih.getInstruction() instanceof NOP)) { - try { - il.delete(ih); - } catch(TargetLostException e) { - InstructionHandle[] targets = e.getTargets(); - - for(int i=0; i < targets.length; i++) { - InstructionTargeter[] targeters = targets[i].getTargeters(); - - for(int j=0; j < targeters.length; j++) - targeters[j].updateTarget(targets[i], next); + if (isLVT) { + addLocalVariableType(l.getName(), Type.getType(l.getSignature()), + l.getIndex(), start, end); + } else { + addLocalVariable(l.getName(), Type.getType(l.getSignature()), + l.getIndex(), start, end); } - } } - } - } - } - - /** - * Set maximum number of local variables. - */ - public void setMaxLocals(int m) { max_locals = m; } - public int getMaxLocals() { return max_locals; } - - /** - * Set maximum stack size for this method. - */ - public void setMaxStack(int m) { max_stack = m; } - public int getMaxStack() { return max_stack; } - - /** @return class that contains this method - */ - public String getClassName() { return class_name; } - public void setClassName(String class_name) { this.class_name = class_name; } - - public void setReturnType(Type return_type) { setType(return_type); } - public Type getReturnType() { return getType(); } - - public void setArgumentTypes(Type[] arg_types) { this.arg_types = arg_types; } - public Type[] getArgumentTypes() { return (Type[])arg_types.clone(); } - public void setArgumentType(int i, Type type) { arg_types[i] = type; } - public Type getArgumentType(int i) { return arg_types[i]; } - - public void setArgumentNames(String[] arg_names) { this.arg_names = arg_names; } - public String[] getArgumentNames() { return (String[])arg_names.clone(); } - public void setArgumentName(int i, String name) { arg_names[i] = name; } - public String getArgumentName(int i) { return arg_names[i]; } - - public InstructionList getInstructionList() { return il; } - public void setInstructionList(InstructionList il) { this.il = il; } - - public String getSignature() { - return Type.getMethodSignature(type, arg_types); - } - - /** - * Computes max. stack size by performing control flow analysis. - */ - public void setMaxStack() { - if(il != null) - max_stack = getMaxStack(cp, il, getExceptionHandlers()); - else - max_stack = 0; - } - - /** - * Compute maximum number of local variables. - */ - public void setMaxLocals() { - if(il != null) { - int max = isStatic()? 0 : 1; - - if(arg_types != null) - for(int i=0; i < arg_types.length; i++) - max += arg_types[i].getSize(); - - for(InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { - Instruction ins = ih.getInstruction(); - - if((ins instanceof LocalVariableInstruction) || - (ins instanceof RET) || (ins instanceof IINC)) - { - int index = ((IndexedInstruction)ins).getIndex() + - ((TypedInstruction)ins).getType(cp).getSize(); - - if(index > max) - max = index; - } - } - - max_locals = max; - } else - max_locals = 0; - } - - /** Do not/Do produce attributes code attributesLineNumberTable and - * LocalVariableTable, like javac -O - */ - public void stripAttributes(boolean flag) { strip_attributes = flag; } - - static final class BranchTarget { - InstructionHandle target; - int stackDepth; - - BranchTarget(InstructionHandle target, int stackDepth) { - this.target = target; - this.stackDepth = stackDepth; - } - } - - static final class BranchStack { - Stack branchTargets = new Stack(); - Hashtable visitedTargets = new Hashtable(); - - public void push(InstructionHandle target, int stackDepth) { - if(visited(target)) - return; - - branchTargets.push(visit(target, stackDepth)); } - public BranchTarget pop() { - if(!branchTargets.empty()) { - BranchTarget bt = (BranchTarget) branchTargets.pop(); - return bt; - } - - return null; - } - - private final BranchTarget visit(InstructionHandle target, int stackDepth) { - BranchTarget bt = new BranchTarget(target, stackDepth); - visitedTargets.put(target, bt); - - return bt; - } - - private final boolean visited(InstructionHandle target) { - return (visitedTargets.get(target) != null); - } - } - - /** - * Computes stack usage of an instruction list by performing control flow analysis. - * - * @return maximum stack depth used by method - */ - public static int getMaxStack(ConstantPoolGen cp, InstructionList il, CodeExceptionGen[] et) { - BranchStack branchTargets = new BranchStack(); - - /* Initially, populate the branch stack with the exception - * handlers, because these aren't (necessarily) branched to - * explicitly. in each case, the stack will have depth 1, - * containing the exception object. + /** + * Adds a local variable to this method. + * + * @param name variable name + * @param type variable type + * @param slot the index of the local variable, if type is long or double, + * the next available index is slot+2 + * @param start from where the variable is valid + * @param end until where the variable is valid + * @return new local variable object + * @see LocalVariable */ - for (int i = 0; i < et.length; i++) { - InstructionHandle handler_pc = et[i].getHandlerPC(); - if (handler_pc != null) - branchTargets.push(handler_pc, 1); - } + public LocalVariableGen addLocalVariable(final String name, final Type type, final int slot, + final InstructionHandle start, final InstructionHandle end) { - int stackDepth = 0, maxStackDepth = 0; - InstructionHandle ih = il.getStart(); - - while(ih != null) { - Instruction instruction = ih.getInstruction(); - short opcode = instruction.getOpcode(); - int delta = instruction.produceStack(cp) - instruction.consumeStack(cp); - - stackDepth += delta; - if(stackDepth > maxStackDepth) - maxStackDepth = stackDepth; - - // choose the next instruction based on whether current is a branch. - if(instruction instanceof BranchInstruction) { - BranchInstruction branch = (BranchInstruction) instruction; - if(instruction instanceof Select) { - // explore all of the select's targets. the default target is handled below. - Select select = (Select) branch; - InstructionHandle[] targets = select.getTargets(); - for (int i = 0; i < targets.length; i++) - branchTargets.push(targets[i], stackDepth); - // nothing to fall through to. - ih = null; - } else if(!(branch instanceof IfInstruction)) { - // if an instruction that comes back to following PC, - // push next instruction, with stack depth reduced by 1. - if(opcode == Constants.JSR || opcode == Constants.JSR_W) - branchTargets.push(ih.getNext(), stackDepth - 1); - ih = null; + final byte t = type.getType(); + if (t != Const.T_ADDRESS) { + final int add = type.getSize(); + if (slot + add > max_locals) { + max_locals = slot + add; + } + final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); + int i; + if ((i = variable_vec.indexOf(l)) >= 0) { + variable_vec.set(i, l); + } else { + variable_vec.add(l); + } + return l; } - // for all branches, the target of the branch is pushed on the branch stack. - // conditional branches have a fall through case, selects don't, and - // jsr/jsr_w return to the next instruction. - branchTargets.push(branch.getTarget(), stackDepth); - } else { - // check for instructions that terminate the method. - if(opcode == Constants.ATHROW || opcode == Constants.RET || - (opcode >= Constants.IRETURN && opcode <= Constants.RETURN)) - ih = null; - } - // normal case, go to the next instruction. - if(ih != null) - ih = ih.getNext(); - // if we have no more instructions, see if there are any deferred branches to explore. - if(ih == null) { - BranchTarget bt = branchTargets.pop(); - if (bt != null) { - ih = bt.target; - stackDepth = bt.stackDepth; + throw new IllegalArgumentException("Can not use " + type + + " as type for local variable"); + } + + /** + * Adds a local variable to this method and assigns an index automatically. + * + * @param name variable name + * @param type variable type + * @param start from where the variable is valid, if this is null, it is + * valid from the start + * @param end until where the variable is valid, if this is null, it is + * valid to the end + * @return new local variable object + * @see LocalVariable + */ + public LocalVariableGen addLocalVariable(final String name, final Type type, + final InstructionHandle start, final InstructionHandle end) { + return addLocalVariable(name, type, max_locals, start, end); + } + + /** + * Remove a local variable, its slot will not be reused, if you do not use + * addLocalVariable with an explicit index argument. + */ + public void removeLocalVariable(final LocalVariableGen l) { + variable_vec.remove(l); + } + + /** + * Remove all local variables. + */ + public void removeLocalVariables() { + variable_vec.clear(); + } + + /* + * If the range of the variable has not been set yet, it will be set to be valid from + * the start to the end of the instruction list. + * + * @return array of declared local variables sorted by index + */ + public LocalVariableGen[] getLocalVariables() { + return getLocalVariableOrTypes(false); + } + + /* + * If the range of the variable has not been set yet, it will be set to be + * valid from the start to the end of the instruction list. + * + * @return array of declared local variable types sorted by index + */ + private LocalVariableGen[] getLocalVariableTypes() { + return getLocalVariableOrTypes(true); + } + + /* + * If the range of the variable or type has not been set yet, it will be set + * to be valid from the start to the end of the instruction list. + * + * @return array of declared local variables or types sorted by index + */ + private LocalVariableGen[] getLocalVariableOrTypes(boolean isLVT) { + int size = (isLVT) ? type_vec.size() : variable_vec.size(); + LocalVariableGen[] lg = new LocalVariableGen[size]; + if (isLVT) { + type_vec.toArray(lg); + } else { + variable_vec.toArray(lg); } - } + + for (int i = 0; i < size; i++) { + if (lg[i].getStart() == null) { + lg[i].setStart(il.getStart()); + } + + if (lg[i].getEnd() == null) { + lg[i].setEnd(il.getEnd()); + } + } + + if (size > 1) { + Arrays.sort(lg, new Comparator() { + @Override + public int compare(final LocalVariableGen o1, final LocalVariableGen o2) { + return o1.getIndex() - o2.getIndex(); + } + }); + } + + return lg; } - return maxStackDepth; - } - - private ArrayList observers; - - /** Add observer for this object. - */ - public void addObserver(MethodObserver o) { - if(observers == null) - observers = new ArrayList(); - - observers.add(o); - } - - /** Remove observer for this object. - */ - public void removeObserver(MethodObserver o) { - if(observers != null) - observers.remove(o); - } - - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if(observers != null) - for(Iterator e = observers.iterator(); e.hasNext(); ) - ((MethodObserver)e.next()).notify(this); - } - - /** - * Return string representation close to declaration format, - * `public static void _main(String[]) throws IOException', e.g. - * - * @return String representation of the method. - */ - public final String toString() { - String access = Utility.accessToString(access_flags); - String signature = Type.getMethodSignature(type, arg_types); - - signature = Utility.methodSignatureToString(signature, name, access, - true, getLocalVariableTable(cp)); - - StringBuffer buf = new StringBuffer(signature); - - if(throws_vec.size() > 0) { - for(Iterator e = throws_vec.iterator(); e.hasNext(); ) - buf.append("\n\t\tthrows " + e.next()); + /** + * @return `LocalVariableTable' attribute of all the local variables of this + * method. + */ + public LocalVariableTable getLocalVariableTable(final ConstantPoolGen cp) { + final LocalVariableGen[] lg = getLocalVariables(); + final int size = lg.length; + final LocalVariable[] lv = new LocalVariable[size]; + for (int i = 0; i < size; i++) { + lv[i] = lg[i].getLocalVariable(cp); + } + return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp + .getConstantPool()); } - return buf.toString(); - } + /** + * @return `LocalVariableTypeTable' attribute of all the local variable + * types of this method. + */ + public LocalVariableTypeTable getLocalVariableTypeTable(ConstantPoolGen cp) { + LocalVariableGen[] lg = getLocalVariableTypes(); + int size = lg.length; + LocalVariable[] lv = new LocalVariable[size]; - /** @return deep copy of this method - */ - public MethodGen copy(String class_name, ConstantPoolGen cp) { - Method m = ((MethodGen)clone()).getMethod(); - MethodGen mg = new MethodGen(m, class_name, this.cp); + for (int i = 0; i < size; i++) { + lv[i] = lg[i].getLocalVariable(cp); + } - if(this.cp != cp) { - mg.setConstantPool(cp); - mg.getInstructionList().replaceConstantPool(this.cp, cp); + return new LocalVariableTypeTable(cp.addUtf8("LocalVariableTypeTable"), + 2 + lv.length * 10, lv, cp.getConstantPool()); } - return mg; - } + /** + * Adds a local variable type to this method. + * + * @param name variable name + * @param type variable type + * @param slot the index of the local variable, if type is long or double, + * the next available index is slot+2 + * @param start from where the variable is valid + * @param end until where the variable is valid + * @return new local variable object + * @see LocalVariable + */ + private LocalVariableGen addLocalVariableType(String name, Type type, int slot, + InstructionHandle start, + InstructionHandle end) { + byte t = type.getType(); + + if (t != Const.T_ADDRESS) { + int add = type.getSize(); + + if (slot + add > max_locals) { + max_locals = slot + add; + } + + LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); + int i; + + if ((i = type_vec.indexOf(l)) >= 0) // Overwrite if necessary + { + type_vec.set(i, l); + } else { + type_vec.add(l); + } + + return l; + } else { + throw new IllegalArgumentException("Can not use " + type + + " as type for local variable"); + } + } + + /** + * Remove all local variable types. + */ + private void removeLocalVariableTypes() { + type_vec.clear(); + } + + /** + * Give an instruction a line number corresponding to the source code line. + * + * @param ih instruction to tag + * @return new line number object + * @see LineNumber + */ + public LineNumberGen addLineNumber(final InstructionHandle ih, final int src_line) { + final LineNumberGen l = new LineNumberGen(ih, src_line); + line_number_vec.add(l); + return l; + } + + /** + * Remove a line number. + */ + public void removeLineNumber(final LineNumberGen l) { + line_number_vec.remove(l); + } + + /** + * Remove all line numbers. + */ + public void removeLineNumbers() { + line_number_vec.clear(); + } + + /* + * @return array of line numbers + */ + public LineNumberGen[] getLineNumbers() { + final LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()]; + line_number_vec.toArray(lg); + return lg; + } + + /** + * @return `LineNumberTable' attribute of all the local variables of this + * method. + */ + public LineNumberTable getLineNumberTable(final ConstantPoolGen cp) { + final int size = line_number_vec.size(); + final LineNumber[] ln = new LineNumber[size]; + for (int i = 0; i < size; i++) { + ln[i] = line_number_vec.get(i).getLineNumber(); + } + return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp + .getConstantPool()); + } + + /** + * Add an exception handler, i.e., specify region where a handler is active + * and an instruction where the actual handling is done. + * + * @param start_pc Start of region (inclusive) + * @param end_pc End of region (inclusive) + * @param handler_pc Where handling is done + * @param catch_type class type of handled exception or null if any + * exception is handled + * @return new exception handler object + */ + public CodeExceptionGen addExceptionHandler(final InstructionHandle start_pc, + final InstructionHandle end_pc, final InstructionHandle handler_pc, final ObjectType catch_type) { + if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) { + throw new ClassGenException("Exception handler target is null instruction"); + } + final CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type); + exception_vec.add(c); + return c; + } + + /** + * Remove an exception handler. + */ + public void removeExceptionHandler(final CodeExceptionGen c) { + exception_vec.remove(c); + } + + /** + * Remove all line numbers. + */ + public void removeExceptionHandlers() { + exception_vec.clear(); + } + + /* + * @return array of declared exception handlers + */ + public CodeExceptionGen[] getExceptionHandlers() { + final CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()]; + exception_vec.toArray(cg); + return cg; + } + + /** + * @return code exceptions for `Code' attribute + */ + private CodeException[] getCodeExceptions() { + final int size = exception_vec.size(); + final CodeException[] c_exc = new CodeException[size]; + for (int i = 0; i < size; i++) { + final CodeExceptionGen c = exception_vec.get(i); + c_exc[i] = c.getCodeException(super.getConstantPool()); + } + return c_exc; + } + + /** + * Add an exception possibly thrown by this method. + * + * @param class_name (fully qualified) name of exception + */ + public void addException(final String class_name) { + throws_vec.add(class_name); + } + + /** + * Remove an exception. + */ + public void removeException(final String c) { + throws_vec.remove(c); + } + + /** + * Remove all exceptions. + */ + public void removeExceptions() { + throws_vec.clear(); + } + + /* + * @return array of thrown exceptions + */ + public String[] getExceptions() { + final String[] e = new String[throws_vec.size()]; + throws_vec.toArray(e); + return e; + } + + /** + * @return `Exceptions' attribute of all the exceptions thrown by this + * method. + */ + private ExceptionTable getExceptionTable(final ConstantPoolGen cp) { + final int size = throws_vec.size(); + final int[] ex = new int[size]; + for (int i = 0; i < size; i++) { + ex[i] = cp.addClass(throws_vec.get(i)); + } + return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp.getConstantPool()); + } + + /** + * Add an attribute to the code. Currently, the JVM knows about the + * LineNumberTable, LocalVariableTable and StackMap attributes, where the + * former two will be generated automatically and the latter is used for the + * MIDP only. Other attributes will be ignored by the JVM but do no harm. + * + * @param a attribute to be added + */ + public void addCodeAttribute(final Attribute a) { + code_attrs_vec.add(a); + } + + /** + * Remove a code attribute. + */ + public void removeCodeAttribute(final Attribute a) { + code_attrs_vec.remove(a); + } + + /** + * Remove all code attributes. + */ + public void removeCodeAttributes() { + code_attrs_vec.clear(); + } + + /** + * @return all attributes of this method. + */ + public Attribute[] getCodeAttributes() { + final Attribute[] attributes = new Attribute[code_attrs_vec.size()]; + code_attrs_vec.toArray(attributes); + return attributes; + } + + /** + * @since 6.0 + */ + public void addAnnotationsAsAttribute(final ConstantPoolGen cp) { + final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); + for (final Attribute attr : attrs) { + addAttribute(attr); + } + } + + /** + * @since 6.0 + */ + public void addParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { + if (!hasParameterAnnotations) { + return; + } + final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, param_annotations); + if (attrs != null) { + for (final Attribute attr : attrs) { + addAttribute(attr); + } + } + } + + /** + * Get method object. Never forget to call setMaxStack() or + * setMaxStack(max), respectively, before calling this method (the same + * applies for max locals). + * + * @return method object + */ + public Method getMethod() { + final String signature = getSignature(); + final ConstantPoolGen _cp = super.getConstantPool(); + final int name_index = _cp.addUtf8(super.getName()); + final int signature_index = _cp.addUtf8(signature); + /* Also updates positions of instructions, i.e., their indices + */ + byte[] byte_code = null; + if (il != null) { + byte_code = il.getByteCode(); + } + LineNumberTable lnt = null; + LocalVariableTable lvt = null; + LocalVariableTypeTable lvtt = null; + + /* Create LocalVariableTable, LocalvariableTypeTable, and LineNumberTable + * attributes (for debuggers, e.g.) + */ + if ((variable_vec.size() > 0) && !strip_attributes) { + addCodeAttribute(lvt = getLocalVariableTable(_cp)); + } + + if ((type_vec.size() > 0) && !strip_attributes) { + addCodeAttribute(lvtt = getLocalVariableTypeTable(_cp)); + } + + if ((line_number_vec.size() > 0) && !strip_attributes) { + addCodeAttribute(lnt = getLineNumberTable(_cp)); + } + final Attribute[] code_attrs = getCodeAttributes(); + /* Each attribute causes 6 additional header bytes + */ + int attrs_len = 0; + for (final Attribute code_attr : code_attrs) { + attrs_len += code_attr.getLength() + 6; + } + final CodeException[] c_exc = getCodeExceptions(); + final int exc_len = c_exc.length * 8; // Every entry takes 8 bytes + Code code = null; + if ((il != null) && !isAbstract() && !isNative()) { + // Remove any stale code attribute + final Attribute[] attributes = getAttributes(); + for (final Attribute a : attributes) { + if (a instanceof Code) { + removeAttribute(a); + } + } + code = new Code(_cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code + 2 + exc_len + // exceptions + 2 + attrs_len, // attributes + max_stack, max_locals, byte_code, c_exc, code_attrs, _cp.getConstantPool()); + addAttribute(code); + } + addAnnotationsAsAttribute(_cp); + addParameterAnnotationsAsAttribute(_cp); + ExceptionTable et = null; + if (throws_vec.size() > 0) { + addAttribute(et = getExceptionTable(_cp)); + // Add `Exceptions' if there are "throws" clauses + } + final Method m = new Method(super.getAccessFlags(), name_index, signature_index, getAttributes(), _cp + .getConstantPool()); + // Undo effects of adding attributes + if (lvt != null) { + removeCodeAttribute(lvt); + } + if (lvtt != null) { + removeCodeAttribute(lvtt); + } + if (lnt != null) { + removeCodeAttribute(lnt); + } + if (code != null) { + removeAttribute(code); + } + if (et != null) { + removeAttribute(et); + } + return m; + } + + /** + * Remove all NOPs from the instruction list (if possible) and update every + * object referring to them, i.e., branch instructions, local variables and + * exception handlers. + */ + public void removeNOPs() { + if (il != null) { + InstructionHandle next; + /* Check branch instructions. + */ + for (InstructionHandle ih = il.getStart(); ih != null; ih = next) { + next = ih.getNext(); + if ((next != null) && (ih.getInstruction() instanceof NOP)) { + try { + il.delete(ih); + } catch (final TargetLostException e) { + for (final InstructionHandle target : e.getTargets()) { + for (final InstructionTargeter targeter : target.getTargeters()) { + targeter.updateTarget(target, next); + } + } + } + } + } + } + } + + /** + * Set maximum number of local variables. + */ + public void setMaxLocals(final int m) { + max_locals = m; + } + + public int getMaxLocals() { + return max_locals; + } + + /** + * Set maximum stack size for this method. + */ + public void setMaxStack(final int m) { // TODO could be package-protected? + max_stack = m; + } + + public int getMaxStack() { + return max_stack; + } + + /** + * @return class that contains this method + */ + public String getClassName() { + return class_name; + } + + public void setClassName(final String class_name) { // TODO could be package-protected? + this.class_name = class_name; + } + + public void setReturnType(final Type return_type) { + setType(return_type); + } + + public Type getReturnType() { + return getType(); + } + + public void setArgumentTypes(final Type[] arg_types) { + this.arg_types = arg_types; + } + + public Type[] getArgumentTypes() { + return arg_types.clone(); + } + + public void setArgumentType(final int i, final Type type) { + arg_types[i] = type; + } + + public Type getArgumentType(final int i) { + return arg_types[i]; + } + + public void setArgumentNames(final String[] arg_names) { + this.arg_names = arg_names; + } + + public String[] getArgumentNames() { + return arg_names.clone(); + } + + public void setArgumentName(final int i, final String name) { + arg_names[i] = name; + } + + public String getArgumentName(final int i) { + return arg_names[i]; + } + + public InstructionList getInstructionList() { + return il; + } + + public void setInstructionList(final InstructionList il) { // TODO could be package-protected? + this.il = il; + } + + @Override + public String getSignature() { + return Type.getMethodSignature(super.getType(), arg_types); + } + + /** + * Computes max. stack size by performing control flow analysis. + */ + public void setMaxStack() { // TODO could be package-protected? (some tests would need repackaging) + if (il != null) { + max_stack = getMaxStack(super.getConstantPool(), il, getExceptionHandlers()); + } else { + max_stack = 0; + } + } + + /** + * Compute maximum number of local variables. + */ + public void setMaxLocals() { // TODO could be package-protected? (some tests would need repackaging) + if (il != null) { + int max = isStatic() ? 0 : 1; + if (arg_types != null) { + for (final Type arg_type : arg_types) { + max += arg_type.getSize(); + } + } + for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { + final Instruction ins = ih.getInstruction(); + if ((ins instanceof LocalVariableInstruction) || (ins instanceof RET) + || (ins instanceof IINC)) { + final int index = ((IndexedInstruction) ins).getIndex() + + ((TypedInstruction) ins).getType(super.getConstantPool()).getSize(); + if (index > max) { + max = index; + } + } + } + max_locals = max; + } else { + max_locals = 0; + } + } + + /** + * Do not/Do produce attributes code attributesLineNumberTable and + * LocalVariableTable, like javac -O + */ + public void stripAttributes(final boolean flag) { + strip_attributes = flag; + } + + static final class BranchTarget { + + final InstructionHandle target; + final int stackDepth; + + BranchTarget(final InstructionHandle target, final int stackDepth) { + this.target = target; + this.stackDepth = stackDepth; + } + } + + static final class BranchStack { + + private final Stack branchTargets = new Stack<>(); + private final Map visitedTargets = new HashMap<>(); + + public void push(final InstructionHandle target, final int stackDepth) { + if (visited(target)) { + return; + } + branchTargets.push(visit(target, stackDepth)); + } + + public BranchTarget pop() { + if (!branchTargets.empty()) { + final BranchTarget bt = branchTargets.pop(); + return bt; + } + return null; + } + + private BranchTarget visit(final InstructionHandle target, final int stackDepth) { + final BranchTarget bt = new BranchTarget(target, stackDepth); + visitedTargets.put(target, bt); + return bt; + } + + private boolean visited(final InstructionHandle target) { + return visitedTargets.get(target) != null; + } + } + + /** + * Computes stack usage of an instruction list by performing control flow + * analysis. + * + * @return maximum stack depth used by method + */ + public static int getMaxStack(final ConstantPoolGen cp, final InstructionList il, + final CodeExceptionGen[] et) { + final BranchStack branchTargets = new BranchStack(); + /* Initially, populate the branch stack with the exception + * handlers, because these aren't (necessarily) branched to + * explicitly. in each case, the stack will have depth 1, + * containing the exception object. + */ + for (final CodeExceptionGen element : et) { + final InstructionHandle handler_pc = element.getHandlerPC(); + if (handler_pc != null) { + branchTargets.push(handler_pc, 1); + } + } + int stackDepth = 0; + int maxStackDepth = 0; + InstructionHandle ih = il.getStart(); + while (ih != null) { + final Instruction instruction = ih.getInstruction(); + final short opcode = instruction.getOpcode(); + final int delta = instruction.produceStack(cp) - instruction.consumeStack(cp); + stackDepth += delta; + if (stackDepth > maxStackDepth) { + maxStackDepth = stackDepth; + } + // choose the next instruction based on whether current is a branch. + if (instruction instanceof BranchInstruction) { + final BranchInstruction branch = (BranchInstruction) instruction; + if (instruction instanceof Select) { + // explore all of the select's targets. the default target is handled below. + final Select select = (Select) branch; + final InstructionHandle[] targets = select.getTargets(); + for (final InstructionHandle target : targets) { + branchTargets.push(target, stackDepth); + } + // nothing to fall through to. + ih = null; + } else if (!(branch instanceof IfInstruction)) { + // if an instruction that comes back to following PC, + // push next instruction, with stack depth reduced by 1. + if (opcode == Const.JSR || opcode == Const.JSR_W) { + branchTargets.push(ih.getNext(), stackDepth - 1); + } + ih = null; + } + // for all branches, the target of the branch is pushed on the branch stack. + // conditional branches have a fall through case, selects don't, and + // jsr/jsr_w return to the next instruction. + branchTargets.push(branch.getTarget(), stackDepth); + } else { + // check for instructions that terminate the method. + if (opcode == Const.ATHROW || opcode == Const.RET + || (opcode >= Const.IRETURN && opcode <= Const.RETURN)) { + ih = null; + } + } + // normal case, go to the next instruction. + if (ih != null) { + ih = ih.getNext(); + } + // if we have no more instructions, see if there are any deferred branches to explore. + if (ih == null) { + final BranchTarget bt = branchTargets.pop(); + if (bt != null) { + ih = bt.target; + stackDepth = bt.stackDepth; + } + } + } + return maxStackDepth; + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(final MethodObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(final MethodObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (final MethodObserver observer : observers) { + observer.notify(this); + } + } + } + + /** + * Return string representation close to declaration format, e.g. public + * static void main(String[]) throws IOException' + * + * @return String representation of the method. + */ + @Override + public final String toString() { + final String access = Utility.accessToString(super.getAccessFlags()); + String signature = Type.getMethodSignature(super.getType(), arg_types); + signature = Utility.methodSignatureToString(signature, super.getName(), access, true, + getLocalVariableTable(super.getConstantPool())); + final StringBuilder buf = new StringBuilder(signature); + for (final Attribute a : getAttributes()) { + if (!((a instanceof Code) || (a instanceof ExceptionTable))) { + buf.append(" [").append(a).append("]"); + } + } + + if (throws_vec.size() > 0) { + for (final String throwsDescriptor : throws_vec) { + buf.append("\n\t\tthrows ").append(throwsDescriptor); + } + } + return buf.toString(); + } + + /** + * @return deep copy of this method + */ + public MethodGen copy(final String class_name, final ConstantPoolGen cp) { + final Method m = ((MethodGen) clone()).getMethod(); + final MethodGen mg = new MethodGen(m, class_name, super.getConstantPool()); + if (super.getConstantPool() != cp) { + mg.setConstantPool(cp); + mg.getInstructionList().replaceConstantPool(super.getConstantPool(), cp); + } + return mg; + } + + //J5TODO: Should param_annotations be an array of arrays? Rather than an array of lists, this + // is more likely to suggest to the caller it is readonly (which a List does not). + /** + * Return a list of AnnotationGen objects representing parameter annotations + * + * @since 6.0 + */ + public List getAnnotationsOnParameter(final int i) { + ensureExistingParameterAnnotationsUnpacked(); + if (!hasParameterAnnotations || i > arg_types.length) { + return null; + } + return param_annotations[i]; + } + + /** + * Goes through the attributes on the method and identifies any that are + * RuntimeParameterAnnotations, extracting their contents and storing them + * as parameter annotations. There are two kinds of parameter annotation - + * visible and invisible. Once they have been unpacked, these attributes are + * deleted. (The annotations will be rebuilt as attributes when someone + * builds a Method object out of this MethodGen object). + */ + private void ensureExistingParameterAnnotationsUnpacked() { + if (haveUnpackedParameterAnnotations) { + return; + } + // Find attributes that contain parameter annotation data + final Attribute[] attrs = getAttributes(); + ParameterAnnotations paramAnnVisAttr = null; + ParameterAnnotations paramAnnInvisAttr = null; + for (final Attribute attribute : attrs) { + if (attribute instanceof ParameterAnnotations) { + // Initialize param_annotations + if (!hasParameterAnnotations) { + @SuppressWarnings("unchecked") // OK + final List[] parmList = new List[arg_types.length]; + param_annotations = parmList; + for (int j = 0; j < arg_types.length; j++) { + param_annotations[j] = new ArrayList<>(); + } + } + hasParameterAnnotations = true; + final ParameterAnnotations rpa = (ParameterAnnotations) attribute; + if (rpa instanceof RuntimeVisibleParameterAnnotations) { + paramAnnVisAttr = rpa; + } else { + paramAnnInvisAttr = rpa; + } + for (int j = 0; j < arg_types.length; j++) { + // This returns Annotation[] ... + final ParameterAnnotationEntry immutableArray = rpa + .getParameterAnnotationEntries()[j]; + // ... which needs transforming into an AnnotationGen[] ... + final List mutable + = makeMutableVersion(immutableArray.getAnnotationEntries()); + // ... then add these to any we already know about + param_annotations[j].addAll(mutable); + } + } + } + if (paramAnnVisAttr != null) { + removeAttribute(paramAnnVisAttr); + } + if (paramAnnInvisAttr != null) { + removeAttribute(paramAnnInvisAttr); + } + haveUnpackedParameterAnnotations = true; + } + + private List makeMutableVersion(final AnnotationEntry[] mutableArray) { + final List result = new ArrayList<>(); + for (final AnnotationEntry element : mutableArray) { + result.add(new AnnotationEntryGen(element, getConstantPool(), + false)); + } + return result; + } + + public void addParameterAnnotation(final int parameterIndex, + final AnnotationEntryGen annotation) { + ensureExistingParameterAnnotationsUnpacked(); + if (!hasParameterAnnotations) { + @SuppressWarnings("unchecked") // OK + final List[] parmList = new List[arg_types.length]; + param_annotations = parmList; + hasParameterAnnotations = true; + } + final List existingAnnotations = param_annotations[parameterIndex]; + if (existingAnnotations != null) { + existingAnnotations.add(annotation); + } else { + final List l = new ArrayList<>(); + l.add(annotation); + param_annotations[parameterIndex] = l; + } + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * MethodGen objects are said to be equal when their names and signatures + * are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the method's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java index c50acc69558..ac22de9153c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Implement this interface if you're interested in changes to a MethodGen object * and register yourself with addObserver(). * - * @author M. Dahm + * @version $Id: MethodObserver.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface MethodObserver { - public void notify(MethodGen method); + + void notify( MethodGen method ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java index 9fd3014caa1..c30cdba6012 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java @@ -21,58 +21,60 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * NEW - Create new object *
    Stack: ... -> ..., objectref
    * - * @author M. Dahm + * @version $Id: NEW.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class NEW extends CPInstruction - implements LoadClass, AllocationInstruction, ExceptionThrower, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - NEW() {} +public class NEW extends CPInstruction implements LoadClass, AllocationInstruction, + ExceptionThrower, StackProducer { - public NEW(int index) { - super(com.sun.org.apache.bcel.internal.Constants.NEW, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + NEW() { + } - public Class[] getExceptions(){ - Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); + public NEW(final int index) { + super(com.sun.org.apache.bcel.internal.Const.NEW, index); + } - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length+1] = ExceptionConstants.INSTANTIATION_ERROR; - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - return cs; - } + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, + ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.INSTANTIATION_ERROR); + } - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - return (ObjectType)getType(cpg); - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitNEW(this); - } + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + return (ObjectType) getType(cpg); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitNEW(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java index dbf157d847a..8e26d2efed3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java @@ -21,7 +21,10 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.ExceptionConst; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -29,79 +32,100 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; *
    Stack: ..., count -> ..., arrayref
    * type must be one of T_INT, T_SHORT, ... * - * @author M. Dahm + * @version $Id: NEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class NEWARRAY extends Instruction - implements AllocationInstruction, ExceptionThrower, StackProducer { - private byte type; +public class NEWARRAY extends Instruction implements AllocationInstruction, ExceptionThrower, + StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - NEWARRAY() {} + private byte type; - public NEWARRAY(byte type) { - super(com.sun.org.apache.bcel.internal.Constants.NEWARRAY, (short)2); - this.type = type; - } - public NEWARRAY(BasicType type) { - this(type.getType()); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + NEWARRAY() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeByte(type); - } - /** - * @return numeric code for basic element type - */ - public final byte getTypecode() { return type; } + public NEWARRAY(final byte type) { + super(com.sun.org.apache.bcel.internal.Const.NEWARRAY, (short) 2); + this.type = type; + } - /** - * @return type of constructed array - */ - public final Type getType() { - return new ArrayType(BasicType.getType(type), 1); - } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + com.sun.org.apache.bcel.internal.Constants.TYPE_NAMES[type]; - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - type = bytes.readByte(); - length = 2; - } + public NEWARRAY(final BasicType type) { + this(type.getType()); + } - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION }; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitNEWARRAY(this); - } + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeByte(type); + } + + + /** + * @return numeric code for basic element type + */ + public final byte getTypecode() { + return type; + } + + + /** + * @return type of constructed array + */ + public final Type getType() { + return new ArrayType(BasicType.getType(type), 1); + } + + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + com.sun.org.apache.bcel.internal.Const.getTypeName(type); + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + type = bytes.readByte(); + super.setLength(2); + } + + + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitNEWARRAY(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java index 8dec0dafbff..785e4e67575 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java @@ -21,27 +21,28 @@ package com.sun.org.apache.bcel.internal.generic; - /** * NOP - Do nothing * - * @author M. Dahm + * @version $Id: NOP.java 1747278 2016-06-07 17:28:43Z britter $ */ public class NOP extends Instruction { - public NOP() { - super(com.sun.org.apache.bcel.internal.Constants.NOP, (short)1); - } + + public NOP() { + super(com.sun.org.apache.bcel.internal.Const.NOP, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitNOP(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitNOP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java new file mode 100644 index 00000000000..1e8398f7437 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java @@ -0,0 +1,67 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import com.sun.org.apache.bcel.internal.classfile.ConstantCP; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; + +/** + * Super class for FieldOrMethod and INVOKEDYNAMIC, since they both have + * names and signatures + * + * @version $Id: FieldOrMethod.java 1481383 2013-05-11 17:34:32Z dbrosius $ + * @since 6.0 + */ +public abstract class NameSignatureInstruction extends CPInstruction { + + public NameSignatureInstruction() { + super(); + } + + public NameSignatureInstruction(final short opcode, final int index) { + super(opcode, index); + } + + public ConstantNameAndType getNameAndType(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + return (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + } + /** @return signature of referenced method/field. + */ + public String getSignature(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantNameAndType cnat = getNameAndType(cpg); + return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); + } + + /** @return name of referenced method/field. + */ + public String getName(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantNameAndType cnat = getNameAndType(cpg); + return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); + } + +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java index 006d6dffd70..14f5d3cbd77 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java @@ -21,17 +21,22 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote entity that has both name and type. This is true for local variables, * methods and fields. * - * @author M. Dahm + * @version $Id: NamedAndTyped.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface NamedAndTyped { - public String getName(); - public Type getType(); - public void setName(String name); - public void setType(Type type); + String getName(); + + + Type getType(); + + + void setName( String name ); + + + void setType( Type type ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java index d3af662a1fc..76cc31eb8f0 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java @@ -21,83 +21,148 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** * Denotes reference such as java.lang.String. * - * @author M. Dahm + * @version $Id: ObjectType.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public final class ObjectType extends ReferenceType { - private String class_name; // Class name of type +public class ObjectType extends ReferenceType { - /** - * @param class_name fully qualified class name, e.g. java.lang.String - */ - public ObjectType(String class_name) { - super(Constants.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); - this.class_name = class_name.replace('/', '.'); - } + private final String class_name; // Class name of type - /** @return name of referenced class - */ - public String getClassName() { return class_name; } - - /** @return a hash code value for the object. - */ - public int hashCode() { return class_name.hashCode(); } - - /** @return true if both type objects refer to the same class. - */ - public boolean equals(Object type) { - return (type instanceof ObjectType)? - ((ObjectType)type).class_name.equals(class_name) : false; - } - - /** - * If "this" doesn't reference a class, it references an interface - * or a non-existant entity. - */ - public boolean referencesClass(){ - JavaClass jc = Repository.lookupClass(class_name); - if (jc == null) - return false; - else - return jc.isClass(); - } - - /** - * If "this" doesn't reference an interface, it references a class - * or a non-existant entity. - */ - public boolean referencesInterface(){ - JavaClass jc = Repository.lookupClass(class_name); - if (jc == null) - return false; - else - return !jc.isClass(); - } - - public boolean subclassOf(ObjectType superclass){ - if (this.referencesInterface() || superclass.referencesInterface()) - return false; - - return Repository.instanceOf(this.class_name, superclass.class_name); - } - - /** - * Java Virtual Machine Specification edition 2, 5.4.4 Access Control - */ - public boolean accessibleTo(ObjectType accessor) { - JavaClass jc = Repository.lookupClass(class_name); - - if(jc.isPublic()) { - return true; - } else { - JavaClass acc = Repository.lookupClass(accessor.class_name); - return acc.getPackageName().equals(jc.getPackageName()); + /** + * @since 6.0 + */ + public static ObjectType getInstance(final String class_name) { + return new ObjectType(class_name); + } + + /** + * @param class_name fully qualified class name, e.g. java.lang.String + */ + public ObjectType(final String class_name) { + super(Const.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); + this.class_name = class_name.replace('/', '.'); + } + + + /** @return name of referenced class + */ + public String getClassName() { + return class_name; + } + + + /** @return a hash code value for the object. + */ + @Override + public int hashCode() { + return class_name.hashCode(); + } + + + /** @return true if both type objects refer to the same class. + */ + @Override + public boolean equals( final Object type ) { + return (type instanceof ObjectType) + ? ((ObjectType) type).class_name.equals(class_name) + : false; + } + + + /** + * If "this" doesn't reference a class, it references an interface + * or a non-existant entity. + * @deprecated (since 6.0) this method returns an inaccurate result + * if the class or interface referenced cannot + * be found: use referencesClassExact() instead + */ + @Deprecated + public boolean referencesClass() { + try { + final JavaClass jc = Repository.lookupClass(class_name); + return jc.isClass(); + } catch (final ClassNotFoundException e) { + return false; + } + } + + + /** + * If "this" doesn't reference an interface, it references a class + * or a non-existant entity. + * @deprecated (since 6.0) this method returns an inaccurate result + * if the class or interface referenced cannot + * be found: use referencesInterfaceExact() instead + */ + @Deprecated + public boolean referencesInterface() { + try { + final JavaClass jc = Repository.lookupClass(class_name); + return !jc.isClass(); + } catch (final ClassNotFoundException e) { + return false; + } + } + + + /** + * Return true if this type references a class, + * false if it references an interface. + * @return true if the type references a class, false if + * it references an interface + * @throws ClassNotFoundException if the class or interface + * referenced by this type can't be found + */ + public boolean referencesClassExact() throws ClassNotFoundException { + final JavaClass jc = Repository.lookupClass(class_name); + return jc.isClass(); + } + + + /** + * Return true if this type references an interface, + * false if it references a class. + * @return true if the type references an interface, false if + * it references a class + * @throws ClassNotFoundException if the class or interface + * referenced by this type can't be found + */ + public boolean referencesInterfaceExact() throws ClassNotFoundException { + final JavaClass jc = Repository.lookupClass(class_name); + return !jc.isClass(); + } + + + /** + * Return true if this type is a subclass of given ObjectType. + * @throws ClassNotFoundException if any of this class's superclasses + * can't be found + */ + public boolean subclassOf( final ObjectType superclass ) throws ClassNotFoundException { + if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) { + return false; + } + return Repository.instanceOf(this.class_name, superclass.class_name); + } + + + /** + * Java Virtual Machine Specification edition 2, 5.4.4 Access Control + * @throws ClassNotFoundException if the class referenced by this type + * can't be found + */ + public boolean accessibleTo( final ObjectType accessor ) throws ClassNotFoundException { + final JavaClass jc = Repository.lookupClass(class_name); + if (jc.isPublic()) { + return true; + } + final JavaClass acc = Repository.lookupClass(accessor.class_name); + return acc.getPackageName().equals(jc.getPackageName()); } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java index 76c460a21d5..16cd4ccdf1a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * POP - Pop top operand stack word * *
    Stack: ..., word -> ...
    * - * @author M. Dahm + * @version $Id: POP.java 1747278 2016-06-07 17:28:43Z britter $ */ public class POP extends StackInstruction implements PopInstruction { - public POP() { - super(com.sun.org.apache.bcel.internal.Constants.POP); - } + + public POP() { + super(com.sun.org.apache.bcel.internal.Const.POP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitStackInstruction(this); - v.visitPOP(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitStackInstruction(this); + v.visitPOP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java index f63925841f6..40de6f75467 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * POP2 - Pop two top operand stack words * *
    Stack: ..., word2, word1 -> ...
    * - * @author M. Dahm + * @version $Id: POP2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class POP2 extends StackInstruction implements PopInstruction { - public POP2() { - super(com.sun.org.apache.bcel.internal.Constants.POP2); - } + + public POP2() { + super(com.sun.org.apache.bcel.internal.Const.POP2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitStackInstruction(this); - v.visitPOP2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitStackInstruction(this); + v.visitPOP2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java index da73c7fd6af..7ab8ebfeccc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,142 +20,176 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * Wrapper class for push operations, which are implemented either as BIPUSH, * LDC or xCONST_n instructions. * - * @author M. Dahm + * @version $Id: PUSH.java 1749598 2016-06-21 20:36:33Z ggregory $ */ -public final class PUSH - implements CompoundInstruction, VariableLengthInstruction, InstructionConstants -{ - private Instruction instruction; +public final class PUSH implements CompoundInstruction, VariableLengthInstruction { - /** - * This constructor also applies for values of type short, char, byte - * - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, int value) { - if((value >= -1) && (value <= 5)) // Use ICONST_n - instruction = INSTRUCTIONS[Constants.ICONST_0 + value]; - else if((value >= -128) && (value <= 127)) // Use BIPUSH - instruction = new BIPUSH((byte)value); - else if((value >= -32768) && (value <= 32767)) // Use SIPUSH - instruction = new SIPUSH((short)value); - else // If everything fails create a Constant pool entry - instruction = new LDC(cp.addInteger(value)); - } + private Instruction instruction; - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, boolean value) { - instruction = INSTRUCTIONS[Constants.ICONST_0 + (value? 1 : 0)]; - } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, float value) { - if(value == 0.0) - instruction = FCONST_0; - else if(value == 1.0) - instruction = FCONST_1; - else if(value == 2.0) - instruction = FCONST_2; - else // Create a Constant pool entry - instruction = new LDC(cp.addFloat(value)); - } + /** + * This constructor also applies for values of type short, char, byte + * + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final int value) { + if ((value >= -1) && (value <= 5)) { + instruction = InstructionConst.getInstruction(Const.ICONST_0 + value); + } else if (Instruction.isValidByte(value)) { + instruction = new BIPUSH((byte) value); + } else if (Instruction.isValidShort(value)) { + instruction = new SIPUSH((short) value); + } else { + instruction = new LDC(cp.addInteger(value)); + } + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, long value) { - if(value == 0) - instruction = LCONST_0; - else if(value == 1) - instruction = LCONST_1; - else // Create a Constant pool entry - instruction = new LDC2_W(cp.addLong(value)); - } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, double value) { - if(value == 0.0) - instruction = DCONST_0; - else if(value == 1.0) - instruction = DCONST_1; - else // Create a Constant pool entry - instruction = new LDC2_W(cp.addDouble(value)); - } + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final boolean value) { + instruction = InstructionConst.getInstruction(Const.ICONST_0 + (value ? 1 : 0)); + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, String value) { - if(value == null) - instruction = ACONST_NULL; - else // Create a Constant pool entry - instruction = new LDC(cp.addString(value)); - } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Number value) { - if((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) - instruction = new PUSH(cp, value.intValue()).instruction; - else if(value instanceof Double) - instruction = new PUSH(cp, value.doubleValue()).instruction; - else if(value instanceof Float) - instruction = new PUSH(cp, value.floatValue()).instruction; - else if(value instanceof Long) - instruction = new PUSH(cp, value.longValue()).instruction; - else - throw new ClassGenException("What's this: " + value); - } + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final float value) { + if (value == 0.0) { + instruction = InstructionConst.FCONST_0; + } else if (value == 1.0) { + instruction = InstructionConst.FCONST_1; + } else if (value == 2.0) { + instruction = InstructionConst.FCONST_2; + } else { + instruction = new LDC(cp.addFloat(value)); + } + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Character value) { - this(cp, (int)value.charValue()); - } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Boolean value) { - this(cp, value.booleanValue()); - } + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final long value) { + if (value == 0) { + instruction = InstructionConst.LCONST_0; + } else if (value == 1) { + instruction = InstructionConst.LCONST_1; + } else { + instruction = new LDC2_W(cp.addLong(value)); + } + } - public final InstructionList getInstructionList() { - return new InstructionList(instruction); - } - public final Instruction getInstruction() { - return instruction; - } + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final double value) { + if (value == 0.0) { + instruction = InstructionConst.DCONST_0; + } else if (value == 1.0) { + instruction = InstructionConst.DCONST_1; + } else { + instruction = new LDC2_W(cp.addDouble(value)); + } + } - /** - * @return mnemonic for instruction - */ - public String toString() { - return instruction.toString() + " (PUSH)"; - } + + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final String value) { + if (value == null) { + instruction = InstructionConst.ACONST_NULL; + } else { + instruction = new LDC(cp.addString(value)); + } + } + + /** + * + * @param cp + * @param value + * @since 6.0 + */ + public PUSH(final ConstantPoolGen cp, final ObjectType value) { + if (value == null) { + instruction = InstructionConst.ACONST_NULL; + } else { + instruction = new LDC(cp.addClass(value)); + } + } + + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final Number value) { + if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) { + instruction = new PUSH(cp, value.intValue()).instruction; + } else if (value instanceof Double) { + instruction = new PUSH(cp, value.doubleValue()).instruction; + } else if (value instanceof Float) { + instruction = new PUSH(cp, value.floatValue()).instruction; + } else if (value instanceof Long) { + instruction = new PUSH(cp, value.longValue()).instruction; + } else { + throw new ClassGenException("What's this: " + value); + } + } + + + /** + * creates a push object from a Character value. Warning: Make sure not to attempt to allow + * autoboxing to create this value parameter, as an alternative constructor will be called + * + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final Character value) { + this(cp, value.charValue()); + } + + + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final Boolean value) { + this(cp, value.booleanValue()); + } + + + @Override + public final InstructionList getInstructionList() { + return new InstructionList(instruction); + } + + + public final Instruction getInstruction() { + return instruction; + } + + + /** + * @return mnemonic for instruction + */ + @Override + public String toString() { + return instruction + " (PUSH)"; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java index 9f7b42f108c..56a81740e1b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java @@ -21,9 +21,8 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * PUTFIELD - Put field in object @@ -31,55 +30,55 @@ import com.sun.org.apache.bcel.internal.ExceptionConstants; * OR *
    Stack: ..., objectref, value.word1, value.word2 -> ...
    * - * @author M. Dahm + * @version $Id: PUTFIELD.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class PUTFIELD - extends FieldInstruction - implements PopInstruction,ExceptionThrower{ - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - PUTFIELD() {} +public class PUTFIELD extends FieldInstruction implements PopInstruction, ExceptionThrower { - public PUTFIELD(int index) { - super(Constants.PUTFIELD, index); - } - - public int consumeStack(ConstantPoolGen cpg) { return getFieldSize(cpg) + 1; } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = - ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = - ExceptionConstants.NULL_POINTER_EXCEPTION; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + PUTFIELD() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitPUTFIELD(this); - } + public PUTFIELD(final int index) { + super(Const.PUTFIELD, index); + } + + + @Override + public int consumeStack( final ConstantPoolGen cpg ) { + return getFieldSize(cpg) + 1; + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitPUTFIELD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java index ffb7a626bc2..d7816175eb6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java @@ -21,9 +21,8 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * PUTSTATIC - Put static field in class @@ -31,51 +30,54 @@ import com.sun.org.apache.bcel.internal.ExceptionConstants; * OR *
    Stack: ..., value.word1, value.word2 -> ...
    * - * @author M. Dahm + * @version $Id: PUTSTATIC.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class PUTSTATIC extends FieldInstruction - implements ExceptionThrower, PopInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - PUTSTATIC() {} +public class PUTSTATIC extends FieldInstruction implements ExceptionThrower, PopInstruction { - public PUTSTATIC(int index) { - super(Constants.PUTSTATIC, index); - } - - public int consumeStack(ConstantPoolGen cpg) { return getFieldSize(cpg); } - - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = - ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + PUTSTATIC() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitPUTSTATIC(this); - } + public PUTSTATIC(final int index) { + super(Const.PUTSTATIC, index); + } + + + @Override + public int consumeStack( final ConstantPoolGen cpg ) { + return getFieldSize(cpg); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitPUTSTATIC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java index f195a83477d..750640b3631 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java @@ -21,12 +21,11 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an unparameterized instruction to pop a value on top from the stack, * such as ISTORE, POP, PUTSTATIC. * - * @author M. Dahm + * @version $Id: PopInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see ISTORE * @see POP */ diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java index bb702276412..c03a2871e5e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java @@ -21,12 +21,11 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an unparameterized instruction to produce a value on top of the stack, * such as ILOAD, LDC, SIPUSH, DUP, ICONST, etc. * - * @author M. Dahm + * @version $Id: PushInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see ILOAD * @see ICONST diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java index 093a870d27f..c1c60a563a5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java @@ -21,108 +21,131 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * RET - Return from subroutine * - *
    Stack: ..., -> ..., address
    + *
    Stack: ... -> ...
    * - * @author M. Dahm + * @version $Id: RET.java 1747278 2016-06-07 17:28:43Z britter $ */ public class RET extends Instruction implements IndexedInstruction, TypedInstruction { - private boolean wide; - private int index; // index to local variable containg the return address - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - RET() {} + private boolean wide; + private int index; // index to local variable containg the return address - public RET(int index) { - super(com.sun.org.apache.bcel.internal.Constants.RET, (short)2); - setIndex(index); // May set wide as side effect - } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - if(wide) - out.writeByte(com.sun.org.apache.bcel.internal.Constants.WIDE); - - out.writeByte(opcode); - - if(wide) - out.writeShort(index); - else - out.writeByte(index); - } - - private final void setWide() { - if(wide = index > com.sun.org.apache.bcel.internal.Constants.MAX_BYTE) - length = 4; // Including the wide byte - else - length = 2; - } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - this.wide = wide; - - if(wide) { - index = bytes.readUnsignedShort(); - length = 4; - } else { - index = bytes.readUnsignedByte(); - length = 2; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + RET() { } - } - /** - * @return index of local variable containg the return address - */ - public final int getIndex() { return index; } - /** - * Set index of local variable containg the return address - */ - public final void setIndex(int n) { - if(n < 0) - throw new ClassGenException("Negative index value: " + n); + public RET(final int index) { + super(com.sun.org.apache.bcel.internal.Const.RET, (short) 2); + setIndex(index); // May set wide as side effect + } - index = n; - setWide(); - } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + index; - } + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + if (wide) { + out.writeByte(com.sun.org.apache.bcel.internal.Const.WIDE); + } + out.writeByte(super.getOpcode()); + if (wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } - /** @return return address type - */ - public Type getType(ConstantPoolGen cp) { - return ReturnaddressType.NO_TARGET; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitRET(this); - } + private void setWide() { + wide = index > com.sun.org.apache.bcel.internal.Const.MAX_BYTE; + if (wide) { + super.setLength(4); // Including the wide byte + } else { + super.setLength(2); + } + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + this.wide = wide; + if (wide) { + index = bytes.readUnsignedShort(); + super.setLength(4); + } else { + index = bytes.readUnsignedByte(); + super.setLength(2); + } + } + + + /** + * @return index of local variable containg the return address + */ + @Override + public final int getIndex() { + return index; + } + + + /** + * Set index of local variable containg the return address + */ + @Override + public final void setIndex( final int n ) { + if (n < 0) { + throw new ClassGenException("Negative index value: " + n); + } + index = n; + setWide(); + } + + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + index; + } + + + /** @return return address type + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return ReturnaddressType.NO_TARGET; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitRET(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java index c9b6621152d..7d414c6eef2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * RETURN - Return from void method *
    Stack: ... -> <empty>
    * - * @author M. Dahm + * @version $Id: RETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class RETURN extends ReturnInstruction { - public RETURN() { - super(com.sun.org.apache.bcel.internal.Constants.RETURN); - } + + public RETURN() { + super(com.sun.org.apache.bcel.internal.Const.RETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java index 0513c1c76de..300a7171a02 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java @@ -20,297 +20,314 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** * Super class for object and array types. * - * @author M. Dahm + * @version $Id: ReferenceType.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public abstract class ReferenceType extends Type { - protected ReferenceType(byte t, String s) { - super(t, s); - } - /** Class is non-abstract but not instantiable from the outside - */ - ReferenceType() { - super(Constants.T_OBJECT, ""); - } - - /** - * Return true iff this type is castable to another type t as defined in - * the JVM specification. The case where this is Type.NULL is not - * defined (see the CHECKCAST definition in the JVM specification). - * However, because e.g. CHECKCAST doesn't throw a - * ClassCastException when casting a null reference to any Object, - * true is returned in this case. - */ - public boolean isCastableTo(Type t) { - if (this.equals(Type.NULL)) - return true; // If this is ever changed in isAssignmentCompatible() - - return isAssignmentCompatibleWith(t); - /* Yes, it's true: It's the same definition. - * See vmspec2 AASTORE / CHECKCAST definitions. - */ - } - - /** - * Return true iff this is assignment compatible with another type t - * as defined in the JVM specification; see the AASTORE definition - * there. - */ - public boolean isAssignmentCompatibleWith(Type t) { - if (!(t instanceof ReferenceType)) - return false; - - ReferenceType T = (ReferenceType) t; - - if (this.equals(Type.NULL)) - return true; // This is not explicitely stated, but clear. Isn't it? - - /* If this is a class type then - */ - if ((this instanceof ObjectType) && (((ObjectType) this).referencesClass())) { - /* If T is a class type, then this must be the same class as T, - or this must be a subclass of T; - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClass())) { - if (this.equals(T)) - return true; - - if (Repository.instanceOf(((ObjectType) this).getClassName(), - ((ObjectType) T).getClassName())) - return true; - } - - /* If T is an interface type, this must implement interface T. - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterface())) { - if (Repository.implementationOf(((ObjectType) this).getClassName(), - ((ObjectType) T).getClassName())) - return true; - } + protected ReferenceType(final byte t, final String s) { + super(t, s); } - /* If this is an interface type, then: - */ - if ((this instanceof ObjectType) && (((ObjectType) this).referencesInterface())) { - /* If T is a class type, then T must be Object (2.4.7). - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClass())) { - if (T.equals(Type.OBJECT)) return true; - } - /* If T is an interface type, then T must be the same interface - * as this or a superinterface of this (2.13.2). - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterface())) { - if (this.equals(T)) return true; - if (Repository.implementationOf(((ObjectType) this).getClassName(), - ((ObjectType) T).getClassName())) - return true; - } + /** Class is non-abstract but not instantiable from the outside + */ + ReferenceType() { + super(Const.T_OBJECT, ""); } - /* If this is an array type, namely, the type SC[], that is, an - * array of components of type SC, then: + + /** + * Return true iff this type is castable to another type t as defined in + * the JVM specification. The case where this is Type.NULL is not + * defined (see the CHECKCAST definition in the JVM specification). + * However, because e.g. CHECKCAST doesn't throw a + * ClassCastException when casting a null reference to any Object, + * true is returned in this case. + * + * @throws ClassNotFoundException if any classes or interfaces required + * to determine assignment compatibility can't be found */ - if (this instanceof ArrayType) { - /* If T is a class type, then T must be Object (2.4.7). - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClass())) { - if (T.equals(Type.OBJECT)) return true; - } - - /* If T is an array type TC[], that is, an array of components - * of type TC, then one of the following must be true: - */ - if (T instanceof ArrayType) { - /* TC and SC are the same primitive type (2.4.1). - */ - Type sc = ((ArrayType) this).getElementType(); - Type tc = ((ArrayType) this).getElementType(); - - if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) - return true; - - /* TC and SC are reference types (2.4.6), and type SC is - * assignable to TC by these runtime rules. - */ - if (tc instanceof ReferenceType && sc instanceof ReferenceType && - ((ReferenceType) sc).isAssignmentCompatibleWith((ReferenceType) tc)) - return true; - } - - /* If T is an interface type, T must be one of the interfaces implemented by arrays (2.15). */ - // TODO: Check if this is still valid or find a way to dynamically find out which - // interfaces arrays implement. However, as of the JVM specification edition 2, there - // are at least two different pages where assignment compatibility is defined and - // on one of them "interfaces implemented by arrays" is exchanged with "'Cloneable' or - // 'java.io.Serializable'" - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterface())) { - for (int ii = 0; ii < Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS.length; ii++) { - if (T.equals(new ObjectType(Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS[ii]))) return true; + public boolean isCastableTo( final Type t ) throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t instanceof ReferenceType; // If this is ever changed in isAssignmentCompatible() } - } + return isAssignmentCompatibleWith(t); + /* Yes, it's true: It's the same definition. + * See vmspec2 AASTORE / CHECKCAST definitions. + */ } - return false; // default. - } - /** - * This commutative operation returns the first common superclass (narrowest ReferenceType - * referencing a class, not an interface). - * If one of the types is a superclass of the other, the former is returned. - * If "this" is Type.NULL, then t is returned. - * If t is Type.NULL, then "this" is returned. - * If "this" equals t ['this.equals(t)'] "this" is returned. - * If "this" or t is an ArrayType, then Type.OBJECT is returned; - * unless their dimensions match. Then an ArrayType of the same - * number of dimensions is returned, with its basic type being the - * first common super class of the basic types of "this" and t. - * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. - * If not all of the two classes' superclasses cannot be found, "null" is returned. - * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". - */ - public ReferenceType getFirstCommonSuperclass(ReferenceType t) { - if (this.equals(Type.NULL)) return t; - if (t.equals(Type.NULL)) return this; - if (this.equals(t)) return this; - /* - * TODO: Above sounds a little arbitrary. On the other hand, there is - * no object referenced by Type.NULL so we can also say all the objects - * referenced by Type.NULL were derived from java.lang.Object. - * However, the Java Language's "instanceof" operator proves us wrong: - * "null" is not referring to an instance of java.lang.Object :) + + /** + * Return true iff this is assignment compatible with another type t + * as defined in the JVM specification; see the AASTORE definition + * there. + * @throws ClassNotFoundException if any classes or interfaces required + * to determine assignment compatibility can't be found */ - - /* This code is from a bug report by Konstantin Shagin */ - - if ((this instanceof ArrayType) && (t instanceof ArrayType)) { - ArrayType arrType1 = (ArrayType) this; - ArrayType arrType2 = (ArrayType) t; - if ( - (arrType1.getDimensions() == arrType2.getDimensions()) && - arrType1.getBasicType() instanceof ObjectType && - arrType2.getBasicType() instanceof ObjectType) { - return new ArrayType( - ((ObjectType) arrType1.getBasicType()).getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()), - arrType1.getDimensions() - ); - - } + public boolean isAssignmentCompatibleWith( final Type t ) throws ClassNotFoundException { + if (!(t instanceof ReferenceType)) { + return false; + } + final ReferenceType T = (ReferenceType) t; + if (this.equals(Type.NULL)) { + return true; // This is not explicitely stated, but clear. Isn't it? + } + /* If this is a class type then + */ + if ((this instanceof ObjectType) && (((ObjectType) this).referencesClassExact())) { + /* If T is a class type, then this must be the same class as T, + or this must be a subclass of T; + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { + if (this.equals(T)) { + return true; + } + if (Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T) + .getClassName())) { + return true; + } + } + /* If T is an interface type, this must implement interface T. + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { + if (Repository.implementationOf(((ObjectType) this).getClassName(), + ((ObjectType) T).getClassName())) { + return true; + } + } + } + /* If this is an interface type, then: + */ + if ((this instanceof ObjectType) && (((ObjectType) this).referencesInterfaceExact())) { + /* If T is a class type, then T must be Object (2.4.7). + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { + if (T.equals(Type.OBJECT)) { + return true; + } + } + /* If T is an interface type, then T must be the same interface + * as this or a superinterface of this (2.13.2). + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { + if (this.equals(T)) { + return true; + } + if (Repository.implementationOf(((ObjectType) this).getClassName(), + ((ObjectType) T).getClassName())) { + return true; + } + } + } + /* If this is an array type, namely, the type SC[], that is, an + * array of components of type SC, then: + */ + if (this instanceof ArrayType) { + /* If T is a class type, then T must be Object (2.4.7). + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { + if (T.equals(Type.OBJECT)) { + return true; + } + } + /* If T is an array type TC[], that is, an array of components + * of type TC, then one of the following must be true: + */ + if (T instanceof ArrayType) { + /* TC and SC are the same primitive type (2.4.1). + */ + final Type sc = ((ArrayType) this).getElementType(); + final Type tc = ((ArrayType) T).getElementType(); + if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) { + return true; + } + /* TC and SC are reference types (2.4.6), and type SC is + * assignable to TC by these runtime rules. + */ + if (tc instanceof ReferenceType && sc instanceof ReferenceType + && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { + return true; + } + } + /* If T is an interface type, T must be one of the interfaces implemented by arrays (2.15). */ + // TODO: Check if this is still valid or find a way to dynamically find out which + // interfaces arrays implement. However, as of the JVM specification edition 2, there + // are at least two different pages where assignment compatibility is defined and + // on one of them "interfaces implemented by arrays" is exchanged with "'Cloneable' or + // 'java.io.Serializable'" + if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { + for (final String element : Const.getInterfacesImplementedByArrays()) { + if (T.equals(ObjectType.getInstance(element))) { + return true; + } + } + } + } + return false; // default. } - if ((this instanceof ArrayType) || (t instanceof ArrayType)) - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) || - ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) - return Type.OBJECT; - // TODO: The above line is correct comparing to the vmspec2. But one could - // make class file verification a bit stronger here by using the notion of - // superinterfaces or even castability or assignment compatibility. - - - // this and t are ObjectTypes, see above. - ObjectType thiz = (ObjectType) this; - ObjectType other = (ObjectType) t; - JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); - JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); - - if ((thiz_sups == null) || (other_sups == null)) { - return null; - } - - // Waaahh... - JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - this_sups[0] = Repository.lookupClass(thiz.getClassName()); - t_sups[0] = Repository.lookupClass(other.getClassName()); - - for (int i = 0; i < t_sups.length; i++) { - for (int j = 0; j < this_sups.length; j++) { - if (this_sups[j].equals(t_sups[i])) return new ObjectType(this_sups[j].getClassName()); - } - } - - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; - } - - /** - * This commutative operation returns the first common superclass (narrowest ReferenceType - * referencing a class, not an interface). - * If one of the types is a superclass of the other, the former is returned. - * If "this" is Type.NULL, then t is returned. - * If t is Type.NULL, then "this" is returned. - * If "this" equals t ['this.equals(t)'] "this" is returned. - * If "this" or t is an ArrayType, then Type.OBJECT is returned. - * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. - * If not all of the two classes' superclasses cannot be found, "null" is returned. - * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". - * - * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has - * slightly changed semantics. - */ - @Deprecated - public ReferenceType firstCommonSuperclass(ReferenceType t) { - if (this.equals(Type.NULL)) return t; - if (t.equals(Type.NULL)) return this; - if (this.equals(t)) return this; - /* - * TODO: Above sounds a little arbitrary. On the other hand, there is - * no object referenced by Type.NULL so we can also say all the objects - * referenced by Type.NULL were derived from java.lang.Object. - * However, the Java Language's "instanceof" operator proves us wrong: - * "null" is not referring to an instance of java.lang.Object :) + /** + * This commutative operation returns the first common superclass (narrowest ReferenceType + * referencing a class, not an interface). + * If one of the types is a superclass of the other, the former is returned. + * If "this" is Type.NULL, then t is returned. + * If t is Type.NULL, then "this" is returned. + * If "this" equals t ['this.equals(t)'] "this" is returned. + * If "this" or t is an ArrayType, then Type.OBJECT is returned; + * unless their dimensions match. Then an ArrayType of the same + * number of dimensions is returned, with its basic type being the + * first common super class of the basic types of "this" and t. + * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. + * If not all of the two classes' superclasses cannot be found, "null" is returned. + * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". + * + * @throws ClassNotFoundException on failure to find superclasses of this + * type, or the type passed as a parameter */ - - if ((this instanceof ArrayType) || (t instanceof ArrayType)) - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - - if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) || - ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) - return Type.OBJECT; - // TODO: The above line is correct comparing to the vmspec2. But one could - // make class file verification a bit stronger here by using the notion of - // superinterfaces or even castability or assignment compatibility. - - - // this and t are ObjectTypes, see above. - ObjectType thiz = (ObjectType) this; - ObjectType other = (ObjectType) t; - JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); - JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); - - if ((thiz_sups == null) || (other_sups == null)) { - return null; + public ReferenceType getFirstCommonSuperclass( final ReferenceType t ) throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t; + } + if (t.equals(Type.NULL)) { + return this; + } + if (this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there is + * no object referenced by Type.NULL so we can also say all the objects + * referenced by Type.NULL were derived from java.lang.Object. + * However, the Java Language's "instanceof" operator proves us wrong: + * "null" is not referring to an instance of java.lang.Object :) + */ + } + /* This code is from a bug report by Konstantin Shagin */ + if ((this instanceof ArrayType) && (t instanceof ArrayType)) { + final ArrayType arrType1 = (ArrayType) this; + final ArrayType arrType2 = (ArrayType) t; + if ((arrType1.getDimensions() == arrType2.getDimensions()) + && arrType1.getBasicType() instanceof ObjectType + && arrType2.getBasicType() instanceof ObjectType) { + return new ArrayType(((ObjectType) arrType1.getBasicType()) + .getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()), arrType1 + .getDimensions()); + } + } + if ((this instanceof ArrayType) || (t instanceof ArrayType)) { + return Type.OBJECT; + // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + } + if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterfaceExact()) + || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterfaceExact())) { + return Type.OBJECT; + // TODO: The above line is correct comparing to the vmspec2. But one could + // make class file verification a bit stronger here by using the notion of + // superinterfaces or even castability or assignment compatibility. + } + // this and t are ObjectTypes, see above. + final ObjectType thiz = (ObjectType) this; + final ObjectType other = (ObjectType) t; + final JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); + final JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); + if ((thiz_sups == null) || (other_sups == null)) { + return null; + } + // Waaahh... + final JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; + final JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; + System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); + System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); + this_sups[0] = Repository.lookupClass(thiz.getClassName()); + t_sups[0] = Repository.lookupClass(other.getClassName()); + for (final JavaClass t_sup : t_sups) { + for (final JavaClass this_sup : this_sups) { + if (this_sup.equals(t_sup)) { + return ObjectType.getInstance(this_sup.getClassName()); + } + } + } + // Huh? Did you ask for Type.OBJECT's superclass?? + return null; } - // Waaahh... - JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - this_sups[0] = Repository.lookupClass(thiz.getClassName()); - t_sups[0] = Repository.lookupClass(other.getClassName()); - - for (int i = 0; i < t_sups.length; i++) { - for (int j = 0; j < this_sups.length; j++) { - if (this_sups[j].equals(t_sups[i])) return new ObjectType(this_sups[j].getClassName()); - } + /** + * This commutative operation returns the first common superclass (narrowest ReferenceType + * referencing a class, not an interface). + * If one of the types is a superclass of the other, the former is returned. + * If "this" is Type.NULL, then t is returned. + * If t is Type.NULL, then "this" is returned. + * If "this" equals t ['this.equals(t)'] "this" is returned. + * If "this" or t is an ArrayType, then Type.OBJECT is returned. + * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. + * If not all of the two classes' superclasses cannot be found, "null" is returned. + * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". + * + * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has + * slightly changed semantics. + * @throws ClassNotFoundException on failure to find superclasses of this + * type, or the type passed as a parameter + */ + @Deprecated + public ReferenceType firstCommonSuperclass( final ReferenceType t ) throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t; + } + if (t.equals(Type.NULL)) { + return this; + } + if (this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there is + * no object referenced by Type.NULL so we can also say all the objects + * referenced by Type.NULL were derived from java.lang.Object. + * However, the Java Language's "instanceof" operator proves us wrong: + * "null" is not referring to an instance of java.lang.Object :) + */ + } + if ((this instanceof ArrayType) || (t instanceof ArrayType)) { + return Type.OBJECT; + // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + } + if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) + || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) { + return Type.OBJECT; + // TODO: The above line is correct comparing to the vmspec2. But one could + // make class file verification a bit stronger here by using the notion of + // superinterfaces or even castability or assignment compatibility. + } + // this and t are ObjectTypes, see above. + final ObjectType thiz = (ObjectType) this; + final ObjectType other = (ObjectType) t; + final JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); + final JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); + if ((thiz_sups == null) || (other_sups == null)) { + return null; + } + // Waaahh... + final JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; + final JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; + System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); + System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); + this_sups[0] = Repository.lookupClass(thiz.getClassName()); + t_sups[0] = Repository.lookupClass(other.getClassName()); + for (final JavaClass t_sup : t_sups) { + for (final JavaClass this_sup : this_sups) { + if (this_sup.equals(t_sup)) { + return ObjectType.getInstance(this_sup.getClassName()); + } + } + } + // Huh? Did you ask for Type.OBJECT's superclass?? + return null; } - - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java index 12906a06391..47c5b300c9e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java @@ -21,50 +21,66 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * Super class for the xRETURN family of instructions. * - * @author M. Dahm + * @version $Id: ReturnInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class ReturnInstruction extends Instruction - implements ExceptionThrower, TypedInstruction, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ReturnInstruction() {} +public abstract class ReturnInstruction extends Instruction implements ExceptionThrower, + TypedInstruction, StackConsumer { - /** - * @param opcode of instruction - */ - protected ReturnInstruction(short opcode) { - super(opcode, (short)1); - } - - public Type getType() { - switch(opcode) { - case Constants.IRETURN: return Type.INT; - case Constants.LRETURN: return Type.LONG; - case Constants.FRETURN: return Type.FLOAT; - case Constants.DRETURN: return Type.DOUBLE; - case Constants.ARETURN: return Type.OBJECT; - case Constants.RETURN: return Type.VOID; - - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ReturnInstruction() { } - } - public Class[] getExceptions() { - return new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; - } - /** @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - return getType(); - } + /** + * @param opcode of instruction + */ + protected ReturnInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + public Type getType() { + final short _opcode = super.getOpcode(); + switch (_opcode) { + case Const.IRETURN: + return Type.INT; + case Const.LRETURN: + return Type.LONG; + case Const.FRETURN: + return Type.FLOAT; + case Const.DRETURN: + return Type.DOUBLE; + case Const.ARETURN: + return Type.OBJECT; + case Const.RETURN: + return Type.VOID; + default: // Never reached + throw new ClassGenException("Unknown type " + _opcode); + } + } + + + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ILLEGAL_MONITOR_STATE + }; + } + + + /** @return type associated with the instruction + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return getType(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java index f62f6db9ccf..a2422242cd3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java @@ -21,55 +21,68 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import java.util.Objects; +import com.sun.org.apache.bcel.internal.Const; /** * Returnaddress, the type JSR or JSR_W instructions push upon the stack. * * see vmspec2 3.3.3 - * @author Enver Haase + * @version $Id: ReturnaddressType.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class ReturnaddressType extends Type { - public static final ReturnaddressType NO_TARGET = new ReturnaddressType(); - private InstructionHandle returnTarget; + public static final ReturnaddressType NO_TARGET = new ReturnaddressType(); + private InstructionHandle returnTarget; - /** - * A Returnaddress [that doesn't know where to return to]. - */ - private ReturnaddressType(){ - super(Constants.T_ADDRESS, ""); - } - /** - * Creates a ReturnaddressType object with a target. - */ - public ReturnaddressType(InstructionHandle returnTarget) { - super(Constants.T_ADDRESS, ""); + /** + * A Returnaddress [that doesn't know where to return to]. + */ + private ReturnaddressType() { + super(Const.T_ADDRESS, ""); + } + + + /** + * Creates a ReturnaddressType object with a target. + */ + public ReturnaddressType(final InstructionHandle returnTarget) { + super(Const.T_ADDRESS, ""); this.returnTarget = returnTarget; - } + } - @Override - public int hashCode() { - return Objects.hashCode(this.returnTarget); - } - /** - * Returns if the two Returnaddresses refer to the same target. - */ - @Override - public boolean equals(Object rat){ - if(!(rat instanceof ReturnaddressType)) - return false; + /** @return a hash code value for the object. + */ + @Override + public int hashCode() { + if (returnTarget == null) { + return 0; + } + return returnTarget.hashCode(); + } - return ((ReturnaddressType)rat).returnTarget.equals(this.returnTarget); - } - /** - * @return the target of this ReturnaddressType - */ - public InstructionHandle getTarget(){ - return returnTarget; - } + /** + * Returns if the two Returnaddresses refer to the same target. + */ + @Override + public boolean equals( final Object rat ) { + if (!(rat instanceof ReturnaddressType)) { + return false; + } + final ReturnaddressType that = (ReturnaddressType) rat; + if (this.returnTarget == null || that.returnTarget == null) { + return that.returnTarget == this.returnTarget; + } + return that.returnTarget.equals(this.returnTarget); + } + + + /** + * @return the target of this ReturnaddressType + */ + public InstructionHandle getTarget() { + return returnTarget; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java index 126f599a38d..56ce69e91ed 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * SALOAD - Load short from array *
    Stack: ..., arrayref, index -> ..., value
    * - * @author M. Dahm + * @version $Id: SALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class SALOAD extends ArrayInstruction implements StackProducer { - public SALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.SALOAD); - } + + public SALOAD() { + super(com.sun.org.apache.bcel.internal.Const.SALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitSALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitSALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java index 10e4f215abf..b84e4385edf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * SASTORE - Store into short array *
    Stack: ..., arrayref, index, value -> ...
    * - * @author M. Dahm + * @version $Id: SASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class SASTORE extends ArrayInstruction implements StackConsumer { - public SASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.SASTORE); - } + + public SASTORE() { + super(com.sun.org.apache.bcel.internal.Const.SASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitSASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitSASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java index 74a30454bd2..ec7cd472196 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java @@ -20,7 +20,9 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -28,67 +30,84 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; * *
    Stack: ... -> ..., value
    * - * @author M. Dahm + * @version $Id: SIPUSH.java 1747278 2016-06-07 17:28:43Z britter $ */ public class SIPUSH extends Instruction implements ConstantPushInstruction { - private short b; - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - SIPUSH() {} + private short b; - public SIPUSH(short b) { - super(com.sun.org.apache.bcel.internal.Constants.SIPUSH, (short)3); - this.b = b; - } - /** - * Dump instruction as short code to stream out. - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - out.writeShort(b); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + SIPUSH() { + } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + b; - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - length = 3; - b = bytes.readShort(); - } + public SIPUSH(final short b) { + super(com.sun.org.apache.bcel.internal.Const.SIPUSH, (short) 3); + this.b = b; + } - public Number getValue() { return Integer.valueOf(b); } - /** @return Type.SHORT - */ - public Type getType(ConstantPoolGen cp) { - return Type.SHORT; - } + /** + * Dump instruction as short code to stream out. + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.dump(out); + out.writeShort(b); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitSIPUSH(this); - } + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + b; + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.setLength(3); + b = bytes.readShort(); + } + + + @Override + public Number getValue() { + return Integer.valueOf(b); + } + + + /** @return Type.SHORT + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.SHORT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitSIPUSH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java index a85e91da980..e88fbed0468 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java @@ -21,31 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * SWAP - Swa top operand stack word *
    Stack: ..., word2, word1 -> ..., word1, word2
    * - * @author M. Dahm + * @version $Id: SWAP.java 1747278 2016-06-07 17:28:43Z britter $ */ public class SWAP extends StackInstruction implements StackConsumer, StackProducer { - public SWAP() { - super(com.sun.org.apache.bcel.internal.Constants.SWAP); - } + + public SWAP() { + super(com.sun.org.apache.bcel.internal.Const.SWAP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitStackInstruction(this); - v.visitSWAP(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitStackInstruction(this); + v.visitSWAP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java index fb4dce327ea..e75ea3c7564 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java @@ -21,130 +21,140 @@ package com.sun.org.apache.bcel.internal.generic; - /** * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or * TABLESWITCH instruction, depending on whether the match values (int[]) can be * sorted with no gaps between the numbers. * - * @author M. Dahm + * @version $Id: SWITCH.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public final class SWITCH implements CompoundInstruction { - private int[] match; - private InstructionHandle[] targets; - private Select instruction; - private int match_length; - /** - * Template for switch() constructs. If the match array can be - * sorted in ascending order with gaps no larger than max_gap - * between the numbers, a TABLESWITCH instruction is generated, and - * a LOOKUPSWITCH otherwise. The former may be more efficient, but - * needs more space. - * - * Note, that the key array always will be sorted, though we leave - * the original arrays unaltered. - * - * @param match array of match values (case 2: ... case 7: ..., etc.) - * @param targets the instructions to be branched to for each case - * @param target the default target - * @param max_gap maximum gap that may between case branches - */ - public SWITCH(int[] match, InstructionHandle[] targets, - InstructionHandle target, int max_gap) { - this.match = (int[])match.clone(); - this.targets = (InstructionHandle[])targets.clone(); + private int[] match; + private InstructionHandle[] targets; + private Select instruction; + private int match_length; - if((match_length = match.length) < 2) // (almost) empty switch, or just default - instruction = new TABLESWITCH(match, targets, target); - else { - sort(0, match_length - 1); - if(matchIsOrdered(max_gap)) { - fillup(max_gap, target); - - instruction = new TABLESWITCH(this.match, this.targets, target); - } - else - instruction = new LOOKUPSWITCH(this.match, this.targets, target); - } - } - - public SWITCH(int[] match, InstructionHandle[] targets, - InstructionHandle target) { - this(match, targets, target, 1); - } - - private final void fillup(int max_gap, InstructionHandle target) { - int max_size = match_length + match_length * max_gap; - int[] m_vec = new int[max_size]; - InstructionHandle[] t_vec = new InstructionHandle[max_size]; - int count = 1; - - m_vec[0] = match[0]; - t_vec[0] = targets[0]; - - for(int i=1; i < match_length; i++) { - int prev = match[i-1]; - int gap = match[i] - prev; - - for(int j=1; j < gap; j++) { - m_vec[count] = prev + j; - t_vec[count] = target; - count++; - } - - m_vec[count] = match[i]; - t_vec[count] = targets[i]; - count++; + /** + * Template for switch() constructs. If the match array can be + * sorted in ascending order with gaps no larger than max_gap + * between the numbers, a TABLESWITCH instruction is generated, and + * a LOOKUPSWITCH otherwise. The former may be more efficient, but + * needs more space. + * + * Note, that the key array always will be sorted, though we leave + * the original arrays unaltered. + * + * @param match array of match values (case 2: ... case 7: ..., etc.) + * @param targets the instructions to be branched to for each case + * @param target the default target + * @param max_gap maximum gap that may between case branches + */ + public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target, final int max_gap) { + this.match = match.clone(); + this.targets = targets.clone(); + if ((match_length = match.length) < 2) { + instruction = new TABLESWITCH(match, targets, target); + } else { + sort(0, match_length - 1); + if (matchIsOrdered(max_gap)) { + fillup(max_gap, target); + instruction = new TABLESWITCH(this.match, this.targets, target); + } else { + instruction = new LOOKUPSWITCH(this.match, this.targets, target); + } + } } - match = new int[count]; - targets = new InstructionHandle[count]; - System.arraycopy(m_vec, 0, match, 0, count); - System.arraycopy(t_vec, 0, targets, 0, count); - } + public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target) { + this(match, targets, target, 1); + } - /** - * Sort match and targets array with QuickSort. - */ - private final void sort(int l, int r) { - int i = l, j = r; - int h, m = match[(l + r) / 2]; - InstructionHandle h2; - do { - while(match[i] < m) i++; - while(m < match[j]) j--; + private void fillup( final int max_gap, final InstructionHandle target ) { + final int max_size = match_length + match_length * max_gap; + final int[] m_vec = new int[max_size]; + final InstructionHandle[] t_vec = new InstructionHandle[max_size]; + int count = 1; + m_vec[0] = match[0]; + t_vec[0] = targets[0]; + for (int i = 1; i < match_length; i++) { + final int prev = match[i - 1]; + final int gap = match[i] - prev; + for (int j = 1; j < gap; j++) { + m_vec[count] = prev + j; + t_vec[count] = target; + count++; + } + m_vec[count] = match[i]; + t_vec[count] = targets[i]; + count++; + } + match = new int[count]; + targets = new InstructionHandle[count]; + System.arraycopy(m_vec, 0, match, 0, count); + System.arraycopy(t_vec, 0, targets, 0, count); + } - if(i <= j) { - h=match[i]; match[i]=match[j]; match[j]=h; // Swap elements - h2=targets[i]; targets[i]=targets[j]; targets[j]=h2; // Swap instructions, too - i++; j--; - } - } while(i <= j); - if(l < j) sort(l, j); - if(i < r) sort(i, r); - } + /** + * Sort match and targets array with QuickSort. + */ + private void sort( final int l, final int r ) { + int i = l; + int j = r; + int h; + final int m = match[(l + r) / 2]; + InstructionHandle h2; + do { + while (match[i] < m) { + i++; + } + while (m < match[j]) { + j--; + } + if (i <= j) { + h = match[i]; + match[i] = match[j]; + match[j] = h; // Swap elements + h2 = targets[i]; + targets[i] = targets[j]; + targets[j] = h2; // Swap instructions, too + i++; + j--; + } + } while (i <= j); + if (l < j) { + sort(l, j); + } + if (i < r) { + sort(i, r); + } + } - /** - * @return match is sorted in ascending order with no gap bigger than max_gap? - */ - private final boolean matchIsOrdered(int max_gap) { - for(int i=1; i < match_length; i++) - if(match[i] - match[i-1] > max_gap) - return false; - return true; - } + /** + * @return match is sorted in ascending order with no gap bigger than max_gap? + */ + private boolean matchIsOrdered( final int max_gap ) { + for (int i = 1; i < match_length; i++) { + if (match[i] - match[i - 1] > max_gap) { + return false; + } + } + return true; + } - public final InstructionList getInstructionList() { - return new InstructionList(instruction); - } - public final Instruction getInstruction() { - return instruction; - } + @Override + public final InstructionList getInstructionList() { + return new InstructionList(instruction); + } + + + public final Instruction getInstruction() { + return instruction; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java index 94d20cba11a..70d6213be88 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,214 +17,338 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions. * - * @author M. Dahm + *

    + * We use our super's target property as the default target. + * + * @version $Id: Select.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see LOOKUPSWITCH * @see TABLESWITCH * @see InstructionList */ -public abstract class Select extends BranchInstruction - implements VariableLengthInstruction, StackProducer -{ - protected int[] match; // matches, i.e., case 1: ... - protected int[] indices; // target offsets - protected InstructionHandle[] targets; // target objects in instruction list - protected int fixed_length; // fixed length defined by subclasses - protected int match_length; // number of cases - protected int padding = 0; // number of pad bytes for alignment +public abstract class Select extends BranchInstruction implements VariableLengthInstruction, + StackConsumer /* @since 6.0 */, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - Select() {} + private int[] match; // matches, i.e., case 1: ... TODO could be package-protected? + private int[] indices; // target offsets TODO could be package-protected? + private InstructionHandle[] targets; // target objects in instruction list TODO could be package-protected? + private int fixed_length; // fixed length defined by subclasses TODO could be package-protected? + private int match_length; // number of cases TODO could be package-protected? + private int padding = 0; // number of pad bytes for alignment TODO could be package-protected? - /** - * (Match, target) pairs for switch. - * `Match' and `targets' must have the same length of course. - * - * @param match array of matching values - * @param targets instruction targets - * @param target default instruction target - */ - Select(short opcode, int[] match, InstructionHandle[] targets, - InstructionHandle target) { - super(opcode, target); - - this.targets = targets; - for(int i=0; i < targets.length; i++) { - BranchInstruction.notifyTargetChanged(targets[i], this); - } - - this.match = match; - - if((match_length = match.length) != targets.length) - throw new ClassGenException("Match and target array have not the same length"); - - indices = new int[match_length]; - } - - /** - * Since this is a variable length instruction, it may shift the following - * instructions which then need to update their position. - * - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - @Override - protected int updatePosition(int offset, int max_offset) { - position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc. - - short old_length = length; - - /* Alignment on 4-byte-boundary, + 1, because of tag byte. + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. */ - padding = (4 - ((position + 1) % 4)) % 4; - length = (short)(fixed_length + padding); // Update length - - return length - old_length; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - - for(int i=0; i < padding; i++) // Padding bytes - out.writeByte(0); - - index = getTargetOffset(); // Write default target offset - out.writeInt(index); - } - - /** - * Read needed data (e.g. index) from file. - */ - @Override - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes - - for(int i=0; i < padding; i++) { - bytes.readByte(); + Select() { } - // Default branch target common for both cases (TABLESWITCH, LOOKUPSWITCH) - index = bytes.readInt(); - } - - /** - * @return mnemonic for instruction - */ - @Override - public String toString(boolean verbose) { - final StringBuilder buf = new StringBuilder(super.toString(verbose)); - - if(verbose) { - for(int i=0; i < match_length; i++) { - String s = "null"; - - if(targets[i] != null) - s = targets[i].getInstruction().toString(); - - buf.append("(").append(match[i]).append(", ") - .append(s).append(" = {").append(indices[i]).append("})"); - } - } - else - buf.append(" ..."); - - return buf.toString(); - } - - /** - * Set branch target for `i'th case - */ - public final void setTarget(int i, InstructionHandle target) { - notifyTargetChanging(targets[i], this); - targets[i] = target; - notifyTargetChanged(targets[i], this); - } - - /** - * @param old_ih old target - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if(target == old_ih) { - targeted = true; - setTarget(new_ih); + /** + * (Match, target) pairs for switch. `Match' and `targets' must have the + * same length of course. + * + * @param match array of matching values + * @param targets instruction targets + * @param defaultTarget default instruction target + */ + Select(final short opcode, final int[] match, final InstructionHandle[] targets, final InstructionHandle defaultTarget) { + // don't set default target before instuction is built + super(opcode, null); + this.match = match; + this.targets = targets; + // now it's safe to set default target + setTarget(defaultTarget); + for (final InstructionHandle target2 : targets) { + notifyTarget(null, target2, this); + } + if ((match_length = match.length) != targets.length) { + throw new ClassGenException("Match and target array have not the same length: Match length: " + + match.length + " Target length: " + targets.length); + } + indices = new int[match_length]; } - for(int i=0; i < targets.length; i++) { - if(targets[i] == old_ih) { - targeted = true; - setTarget(i, new_ih); - } + /** + * Since this is a variable length instruction, it may shift the following + * instructions which then need to update their position. + * + * Called by InstructionList.setPositions when setting the position for + * every instruction. In the presence of variable length instructions + * `setPositions' performs multiple passes over the instruction list to + * calculate the correct (byte) positions and offsets by calling this + * function. + * + * @param offset additional offset caused by preceding (variable length) + * instructions + * @param max_offset the maximum offset that may be caused by these + * instructions + * @return additional offset caused by possible change of this instruction's + * length + */ + @Override + protected int updatePosition(final int offset, final int max_offset) { + setPosition(getPosition() + offset); // Additional offset caused by preceding SWITCHs, GOTOs, etc. + final short old_length = (short) super.getLength(); + /* Alignment on 4-byte-boundary, + 1, because of tag byte. + */ + padding = (4 - ((getPosition() + 1) % 4)) % 4; + super.setLength((short) (fixed_length + padding)); // Update length + return super.getLength() - old_length; } - if(!targeted) - throw new ClassGenException("Not targeting " + old_ih); - } + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + for (int i = 0; i < padding; i++) { + out.writeByte(0); + } + super.setIndex(getTargetOffset()); // Write default target offset + out.writeInt(super.getIndex()); + } - /** - * @return true, if ih is target of this instruction - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - if(target == ih) - return true; + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes + for (int i = 0; i < padding; i++) { + bytes.readByte(); + } + // Default branch target common for both cases (TABLESWITCH, LOOKUPSWITCH) + super.setIndex(bytes.readInt()); + } - for(int i=0; i < targets.length; i++) - if(targets[i] == ih) - return true; + /** + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + final StringBuilder buf = new StringBuilder(super.toString(verbose)); + if (verbose) { + for (int i = 0; i < match_length; i++) { + String s = "null"; + if (targets[i] != null) { + s = targets[i].getInstruction().toString(); + } + buf.append("(").append(match[i]).append(", ").append(s).append(" = {").append( + indices[i]).append("})"); + } + } else { + buf.append(" ..."); + } + return buf.toString(); + } - return false; - } + /** + * Set branch target for `i'th case + */ + public void setTarget(final int i, final InstructionHandle target) { // TODO could be package-protected? + notifyTarget(targets[i], target, this); + targets[i] = target; + } - /** - * Inform targets that they're not targeted anymore. - */ - @Override - void dispose() { - super.dispose(); + /** + * @param old_ih old target + * @param new_ih new target + */ + @Override + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + boolean targeted = false; + if (super.getTarget() == old_ih) { + targeted = true; + setTarget(new_ih); + } + for (int i = 0; i < targets.length; i++) { + if (targets[i] == old_ih) { + targeted = true; + setTarget(i, new_ih); + } + } + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih); + } + } - for(int i=0; i < targets.length; i++) - targets[i].removeTargeter(this); - } + /** + * @return true, if ih is target of this instruction + */ + @Override + public boolean containsTarget(final InstructionHandle ih) { + if (super.getTarget() == ih) { + return true; + } + for (final InstructionHandle target2 : targets) { + if (target2 == ih) { + return true; + } + } + return false; + } - /** - * @return array of match indices - */ - public int[] getMatchs() { return match; } + @Override + protected Object clone() throws CloneNotSupportedException { + final Select copy = (Select) super.clone(); + copy.match = match.clone(); + copy.indices = indices.clone(); + copy.targets = targets.clone(); + return copy; + } - /** - * @return array of match target offsets - */ - public int[] getIndices() { return indices; } + /** + * Inform targets that they're not targeted anymore. + */ + @Override + void dispose() { + super.dispose(); + for (final InstructionHandle target2 : targets) { + target2.removeTargeter(this); + } + } - /** - * @return array of match targets - */ - public InstructionHandle[] getTargets() { return targets; } + /** + * @return array of match indices + */ + public int[] getMatchs() { + return match; + } + + /** + * @return array of match target offsets + */ + public int[] getIndices() { + return indices; + } + + /** + * @return array of match targets + */ + public InstructionHandle[] getTargets() { + return targets; + } + + /** + * @return match entry + * @since 6.0 + */ + final int getMatch(final int index) { + return match[index]; + } + + /** + * @return index entry from indices + * @since 6.0 + */ + final int getIndices(final int index) { + return indices[index]; + } + + /** + * @return target entry + * @since 6.0 + */ + final InstructionHandle getTarget(final int index) { + return targets[index]; + } + + /** + * @return the fixed_length + * @since 6.0 + */ + final int getFixed_length() { + return fixed_length; + } + + /** + * @param fixed_length the fixed_length to set + * @since 6.0 + */ + final void setFixed_length(final int fixed_length) { + this.fixed_length = fixed_length; + } + + /** + * @return the match_length + * @since 6.0 + */ + final int getMatch_length() { + return match_length; + } + + /** + * @param match_length the match_length to set + * @since 6.0 + */ + final int setMatch_length(final int match_length) { + this.match_length = match_length; + return match_length; + } + + /** + * + * @param index + * @param value + * @since 6.0 + */ + final void setMatch(final int index, final int value) { + match[index] = value; + } + + /** + * + * @param array + * @since 6.0 + */ + final void setIndices(final int[] array) { + indices = array; + } + + /** + * + * @param array + * @since 6.0 + */ + final void setMatches(final int[] array) { + match = array; + } + + /** + * + * @param array + * @since 6.0 + */ + final void setTargets(final InstructionHandle[] array) { + targets = array; + } + + /** + * + * @return the padding + * @since 6.0 + */ + final int getPadding() { + return padding; + } + + /** + * @since 6.0 + */ + final int setIndices(final int i, final int value) { + indices[i] = value; + return value; // Allow use in nested calls + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java new file mode 100644 index 00000000000..946d962fcf3 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java @@ -0,0 +1,273 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.ConstantDouble; +import com.sun.org.apache.bcel.internal.classfile.ConstantFloat; +import com.sun.org.apache.bcel.internal.classfile.ConstantInteger; +import com.sun.org.apache.bcel.internal.classfile.ConstantLong; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; +import com.sun.org.apache.bcel.internal.classfile.SimpleElementValue; + +/** + * @since 6.0 + */ +public class SimpleElementValueGen extends ElementValueGen +{ + // For primitive types and string type, this points to the value entry in + // the cpGen + // For 'class' this points to the class entry in the cpGen + private int idx; + + // ctors for each supported type... type could be inferred but for now lets + // force it to be passed + /** + * Protected ctor used for deserialization, doesn't *put* an entry in the + * constant pool, assumes the one at the supplied index is correct. + */ + protected SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen) + { + super(type, cpGen); + this.idx = idx; + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value) + { + super(type, cpGen); + idx = getConstantPool().addInteger(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value) + { + super(type, cpGen); + idx = getConstantPool().addLong(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value) + { + super(type, cpGen); + idx = getConstantPool().addDouble(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value) + { + super(type, cpGen); + idx = getConstantPool().addFloat(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value) + { + super(type, cpGen); + idx = getConstantPool().addInteger(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value) + { + super(type, cpGen); + idx = getConstantPool().addInteger(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value) + { + super(type, cpGen); + idx = getConstantPool().addInteger(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value) + { + super(type, cpGen); + if (value) { + idx = getConstantPool().addInteger(1); + } else { + idx = getConstantPool().addInteger(0); + } + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value) + { + super(type, cpGen); + idx = getConstantPool().addUtf8(value); + } + + /** + * The boolean controls whether we copy info from the 'old' constant pool to + * the 'new'. You need to use this ctor if the annotation is being copied + * from one file to another. + */ + public SimpleElementValueGen(final SimpleElementValue value, + final ConstantPoolGen cpool, final boolean copyPoolEntries) + { + super(value.getElementValueType(), cpool); + if (!copyPoolEntries) + { + // J5ASSERT: Could assert value.stringifyValue() is the same as + // cpool.getConstant(SimpleElementValuevalue.getIndex()) + idx = value.getIndex(); + } + else + { + switch (value.getElementValueType()) + { + case STRING: + idx = cpool.addUtf8(value.getValueString()); + break; + case PRIMITIVE_INT: + idx = cpool.addInteger(value.getValueInt()); + break; + case PRIMITIVE_BYTE: + idx = cpool.addInteger(value.getValueByte()); + break; + case PRIMITIVE_CHAR: + idx = cpool.addInteger(value.getValueChar()); + break; + case PRIMITIVE_LONG: + idx = cpool.addLong(value.getValueLong()); + break; + case PRIMITIVE_FLOAT: + idx = cpool.addFloat(value.getValueFloat()); + break; + case PRIMITIVE_DOUBLE: + idx = cpool.addDouble(value.getValueDouble()); + break; + case PRIMITIVE_BOOLEAN: + if (value.getValueBoolean()) + { + idx = cpool.addInteger(1); + } + else + { + idx = cpool.addInteger(0); + } + break; + case PRIMITIVE_SHORT: + idx = cpool.addInteger(value.getValueShort()); + break; + default: + throw new RuntimeException( + "SimpleElementValueGen class does not know how to copy this type " + super.getElementValueType()); + } + } + } + + /** + * Return immutable variant + */ + @Override + public ElementValue getElementValue() + { + return new SimpleElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool()); + } + + public int getIndex() + { + return idx; + } + + public String getValueString() + { + if (super.getElementValueType() != STRING) { + throw new RuntimeException( + "Dont call getValueString() on a non STRING ElementValue"); + } + final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx); + return c.getBytes(); + } + + public int getValueInt() + { + if (super.getElementValueType() != PRIMITIVE_INT) { + throw new RuntimeException( + "Dont call getValueString() on a non STRING ElementValue"); + } + final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); + return c.getBytes(); + } + + // Whatever kind of value it is, return it as a string + @Override + public String stringifyValue() + { + switch (super.getElementValueType()) + { + case PRIMITIVE_INT: + final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); + return Integer.toString(c.getBytes()); + case PRIMITIVE_LONG: + final ConstantLong j = (ConstantLong) getConstantPool().getConstant(idx); + return Long.toString(j.getBytes()); + case PRIMITIVE_DOUBLE: + final ConstantDouble d = (ConstantDouble) getConstantPool().getConstant(idx); + return Double.toString(d.getBytes()); + case PRIMITIVE_FLOAT: + final ConstantFloat f = (ConstantFloat) getConstantPool().getConstant(idx); + return Float.toString(f.getBytes()); + case PRIMITIVE_SHORT: + final ConstantInteger s = (ConstantInteger) getConstantPool().getConstant(idx); + return Integer.toString(s.getBytes()); + case PRIMITIVE_BYTE: + final ConstantInteger b = (ConstantInteger) getConstantPool().getConstant(idx); + return Integer.toString(b.getBytes()); + case PRIMITIVE_CHAR: + final ConstantInteger ch = (ConstantInteger) getConstantPool().getConstant(idx); + return Integer.toString(ch.getBytes()); + case PRIMITIVE_BOOLEAN: + final ConstantInteger bo = (ConstantInteger) getConstantPool().getConstant(idx); + if (bo.getBytes() == 0) { + return "false"; + } + return "true"; + case STRING: + final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); + return cu8.getBytes(); + default: + throw new RuntimeException( + "SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType()); + } + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 kind of value + switch (super.getElementValueType()) + { + case PRIMITIVE_INT: + case PRIMITIVE_BYTE: + case PRIMITIVE_CHAR: + case PRIMITIVE_FLOAT: + case PRIMITIVE_LONG: + case PRIMITIVE_BOOLEAN: + case PRIMITIVE_SHORT: + case PRIMITIVE_DOUBLE: + case STRING: + dos.writeShort(idx); + break; + default: + throw new RuntimeException( + "SimpleElementValueGen doesnt know how to write out type " + super.getElementValueType()); + } + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java index 1dd12439cfb..092c3e5e790 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java @@ -21,14 +21,14 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote an instruction that may consume a value from the stack. * - * @author M. Dahm + * @version $Id: StackConsumer.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface StackConsumer { - /** @return how many words are consumed from stack - */ - public int consumeStack(ConstantPoolGen cpg); + + /** @return how many words are consumed from stack + */ + int consumeStack( ConstantPoolGen cpg ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java index 82fdd2c89e3..c52fee76c87 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java @@ -21,29 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Super class for stack operations like DUP and POP. * - * @author M. Dahm + * @version $Id: StackInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ public abstract class StackInstruction extends Instruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - StackInstruction() {} - /** - * @param opcode instruction opcode - */ - protected StackInstruction(short opcode) { - super(opcode, (short)1); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + StackInstruction() { + } - /** @return Type.UNKNOWN - */ - public Type getType(ConstantPoolGen cp) { - return Type.UNKNOWN; - } + + /** + * @param opcode instruction opcode + */ + protected StackInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + /** @return Type.UNKNOWN + */ + public Type getType( final ConstantPoolGen cp ) { + return Type.UNKNOWN; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java index 9aa3795c040..4cc8a407051 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java @@ -21,15 +21,15 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote an instruction that may produce a value on top of the stack * (this excludes DUP_X1, e.g.) * - * @author M. Dahm + * @version $Id: StackProducer.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface StackProducer { - /** @return how many words are produced on stack - */ - public int produceStack(ConstantPoolGen cpg); + + /** @return how many words are produced on stack + */ + int produceStack( ConstantPoolGen cpg ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java index 3f27a250cc5..33d871bce79 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java @@ -21,47 +21,48 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an unparameterized instruction to store a value into a local variable, * e.g. ISTORE. * - * @author M. Dahm + * @version $Id: StoreInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class StoreInstruction extends LocalVariableInstruction - implements PopInstruction -{ - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - StoreInstruction(short canon_tag, short c_tag) { - super(canon_tag, c_tag); - } +public abstract class StoreInstruction extends LocalVariableInstruction implements PopInstruction { - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ASTORE_0, e.g. - * @param n local variable index (unsigned short) - */ - protected StoreInstruction(short opcode, short c_tag, int n) { - super(opcode, c_tag, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + * tag and length are defined in readInstruction and initFromFile, respectively. + */ + StoreInstruction(final short canon_tag, final short c_tag) { + super(canon_tag, c_tag); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLocalVariableInstruction(this); - v.visitStoreInstruction(this); - } + + /** + * @param opcode Instruction opcode + * @param c_tag Instruction number for compact version, ASTORE_0, e.g. + * @param n local variable index (unsigned short) + */ + protected StoreInstruction(final short opcode, final short c_tag, final int n) { + super(opcode, c_tag, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLocalVariableInstruction(this); + v.visitStoreInstruction(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java index 13d91c825c5..a0d994f1e9d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java @@ -21,94 +21,97 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * TABLESWITCH - Switch within given range of values, i.e., low..high * - * @author M. Dahm + * @version $Id: TABLESWITCH.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see SWITCH */ public class TABLESWITCH extends Select { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - TABLESWITCH() {} - /** - * @param match sorted array of match values, match[0] must be low value, - * match[match_length - 1] high value - * @param targets where to branch for matched values - * @param target default branch - */ - public TABLESWITCH(int[] match, InstructionHandle[] targets, - InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.TABLESWITCH, match, targets, target); - - length = (short)(13 + match_length * 4); /* Alignment remainder assumed - * 0 here, until dump time */ - fixed_length = length; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - - int low = (match_length > 0)? match[0] : 0; - out.writeInt(low); - - int high = (match_length > 0)? match[match_length - 1] : 0; - out.writeInt(high); - - for(int i=0; i < match_length; i++) // jump offsets - out.writeInt(indices[i] = getTargetOffset(targets[i])); - } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - super.initFromFile(bytes, wide); - - int low = bytes.readInt(); - int high = bytes.readInt(); - - match_length = high - low + 1; - fixed_length = (short)(13 + match_length * 4); - length = (short)(fixed_length + padding); - - match = new int[match_length]; - indices = new int[match_length]; - targets = new InstructionHandle[match_length]; - - for(int i=low; i <= high; i++) - match[i - low] = i; - - for(int i=0; i < match_length; i++) { - indices[i] = bytes.readInt(); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + TABLESWITCH() { } - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitVariableLengthInstruction(this); - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitSelect(this); - v.visitTABLESWITCH(this); - } + /** + * @param match sorted array of match values, match[0] must be low value, + * match[match_length - 1] high value + * @param targets where to branch for matched values + * @param defaultTarget default branch + */ + public TABLESWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle defaultTarget) { + super(com.sun.org.apache.bcel.internal.Const.TABLESWITCH, match, targets, defaultTarget); + /* Alignment remainder assumed 0 here, until dump time */ + final short _length = (short) (13 + getMatch_length() * 4); + super.setLength(_length); + setFixed_length(_length); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.dump(out); + final int _match_length = getMatch_length(); + final int low = (_match_length > 0) ? super.getMatch(0) : 0; + out.writeInt(low); + final int high = (_match_length > 0) ? super.getMatch(_match_length - 1) : 0; + out.writeInt(high); + for (int i = 0; i < _match_length; i++) { + out.writeInt(setIndices(i, getTargetOffset(super.getTarget(i)))); + } + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + final int low = bytes.readInt(); + final int high = bytes.readInt(); + final int _match_length = high - low + 1; + setMatch_length(_match_length); + final short _fixed_length = (short) (13 + _match_length * 4); + setFixed_length(_fixed_length); + super.setLength((short) (_fixed_length + super.getPadding())); + super.setMatches(new int[_match_length]); + super.setIndices(new int[_match_length]); + super.setTargets(new InstructionHandle[_match_length]); + for (int i = 0; i < _match_length; i++) { + super.setMatch(i, low + i); + super.setIndices(i, bytes.readInt()); + } + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitVariableLengthInstruction(this); + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitSelect(this); + v.visitTABLESWITCH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java index 2acd713f3a1..07c9f6c2877 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java @@ -21,47 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * Thrown by InstructionList.remove() when one or multiple disposed instruction - * are still being referenced by a InstructionTargeter object. I.e. the + * Thrown by InstructionList.remove() when one or multiple disposed instructions + * are still being referenced by an InstructionTargeter object. I.e. the * InstructionTargeter has to be notified that (one of) the InstructionHandle it * is referencing is being removed from the InstructionList and thus not valid anymore. * - * Making this an exception instead of a return value forces the user to handle + *

    Making this an exception instead of a return value forces the user to handle * these case explicitely in a try { ... } catch. The following code illustrates - * how this may be done: + * how this may be done:

    * *
      *     ...
      *     try {
    - *      il.delete(start_ih, end_ih);
    + *         il.delete(start_ih, end_ih);
      *     } catch(TargetLostException e) {
    - *       InstructionHandle[] targets = e.getTargets();
    - *       for(int i=0; i < targets.length; i++) {
    - *         InstructionTargeter[] targeters = targets[i].getTargeters();
    - *
    - *         for(int j=0; j < targeters.length; j++)
    - *           targeters[j].updateTarget(targets[i], new_target);
    - *       }
    + *         for (InstructionHandle target : e.getTargets()) {
    + *             for (InstructionTargeter targeter : target.getTargeters()) {
    + *                 targeter.updateTarget(target, new_target);
    + *             }
    + *         }
      *     }
      * 
    * * @see InstructionHandle * @see InstructionList * @see InstructionTargeter - * @author M. Dahm + * @version $Id: TargetLostException.java 1747278 2016-06-07 17:28:43Z britter $ */ public final class TargetLostException extends Exception { - private InstructionHandle[] targets; - TargetLostException(InstructionHandle[] t, String mesg) { - super(mesg); - targets = t; - } + private static final long serialVersionUID = -6857272667645328384L; + private final InstructionHandle[] targets; - /** - * @return list of instructions still being targeted. - */ - public InstructionHandle[] getTargets() { return targets; } + + TargetLostException(final InstructionHandle[] t, final String mesg) { + super(mesg); + targets = t; + } + + + /** + * @return list of instructions still being targeted. + */ + public InstructionHandle[] getTargets() { + return targets; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java index e936ca9b891..b370ca2c177 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,237 +17,374 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.ArrayList; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.ClassFormatException; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** - * Abstract super class for all possible java types, namely basic types - * such as int, object types like String and array types, e.g. int[] + * Abstract super class for all possible java types, namely basic types such as + * int, object types like String and array types, e.g. int[] * - * @author M. Dahm + * @version $Id: Type.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public abstract class Type implements java.io.Serializable { - protected byte type; - protected String signature; // signature for the type +public abstract class Type { - /** Predefined constants - */ - public static final BasicType VOID = new BasicType(Constants.T_VOID); - public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN); - public static final BasicType INT = new BasicType(Constants.T_INT); - public static final BasicType SHORT = new BasicType(Constants.T_SHORT); - public static final BasicType BYTE = new BasicType(Constants.T_BYTE); - public static final BasicType LONG = new BasicType(Constants.T_LONG); - public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE); - public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT); - public static final BasicType CHAR = new BasicType(Constants.T_CHAR); - public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); - public static final ObjectType STRING = new ObjectType("java.lang.String"); - public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); - public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); - public static final Type[] NO_ARGS = new Type[0]; - public static final ReferenceType NULL = new ReferenceType(){}; - public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, - ""){}; - - protected Type(byte t, String s) { - type = t; - signature = s; - } - - /** - * @return signature for given type. - */ - public String getSignature() { return signature; } - - /** - * @return type as defined in Constants - */ - public byte getType() { return type; } - - /** - * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise) - */ - public int getSize() { - switch(type) { - case Constants.T_DOUBLE: - case Constants.T_LONG: return 2; - case Constants.T_VOID: return 0; - default: return 1; - } - } - - /** - * @return Type string, e.g. `int[]' - */ - public String toString() { - return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN)))? signature : - Utility.signatureToString(signature, false); - } - - /** - * Convert type to Java method signature, e.g. int[] f(java.lang.String x) - * becomes (Ljava/lang/String;)[I - * - * @param return_type what the method returns - * @param arg_types what are the argument types - * @return method signature for given type(s). - */ - public static String getMethodSignature(Type return_type, Type[] arg_types) { - StringBuffer buf = new StringBuffer("("); - int length = (arg_types == null)? 0 : arg_types.length; - - for(int i=0; i < length; i++) - buf.append(arg_types[i].getSignature()); - - buf.append(')'); - buf.append(return_type.getSignature()); - - return buf.toString(); - } - - private static int consumed_chars=0; // Remember position in string, see getArgumentTypes - - /** - * Convert signature to a Type object. - * @param signature signature string such as Ljava/lang/String; - * @return type object - */ - public static final Type getType(String signature) - throws StringIndexOutOfBoundsException - { - byte type = Utility.typeOfSignature(signature); - - if(type <= Constants.T_VOID) { - consumed_chars = 1; - return BasicType.getType(type); - } else if(type == Constants.T_ARRAY) { - int dim=0; - do { // Count dimensions - dim++; - } while(signature.charAt(dim) == '['); - - // Recurse, but just once, if the signature is ok - Type t = getType(signature.substring(dim)); - - consumed_chars += dim; // update counter - - return new ArrayType(t, dim); - } else { // type == T_REFERENCE - int index = signature.indexOf(';'); // Look for closing `;' - - if(index < 0) - throw new ClassFormatException("Invalid signature: " + signature); - - consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed - - return new ObjectType(signature.substring(1, index).replace('/', '.')); - } - } - - /** - * Convert return value of a method (signature) to a Type object. - * - * @param signature signature string such as (Ljava/lang/String;)V - * @return return type - */ - public static Type getReturnType(String signature) { - try { - // Read return type after `)' - int index = signature.lastIndexOf(')') + 1; - return getType(signature.substring(index)); - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - /** - * Convert arguments of a method (signature) to an array of Type objects. - * @param signature signature string such as (Ljava/lang/String;)V - * @return array of argument types - */ - public static Type[] getArgumentTypes(String signature) { - ArrayList vec = new ArrayList(); - int index; - Type[] types; - - try { // Read all declarations between for `(' and `)' - if(signature.charAt(0) != '(') - throw new ClassFormatException("Invalid method signature: " + signature); - - index = 1; // current string position - - while(signature.charAt(index) != ')') { - vec.add(getType(signature.substring(index))); - index += consumed_chars; // update position - } - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - - types = new Type[vec.size()]; - vec.toArray(types); - return types; - } - - /** Convert runtime java.lang.Class to BCEL Type object. - * @param cl Java class - * @return corresponding Type object - */ - public static Type getType(java.lang.Class cl) { - if(cl == null) { - throw new IllegalArgumentException("Class must not be null"); - } - - /* That's an amzingly easy case, because getName() returns - * the signature. That's what we would have liked anyway. + private final byte type; + private String signature; // signature for the type + /** + * Predefined constants */ - if(cl.isArray()) { - return getType(cl.getName()); - } else if(cl.isPrimitive()) { - if(cl == Integer.TYPE) { - return INT; - } else if(cl == Void.TYPE) { - return VOID; - } else if(cl == Double.TYPE) { - return DOUBLE; - } else if(cl == Float.TYPE) { - return FLOAT; - } else if(cl == Boolean.TYPE) { - return BOOLEAN; - } else if(cl == Byte.TYPE) { - return BYTE; - } else if(cl == Short.TYPE) { - return SHORT; - } else if(cl == Byte.TYPE) { - return BYTE; - } else if(cl == Long.TYPE) { - return LONG; - } else if(cl == Character.TYPE) { - return CHAR; - } else { - throw new IllegalStateException("Ooops, what primitive type is " + cl); - } - } else { // "Real" class - return new ObjectType(cl.getName()); - } - } + public static final BasicType VOID = new BasicType(Const.T_VOID); + public static final BasicType BOOLEAN = new BasicType(Const.T_BOOLEAN); + public static final BasicType INT = new BasicType(Const.T_INT); + public static final BasicType SHORT = new BasicType(Const.T_SHORT); + public static final BasicType BYTE = new BasicType(Const.T_BYTE); + public static final BasicType LONG = new BasicType(Const.T_LONG); + public static final BasicType DOUBLE = new BasicType(Const.T_DOUBLE); + public static final BasicType FLOAT = new BasicType(Const.T_FLOAT); + public static final BasicType CHAR = new BasicType(Const.T_CHAR); + public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); + public static final ObjectType CLASS = new ObjectType("java.lang.Class"); + public static final ObjectType STRING = new ObjectType("java.lang.String"); + public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); + public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); + public static final Type[] NO_ARGS = new Type[0]; // EMPTY, so immutable + public static final ReferenceType NULL = new ReferenceType() { + }; + public static final Type UNKNOWN = new Type(Const.T_UNKNOWN, "") { + }; - public static String getSignature(java.lang.reflect.Method meth) { - StringBuffer sb = new StringBuffer("("); - Class[] params = meth.getParameterTypes(); // avoid clone - - for(int j = 0; j < params.length; j++) { - sb.append(getType(params[j]).getSignature()); + protected Type(final byte t, final String s) { + type = t; + signature = s; } - sb.append(")"); - sb.append(getType(meth.getReturnType()).getSignature()); - return sb.toString(); - } + /** + * @return hashcode of Type + */ + @Override + public int hashCode() { + return type ^ signature.hashCode(); + } + + /** + * @return whether the Types are equal + */ + @Override + public boolean equals(final Object o) { + if (o instanceof Type) { + final Type t = (Type) o; + return (type == t.type) && signature.equals(t.signature); + } + return false; + } + + /** + * @return signature for given type. + */ + public String getSignature() { + return signature; + } + + /** + * @return type as defined in Constants + */ + public byte getType() { + return type; + } + + /** + * boolean, short and char variable are considered as int in the stack or + * local variable area. Returns {@link Type#INT} for + * {@link Type#BOOLEAN}, {@link Type#SHORT} or {@link Type#CHAR}, otherwise + * returns the given type. + * + * @since 6.0 + */ + public Type normalizeForStackOrLocal() { + if (this == Type.BOOLEAN || this == Type.BYTE || this == Type.SHORT || this == Type.CHAR) { + return Type.INT; + } + return this; + } + + /** + * @return stack size of this type (2 for long and double, 0 for void, 1 + * otherwise) + */ + public int getSize() { + switch (type) { + case Const.T_DOUBLE: + case Const.T_LONG: + return 2; + case Const.T_VOID: + return 0; + default: + return 1; + } + } + + /** + * @return Type string, e.g. `int[]' + */ + @Override + public String toString() { + return ((this.equals(Type.NULL) || (type >= Const.T_UNKNOWN))) ? signature : Utility + .signatureToString(signature, false); + } + + /** + * Convert type to Java method signature, e.g. int[] f(java.lang.String x) + * becomes (Ljava/lang/String;)[I + * + * @param return_type what the method returns + * @param arg_types what are the argument types + * @return method signature for given type(s). + */ + public static String getMethodSignature(final Type return_type, final Type[] arg_types) { + final StringBuilder buf = new StringBuilder("("); + if (arg_types != null) { + for (final Type arg_type : arg_types) { + buf.append(arg_type.getSignature()); + } + } + buf.append(')'); + buf.append(return_type.getSignature()); + return buf.toString(); + } + + private static final ThreadLocal consumed_chars = new ThreadLocal() { + + @Override + protected Integer initialValue() { + return Integer.valueOf(0); + } + };//int consumed_chars=0; // Remember position in string, see getArgumentTypes + + private static int unwrap(final ThreadLocal tl) { + return tl.get().intValue(); + } + + private static void wrap(final ThreadLocal tl, final int value) { + tl.set(Integer.valueOf(value)); + } + + /** + * Convert signature to a Type object. + * + * @param signature signature string such as Ljava/lang/String; + * @return type object + */ + // @since 6.0 no longer final + public static Type getType(final String signature) throws StringIndexOutOfBoundsException { + final byte type = Utility.typeOfSignature(signature); + if (type <= Const.T_VOID) { + //corrected concurrent private static field acess + wrap(consumed_chars, 1); + return BasicType.getType(type); + } else if (type == Const.T_ARRAY) { + int dim = 0; + do { // Count dimensions + dim++; + } while (signature.charAt(dim) == '['); + // Recurse, but just once, if the signature is ok + final Type t = getType(signature.substring(dim)); + //corrected concurrent private static field acess + // consumed_chars += dim; // update counter - is replaced by + final int _temp = unwrap(consumed_chars) + dim; + wrap(consumed_chars, _temp); + return new ArrayType(t, dim); + } else { // type == T_REFERENCE + // Utility.signatureToString understands how to parse + // generic types. + final String parsedSignature = Utility.signatureToString(signature, false); + wrap(consumed_chars, parsedSignature.length() + 2); // "Lblabla;" `L' and `;' are removed + return ObjectType.getInstance(parsedSignature.replace('/', '.')); + } + } + + /** + * Convert return value of a method (signature) to a Type object. + * + * @param signature signature string such as (Ljava/lang/String;)V + * @return return type + */ + public static Type getReturnType(final String signature) { + try { + // Read return type after `)' + final int index = signature.lastIndexOf(')') + 1; + return getType(signature.substring(index)); + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + } + + /** + * Convert arguments of a method (signature) to an array of Type objects. + * + * @param signature signature string such as (Ljava/lang/String;)V + * @return array of argument types + */ + public static Type[] getArgumentTypes(final String signature) { + final List vec = new ArrayList<>(); + int index; + Type[] types; + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + index = 1; // current string position + while (signature.charAt(index) != ')') { + vec.add(getType(signature.substring(index))); + //corrected concurrent private static field acess + index += unwrap(consumed_chars); // update position + } + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + types = new Type[vec.size()]; + vec.toArray(types); + return types; + } + + /** + * Convert runtime java.lang.Class to BCEL Type object. + * + * @param cl Java class + * @return corresponding Type object + */ + public static Type getType(final java.lang.Class cl) { + if (cl == null) { + throw new IllegalArgumentException("Class must not be null"); + } + /* That's an amzingly easy case, because getName() returns + * the signature. That's what we would have liked anyway. + */ + if (cl.isArray()) { + return getType(cl.getName()); + } else if (cl.isPrimitive()) { + if (cl == Integer.TYPE) { + return INT; + } else if (cl == Void.TYPE) { + return VOID; + } else if (cl == Double.TYPE) { + return DOUBLE; + } else if (cl == Float.TYPE) { + return FLOAT; + } else if (cl == Boolean.TYPE) { + return BOOLEAN; + } else if (cl == Byte.TYPE) { + return BYTE; + } else if (cl == Short.TYPE) { + return SHORT; + } else if (cl == Byte.TYPE) { + return BYTE; + } else if (cl == Long.TYPE) { + return LONG; + } else if (cl == Character.TYPE) { + return CHAR; + } else { + throw new IllegalStateException("Ooops, what primitive type is " + cl); + } + } else { // "Real" class + return ObjectType.getInstance(cl.getName()); + } + } + + /** + * Convert runtime java.lang.Class[] to BCEL Type objects. + * + * @param classes an array of runtime class objects + * @return array of corresponding Type objects + */ + public static Type[] getTypes(final java.lang.Class[] classes) { + final Type[] ret = new Type[classes.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = getType(classes[i]); + } + return ret; + } + + public static String getSignature(final java.lang.reflect.Method meth) { + final StringBuilder sb = new StringBuilder("("); + final Class[] params = meth.getParameterTypes(); // avoid clone + for (final Class param : params) { + sb.append(getType(param).getSignature()); + } + sb.append(")"); + sb.append(getType(meth.getReturnType()).getSignature()); + return sb.toString(); + } + + static int size(final int coded) { + return coded & 3; + } + + static int consumed(final int coded) { + return coded >> 2; + } + + static int encode(final int size, final int consumed) { + return consumed << 2 | size; + } + + static int getArgumentTypesSize(final String signature) { + int res = 0; + int index; + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + index = 1; // current string position + while (signature.charAt(index) != ')') { + final int coded = getTypeSize(signature.substring(index)); + res += size(coded); + index += consumed(coded); + } + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + return res; + } + + static int getTypeSize(final String signature) throws StringIndexOutOfBoundsException { + final byte type = Utility.typeOfSignature(signature); + if (type <= Const.T_VOID) { + return encode(BasicType.getType(type).getSize(), 1); + } else if (type == Const.T_ARRAY) { + int dim = 0; + do { // Count dimensions + dim++; + } while (signature.charAt(dim) == '['); + // Recurse, but just once, if the signature is ok + final int consumed = consumed(getTypeSize(signature.substring(dim))); + return encode(1, dim + consumed); + } else { // type == T_REFERENCE + final int index = signature.indexOf(';'); // Look for closing `;' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + return encode(1, index + 1); + } + } + + static int getReturnTypeSize(final String signature) { + final int index = signature.lastIndexOf(')') + 1; + return Type.size(getTypeSize(signature.substring(index))); + } + + + /* + * Currently only used by the ArrayType constructor. + * The signature has a complicated dependency on other parameter + * so it's tricky to do it in a call to the super ctor. + */ + void setSignature(final String signature) { + this.signature = signature; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java index 6332a4e5747..b16702d2a80 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Get the type associated with an instruction, int for ILOAD, or the type * of the field of a PUTFIELD instruction, e.g.. * - * @author M. Dahm + * @version $Id: TypedInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface TypedInstruction { - public Type getType(ConstantPoolGen cpg); + + Type getType( ConstantPoolGen cpg ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java index 5c96001f0c2..533626bcf72 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an instruction to perform an unconditional branch, i.e., GOTO, JSR. * - * @author M. Dahm + * @version $Id: UnconditionalBranch.java 1747278 2016-06-07 17:28:43Z britter $ * @see GOTO * @see JSR */ -public interface UnconditionalBranch {} +public interface UnconditionalBranch { +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java index 6395b8d9ec0..c1b2785433f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java @@ -21,16 +21,16 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an instruction to be a variable length instruction, such as * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH. * - * @author M. Dahm + * @version $Id: VariableLengthInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see GOTO * @see JSR * @see LOOKUPSWITCH * @see TABLESWITCH */ -public interface VariableLengthInstruction {} +public interface VariableLengthInstruction { +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java index 0a1eb5ee1d5..e4947b02bee 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java @@ -21,194 +21,558 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Interface implementing the Visitor pattern programming style. * I.e., a class that implements this interface can handle all types of * instructions with the properly typed methods just by calling the accept() * method. * - * @author M. Dahm + * @version $Id: Visitor.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface Visitor { - public void visitStackInstruction(StackInstruction obj); - public void visitLocalVariableInstruction(LocalVariableInstruction obj); - public void visitBranchInstruction(BranchInstruction obj); - public void visitLoadClass(LoadClass obj); - public void visitFieldInstruction(FieldInstruction obj); - public void visitIfInstruction(IfInstruction obj); - public void visitConversionInstruction(ConversionInstruction obj); - public void visitPopInstruction(PopInstruction obj); - public void visitStoreInstruction(StoreInstruction obj); - public void visitTypedInstruction(TypedInstruction obj); - public void visitSelect(Select obj); - public void visitJsrInstruction(JsrInstruction obj); - public void visitGotoInstruction(GotoInstruction obj); - public void visitUnconditionalBranch(UnconditionalBranch obj); - public void visitPushInstruction(PushInstruction obj); - public void visitArithmeticInstruction(ArithmeticInstruction obj); - public void visitCPInstruction(CPInstruction obj); - public void visitInvokeInstruction(InvokeInstruction obj); - public void visitArrayInstruction(ArrayInstruction obj); - public void visitAllocationInstruction(AllocationInstruction obj); - public void visitReturnInstruction(ReturnInstruction obj); - public void visitFieldOrMethod(FieldOrMethod obj); - public void visitConstantPushInstruction(ConstantPushInstruction obj); - public void visitExceptionThrower(ExceptionThrower obj); - public void visitLoadInstruction(LoadInstruction obj); - public void visitVariableLengthInstruction(VariableLengthInstruction obj); - public void visitStackProducer(StackProducer obj); - public void visitStackConsumer(StackConsumer obj); - public void visitACONST_NULL(ACONST_NULL obj); - public void visitGETSTATIC(GETSTATIC obj); - public void visitIF_ICMPLT(IF_ICMPLT obj); - public void visitMONITOREXIT(MONITOREXIT obj); - public void visitIFLT(IFLT obj); - public void visitLSTORE(LSTORE obj); - public void visitPOP2(POP2 obj); - public void visitBASTORE(BASTORE obj); - public void visitISTORE(ISTORE obj); - public void visitCHECKCAST(CHECKCAST obj); - public void visitFCMPG(FCMPG obj); - public void visitI2F(I2F obj); - public void visitATHROW(ATHROW obj); - public void visitDCMPL(DCMPL obj); - public void visitARRAYLENGTH(ARRAYLENGTH obj); - public void visitDUP(DUP obj); - public void visitINVOKESTATIC(INVOKESTATIC obj); - public void visitLCONST(LCONST obj); - public void visitDREM(DREM obj); - public void visitIFGE(IFGE obj); - public void visitCALOAD(CALOAD obj); - public void visitLASTORE(LASTORE obj); - public void visitI2D(I2D obj); - public void visitDADD(DADD obj); - public void visitINVOKESPECIAL(INVOKESPECIAL obj); - public void visitIAND(IAND obj); - public void visitPUTFIELD(PUTFIELD obj); - public void visitILOAD(ILOAD obj); - public void visitDLOAD(DLOAD obj); - public void visitDCONST(DCONST obj); - public void visitNEW(NEW obj); - public void visitIFNULL(IFNULL obj); - public void visitLSUB(LSUB obj); - public void visitL2I(L2I obj); - public void visitISHR(ISHR obj); - public void visitTABLESWITCH(TABLESWITCH obj); - public void visitIINC(IINC obj); - public void visitDRETURN(DRETURN obj); - public void visitFSTORE(FSTORE obj); - public void visitDASTORE(DASTORE obj); - public void visitIALOAD(IALOAD obj); - public void visitDDIV(DDIV obj); - public void visitIF_ICMPGE(IF_ICMPGE obj); - public void visitLAND(LAND obj); - public void visitIDIV(IDIV obj); - public void visitLOR(LOR obj); - public void visitCASTORE(CASTORE obj); - public void visitFREM(FREM obj); - public void visitLDC(LDC obj); - public void visitBIPUSH(BIPUSH obj); - public void visitDSTORE(DSTORE obj); - public void visitF2L(F2L obj); - public void visitFMUL(FMUL obj); - public void visitLLOAD(LLOAD obj); - public void visitJSR(JSR obj); - public void visitFSUB(FSUB obj); - public void visitSASTORE(SASTORE obj); - public void visitALOAD(ALOAD obj); - public void visitDUP2_X2(DUP2_X2 obj); - public void visitRETURN(RETURN obj); - public void visitDALOAD(DALOAD obj); - public void visitSIPUSH(SIPUSH obj); - public void visitDSUB(DSUB obj); - public void visitL2F(L2F obj); - public void visitIF_ICMPGT(IF_ICMPGT obj); - public void visitF2D(F2D obj); - public void visitI2L(I2L obj); - public void visitIF_ACMPNE(IF_ACMPNE obj); - public void visitPOP(POP obj); - public void visitI2S(I2S obj); - public void visitIFEQ(IFEQ obj); - public void visitSWAP(SWAP obj); - public void visitIOR(IOR obj); - public void visitIREM(IREM obj); - public void visitIASTORE(IASTORE obj); - public void visitNEWARRAY(NEWARRAY obj); - public void visitINVOKEINTERFACE(INVOKEINTERFACE obj); - public void visitINEG(INEG obj); - public void visitLCMP(LCMP obj); - public void visitJSR_W(JSR_W obj); - public void visitMULTIANEWARRAY(MULTIANEWARRAY obj); - public void visitDUP_X2(DUP_X2 obj); - public void visitSALOAD(SALOAD obj); - public void visitIFNONNULL(IFNONNULL obj); - public void visitDMUL(DMUL obj); - public void visitIFNE(IFNE obj); - public void visitIF_ICMPLE(IF_ICMPLE obj); - public void visitLDC2_W(LDC2_W obj); - public void visitGETFIELD(GETFIELD obj); - public void visitLADD(LADD obj); - public void visitNOP(NOP obj); - public void visitFALOAD(FALOAD obj); - public void visitINSTANCEOF(INSTANCEOF obj); - public void visitIFLE(IFLE obj); - public void visitLXOR(LXOR obj); - public void visitLRETURN(LRETURN obj); - public void visitFCONST(FCONST obj); - public void visitIUSHR(IUSHR obj); - public void visitBALOAD(BALOAD obj); - public void visitDUP2(DUP2 obj); - public void visitIF_ACMPEQ(IF_ACMPEQ obj); - public void visitIMPDEP1(IMPDEP1 obj); - public void visitMONITORENTER(MONITORENTER obj); - public void visitLSHL(LSHL obj); - public void visitDCMPG(DCMPG obj); - public void visitD2L(D2L obj); - public void visitIMPDEP2(IMPDEP2 obj); - public void visitL2D(L2D obj); - public void visitRET(RET obj); - public void visitIFGT(IFGT obj); - public void visitIXOR(IXOR obj); - public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj); - public void visitFASTORE(FASTORE obj); - public void visitIRETURN(IRETURN obj); - public void visitIF_ICMPNE(IF_ICMPNE obj); - public void visitFLOAD(FLOAD obj); - public void visitLDIV(LDIV obj); - public void visitPUTSTATIC(PUTSTATIC obj); - public void visitAALOAD(AALOAD obj); - public void visitD2I(D2I obj); - public void visitIF_ICMPEQ(IF_ICMPEQ obj); - public void visitAASTORE(AASTORE obj); - public void visitARETURN(ARETURN obj); - public void visitDUP2_X1(DUP2_X1 obj); - public void visitFNEG(FNEG obj); - public void visitGOTO_W(GOTO_W obj); - public void visitD2F(D2F obj); - public void visitGOTO(GOTO obj); - public void visitISUB(ISUB obj); - public void visitF2I(F2I obj); - public void visitDNEG(DNEG obj); - public void visitICONST(ICONST obj); - public void visitFDIV(FDIV obj); - public void visitI2B(I2B obj); - public void visitLNEG(LNEG obj); - public void visitLREM(LREM obj); - public void visitIMUL(IMUL obj); - public void visitIADD(IADD obj); - public void visitLSHR(LSHR obj); - public void visitLOOKUPSWITCH(LOOKUPSWITCH obj); - public void visitDUP_X1(DUP_X1 obj); - public void visitFCMPL(FCMPL obj); - public void visitI2C(I2C obj); - public void visitLMUL(LMUL obj); - public void visitLUSHR(LUSHR obj); - public void visitISHL(ISHL obj); - public void visitLALOAD(LALOAD obj); - public void visitASTORE(ASTORE obj); - public void visitANEWARRAY(ANEWARRAY obj); - public void visitFRETURN(FRETURN obj); - public void visitFADD(FADD obj); - public void visitBREAKPOINT(BREAKPOINT obj); + + void visitStackInstruction( StackInstruction obj ); + + + void visitLocalVariableInstruction( LocalVariableInstruction obj ); + + + void visitBranchInstruction( BranchInstruction obj ); + + + void visitLoadClass( LoadClass obj ); + + + void visitFieldInstruction( FieldInstruction obj ); + + + void visitIfInstruction( IfInstruction obj ); + + + void visitConversionInstruction( ConversionInstruction obj ); + + + void visitPopInstruction( PopInstruction obj ); + + + void visitStoreInstruction( StoreInstruction obj ); + + + void visitTypedInstruction( TypedInstruction obj ); + + + void visitSelect( Select obj ); + + + void visitJsrInstruction( JsrInstruction obj ); + + + void visitGotoInstruction( GotoInstruction obj ); + + + void visitUnconditionalBranch( UnconditionalBranch obj ); + + + void visitPushInstruction( PushInstruction obj ); + + + void visitArithmeticInstruction( ArithmeticInstruction obj ); + + + void visitCPInstruction( CPInstruction obj ); + + + void visitInvokeInstruction( InvokeInstruction obj ); + + + void visitArrayInstruction( ArrayInstruction obj ); + + + void visitAllocationInstruction( AllocationInstruction obj ); + + + void visitReturnInstruction( ReturnInstruction obj ); + + + void visitFieldOrMethod( FieldOrMethod obj ); + + + void visitConstantPushInstruction( ConstantPushInstruction obj ); + + + void visitExceptionThrower( ExceptionThrower obj ); + + + void visitLoadInstruction( LoadInstruction obj ); + + + void visitVariableLengthInstruction( VariableLengthInstruction obj ); + + + void visitStackProducer( StackProducer obj ); + + + void visitStackConsumer( StackConsumer obj ); + + + void visitACONST_NULL( ACONST_NULL obj ); + + + void visitGETSTATIC( GETSTATIC obj ); + + + void visitIF_ICMPLT( IF_ICMPLT obj ); + + + void visitMONITOREXIT( MONITOREXIT obj ); + + + void visitIFLT( IFLT obj ); + + + void visitLSTORE( LSTORE obj ); + + + void visitPOP2( POP2 obj ); + + + void visitBASTORE( BASTORE obj ); + + + void visitISTORE( ISTORE obj ); + + + void visitCHECKCAST( CHECKCAST obj ); + + + void visitFCMPG( FCMPG obj ); + + + void visitI2F( I2F obj ); + + + void visitATHROW( ATHROW obj ); + + + void visitDCMPL( DCMPL obj ); + + + void visitARRAYLENGTH( ARRAYLENGTH obj ); + + + void visitDUP( DUP obj ); + + + void visitINVOKESTATIC( INVOKESTATIC obj ); + + + void visitLCONST( LCONST obj ); + + + void visitDREM( DREM obj ); + + + void visitIFGE( IFGE obj ); + + + void visitCALOAD( CALOAD obj ); + + + void visitLASTORE( LASTORE obj ); + + + void visitI2D( I2D obj ); + + + void visitDADD( DADD obj ); + + + void visitINVOKESPECIAL( INVOKESPECIAL obj ); + + + void visitIAND( IAND obj ); + + + void visitPUTFIELD( PUTFIELD obj ); + + + void visitILOAD( ILOAD obj ); + + + void visitDLOAD( DLOAD obj ); + + + void visitDCONST( DCONST obj ); + + + void visitNEW( NEW obj ); + + + void visitIFNULL( IFNULL obj ); + + + void visitLSUB( LSUB obj ); + + + void visitL2I( L2I obj ); + + + void visitISHR( ISHR obj ); + + + void visitTABLESWITCH( TABLESWITCH obj ); + + + void visitIINC( IINC obj ); + + + void visitDRETURN( DRETURN obj ); + + + void visitFSTORE( FSTORE obj ); + + + void visitDASTORE( DASTORE obj ); + + + void visitIALOAD( IALOAD obj ); + + + void visitDDIV( DDIV obj ); + + + void visitIF_ICMPGE( IF_ICMPGE obj ); + + + void visitLAND( LAND obj ); + + + void visitIDIV( IDIV obj ); + + + void visitLOR( LOR obj ); + + + void visitCASTORE( CASTORE obj ); + + + void visitFREM( FREM obj ); + + + void visitLDC( LDC obj ); + + + void visitBIPUSH( BIPUSH obj ); + + + void visitDSTORE( DSTORE obj ); + + + void visitF2L( F2L obj ); + + + void visitFMUL( FMUL obj ); + + + void visitLLOAD( LLOAD obj ); + + + void visitJSR( JSR obj ); + + + void visitFSUB( FSUB obj ); + + + void visitSASTORE( SASTORE obj ); + + + void visitALOAD( ALOAD obj ); + + + void visitDUP2_X2( DUP2_X2 obj ); + + + void visitRETURN( RETURN obj ); + + + void visitDALOAD( DALOAD obj ); + + + void visitSIPUSH( SIPUSH obj ); + + + void visitDSUB( DSUB obj ); + + + void visitL2F( L2F obj ); + + + void visitIF_ICMPGT( IF_ICMPGT obj ); + + + void visitF2D( F2D obj ); + + + void visitI2L( I2L obj ); + + + void visitIF_ACMPNE( IF_ACMPNE obj ); + + + void visitPOP( POP obj ); + + + void visitI2S( I2S obj ); + + + void visitIFEQ( IFEQ obj ); + + + void visitSWAP( SWAP obj ); + + + void visitIOR( IOR obj ); + + + void visitIREM( IREM obj ); + + + void visitIASTORE( IASTORE obj ); + + + void visitNEWARRAY( NEWARRAY obj ); + + + void visitINVOKEINTERFACE( INVOKEINTERFACE obj ); + + + void visitINEG( INEG obj ); + + + void visitLCMP( LCMP obj ); + + + void visitJSR_W( JSR_W obj ); + + + void visitMULTIANEWARRAY( MULTIANEWARRAY obj ); + + + void visitDUP_X2( DUP_X2 obj ); + + + void visitSALOAD( SALOAD obj ); + + + void visitIFNONNULL( IFNONNULL obj ); + + + void visitDMUL( DMUL obj ); + + + void visitIFNE( IFNE obj ); + + + void visitIF_ICMPLE( IF_ICMPLE obj ); + + + void visitLDC2_W( LDC2_W obj ); + + + void visitGETFIELD( GETFIELD obj ); + + + void visitLADD( LADD obj ); + + + void visitNOP( NOP obj ); + + + void visitFALOAD( FALOAD obj ); + + + void visitINSTANCEOF( INSTANCEOF obj ); + + + void visitIFLE( IFLE obj ); + + + void visitLXOR( LXOR obj ); + + + void visitLRETURN( LRETURN obj ); + + + void visitFCONST( FCONST obj ); + + + void visitIUSHR( IUSHR obj ); + + + void visitBALOAD( BALOAD obj ); + + + void visitDUP2( DUP2 obj ); + + + void visitIF_ACMPEQ( IF_ACMPEQ obj ); + + + void visitIMPDEP1( IMPDEP1 obj ); + + + void visitMONITORENTER( MONITORENTER obj ); + + + void visitLSHL( LSHL obj ); + + + void visitDCMPG( DCMPG obj ); + + + void visitD2L( D2L obj ); + + + void visitIMPDEP2( IMPDEP2 obj ); + + + void visitL2D( L2D obj ); + + + void visitRET( RET obj ); + + + void visitIFGT( IFGT obj ); + + + void visitIXOR( IXOR obj ); + + + void visitINVOKEVIRTUAL( INVOKEVIRTUAL obj ); + + + /** + * @since 6.0 + */ + void visitINVOKEDYNAMIC( INVOKEDYNAMIC obj ); + + + void visitFASTORE( FASTORE obj ); + + + void visitIRETURN( IRETURN obj ); + + + void visitIF_ICMPNE( IF_ICMPNE obj ); + + + void visitFLOAD( FLOAD obj ); + + + void visitLDIV( LDIV obj ); + + + void visitPUTSTATIC( PUTSTATIC obj ); + + + void visitAALOAD( AALOAD obj ); + + + void visitD2I( D2I obj ); + + + void visitIF_ICMPEQ( IF_ICMPEQ obj ); + + + void visitAASTORE( AASTORE obj ); + + + void visitARETURN( ARETURN obj ); + + + void visitDUP2_X1( DUP2_X1 obj ); + + + void visitFNEG( FNEG obj ); + + + void visitGOTO_W( GOTO_W obj ); + + + void visitD2F( D2F obj ); + + + void visitGOTO( GOTO obj ); + + + void visitISUB( ISUB obj ); + + + void visitF2I( F2I obj ); + + + void visitDNEG( DNEG obj ); + + + void visitICONST( ICONST obj ); + + + void visitFDIV( FDIV obj ); + + + void visitI2B( I2B obj ); + + + void visitLNEG( LNEG obj ); + + + void visitLREM( LREM obj ); + + + void visitIMUL( IMUL obj ); + + + void visitIADD( IADD obj ); + + + void visitLSHR( LSHR obj ); + + + void visitLOOKUPSWITCH( LOOKUPSWITCH obj ); + + + void visitDUP_X1( DUP_X1 obj ); + + + void visitFCMPL( FCMPL obj ); + + + void visitI2C( I2C obj ); + + + void visitLMUL( LMUL obj ); + + + void visitLUSHR( LUSHR obj ); + + + void visitISHL( ISHL obj ); + + + void visitLALOAD( LALOAD obj ); + + + void visitASTORE( ASTORE obj ); + + + void visitANEWARRAY( ANEWARRAY obj ); + + + void visitFRETURN( FRETURN obj ); + + + void visitFADD( FADD obj ); + + + void visitBREAKPOINT( BREAKPOINT obj ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/package.html b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/package.html index e39189be9d8..d8a276d067b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/package.html +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/package.html @@ -1,14 +1,30 @@ +

    This package contains the "generic" part of the -Byte Code Engineering +Byte Code Engineering Library, i.e., classes to dynamically modify class objects and byte code instructions.

    diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/package.html b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/package.html index 92de99d1fbd..2b6dd18ef9b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/package.html +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/package.html @@ -1,16 +1,32 @@ +

    This package contains basic classes for the -Byte Code Engineering Library +Byte Code Engineering Library and constants defined by the - + JVM specification.

    diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java index 15417bdd19a..b7246b8f200 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java @@ -21,202 +21,197 @@ package com.sun.org.apache.bcel.internal.util; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Code; +import com.sun.org.apache.bcel.internal.classfile.CodeException; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.ExceptionTable; +import com.sun.org.apache.bcel.internal.classfile.InnerClass; +import com.sun.org.apache.bcel.internal.classfile.InnerClasses; +import com.sun.org.apache.bcel.internal.classfile.LineNumber; +import com.sun.org.apache.bcel.internal.classfile.LineNumberTable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable; +import com.sun.org.apache.bcel.internal.classfile.SourceFile; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Convert found attributes into HTML file. * - * @author M. Dahm + * @version $Id: AttributeHTML.java 1749603 2016-06-21 20:50:19Z ggregory $ * */ -final class AttributeHTML implements com.sun.org.apache.bcel.internal.Constants { - private String class_name; // name of current class - private PrintWriter file; // file to write to - private int attr_count = 0; - private ConstantHTML constant_html; - private ConstantPool constant_pool; +final class AttributeHTML { - AttributeHTML(String dir, String class_name, ConstantPool constant_pool, - ConstantHTML constant_html) throws IOException - { - this.class_name = class_name; - this.constant_pool = constant_pool; - this.constant_html = constant_html; + private final String class_name; // name of current class + private final PrintWriter file; // file to write to + private int attr_count = 0; + private final ConstantHTML constant_html; + private final ConstantPool constant_pool; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_attributes.html")); - file.println(""); - } - private final String codeLink(int link, int method_number) { - return "" + - link + ""; - } - - final void close() { - file.println("
    "); - file.close(); - } - - final void writeAttribute(Attribute attribute, String anchor) throws IOException { - writeAttribute(attribute, anchor, 0); - } - - final void writeAttribute(Attribute attribute, String anchor, int method_number) throws IOException { - byte tag = attribute.getTag(); - int index; - - if(tag == ATTR_UNKNOWN) // Don't know what to do about this one - return; - - attr_count++; // Increment number of attributes found so far - - if(attr_count % 2 == 0) - file.print("

    "); - else - file.print("
    "); - - file.println("

    " + attr_count + " " + ATTRIBUTE_NAMES[tag] + "

    "); - - /* Handle different attributes - */ - switch(tag) { - case ATTR_CODE: - Code c = (Code)attribute; - - // Some directly printable values - file.print("
    • Maximum stack size = " + c.getMaxStack() + - "
    • \n
    • Number of local variables = " + - c.getMaxLocals() + "
    • \n
    • Byte code
    \n"); - - // Get handled exceptions and list them - CodeException[] ce = c.getExceptionTable(); - int len = ce.length; - - if(len > 0) { - file.print("

    Exceptions handled

      "); - - for(int i=0; i < len; i++) { - int catch_type = ce[i].getCatchType(); // Index in constant pool - - file.print("
    • "); - - if(catch_type != 0) - file.print(constant_html.referenceConstant(catch_type)); // Create Link to _cp.html - else - file.print("Any Exception"); - - file.print("
      (Ranging from lines " + codeLink(ce[i].getStartPC(), method_number) + - " to " + codeLink(ce[i].getEndPC(), method_number) + ", handled at line " + - codeLink(ce[i].getHandlerPC(), method_number) + ")
    • "); - } - file.print("
    "); - } - break; - - case ATTR_CONSTANT_VALUE: - index = ((ConstantValue)attribute).getConstantValueIndex(); - - // Reference _cp.html - file.print("\n"); - break; - - case ATTR_SOURCE_FILE: - index = ((SourceFile)attribute).getSourceFileIndex(); - - // Reference _cp.html - file.print("\n"); - break; - - case ATTR_EXCEPTIONS: - // List thrown exceptions - int[] indices = ((ExceptionTable)attribute).getExceptionIndexTable(); - - file.print("\n"); - break; - - case ATTR_LINE_NUMBER_TABLE: - LineNumber[] line_numbers =((LineNumberTable)attribute).getLineNumberTable(); - - // List line number pairs - file.print("

    "); - - for(int i=0; i < line_numbers.length; i++) { - file.print("(" + line_numbers[i].getStartPC() + ", " + line_numbers[i].getLineNumber() + ")"); - - if(i < line_numbers.length - 1) - file.print(", "); // breakable - } - break; - - case ATTR_LOCAL_VARIABLE_TABLE: - LocalVariable[] vars = ((LocalVariableTable)attribute).getLocalVariableTable(); - - // List name, range and type - file.print("

      "); - - for(int i=0; i < vars.length; i++) { - index = vars[i].getSignatureIndex(); - String signature = ((ConstantUtf8)constant_pool.getConstant(index, CONSTANT_Utf8)).getBytes(); - signature = Utility.signatureToString(signature, false); - int start = vars[i].getStartPC(); - int end = (start + vars[i].getLength()); - - file.println("
    • " + Class2HTML.referenceType(signature) + - " " + vars[i].getName() + " in slot %" + vars[i].getIndex() + - "
      Valid from lines " + - "" + - start + " to " + - "" + - end + "
    • "); - } - file.print("
    \n"); - - break; - - case ATTR_INNER_CLASSES: - InnerClass[] classes = ((InnerClasses)attribute).getInnerClasses(); - - // List inner classes - file.print("
      "); - - for(int i=0; i < classes.length; i++) { - String name, access; - - index = classes[i].getInnerNameIndex(); - if(index > 0) - name =((ConstantUtf8)constant_pool.getConstant(index, CONSTANT_Utf8)).getBytes(); - else - name = "<anonymous>"; - - access = Utility.accessToString(classes[i].getInnerAccessFlags()); - - file.print("
    • " + access + " "+ - constant_html.referenceConstant(classes[i].getInnerClassIndex()) + - " in class " + - constant_html.referenceConstant(classes[i].getOuterClassIndex()) + - " named " + name + "
    • \n"); - } - - file.print("
    \n"); - break; - - default: // Such as Unknown attribute or Deprecated - file.print("

    " + attribute.toString()); + AttributeHTML(final String dir, final String class_name, final ConstantPool constant_pool, + final ConstantHTML constant_html) throws IOException { + this.class_name = class_name; + this.constant_pool = constant_pool; + this.constant_html = constant_html; + file = new PrintWriter(new FileOutputStream(dir + class_name + "_attributes.html")); + file.println(""); } - file.println(""); - file.flush(); - } + + private String codeLink( final int link, final int method_number ) { + return "" + link + ""; + } + + + final void close() { + file.println("
    "); + file.close(); + } + + + final void writeAttribute( final Attribute attribute, final String anchor ) { + writeAttribute(attribute, anchor, 0); + } + + + final void writeAttribute( final Attribute attribute, final String anchor, final int method_number ) { + final byte tag = attribute.getTag(); + int index; + if (tag == Const.ATTR_UNKNOWN) { + return; + } + attr_count++; // Increment number of attributes found so far + if (attr_count % 2 == 0) { + file.print("

    "); + } else { + file.print("
    "); + } + file.println("

    " + attr_count + " " + Const.getAttributeName(tag) + + "

    "); + /* Handle different attributes + */ + switch (tag) { + case Const.ATTR_CODE: + final Code c = (Code) attribute; + // Some directly printable values + file.print("
    • Maximum stack size = " + c.getMaxStack() + + "
    • \n
    • Number of local variables = " + c.getMaxLocals() + + "
    • \n
    • Byte code
    \n"); + // Get handled exceptions and list them + final CodeException[] ce = c.getExceptionTable(); + final int len = ce.length; + if (len > 0) { + file.print("

    Exceptions handled

      "); + for (final CodeException cex : ce) { + final int catch_type = cex.getCatchType(); // Index in constant pool + file.print("
    • "); + if (catch_type != 0) { + file.print(constant_html.referenceConstant(catch_type)); // Create Link to _cp.html + } else { + file.print("Any Exception"); + } + file.print("
      (Ranging from lines " + + codeLink(cex.getStartPC(), method_number) + " to " + + codeLink(cex.getEndPC(), method_number) + ", handled at line " + + codeLink(cex.getHandlerPC(), method_number) + ")
    • "); + } + file.print("
    "); + } + break; + case Const.ATTR_CONSTANT_VALUE: + index = ((ConstantValue) attribute).getConstantValueIndex(); + // Reference _cp.html + file.print("\n"); + break; + case Const.ATTR_SOURCE_FILE: + index = ((SourceFile) attribute).getSourceFileIndex(); + // Reference _cp.html + file.print("\n"); + break; + case Const.ATTR_EXCEPTIONS: + // List thrown exceptions + final int[] indices = ((ExceptionTable) attribute).getExceptionIndexTable(); + file.print("\n"); + break; + case Const.ATTR_LINE_NUMBER_TABLE: + final LineNumber[] line_numbers = ((LineNumberTable) attribute).getLineNumberTable(); + // List line number pairs + file.print("

    "); + for (int i = 0; i < line_numbers.length; i++) { + file.print("(" + line_numbers[i].getStartPC() + ", " + + line_numbers[i].getLineNumber() + ")"); + if (i < line_numbers.length - 1) { + file.print(", "); // breakable + } + } + break; + case Const.ATTR_LOCAL_VARIABLE_TABLE: + final LocalVariable[] vars = ((LocalVariableTable) attribute).getLocalVariableTable(); + // List name, range and type + file.print("

      "); + for (final LocalVariable var : vars) { + index = var.getSignatureIndex(); + String signature = ((ConstantUtf8) constant_pool.getConstant(index, + Const.CONSTANT_Utf8)).getBytes(); + signature = Utility.signatureToString(signature, false); + final int start = var.getStartPC(); + final int end = start + var.getLength(); + file.println("
    • " + Class2HTML.referenceType(signature) + " " + + var.getName() + " in slot %" + var.getIndex() + + "
      Valid from lines " + "" + + start + " to " + "" + end + "
    • "); + } + file.print("
    \n"); + break; + case Const.ATTR_INNER_CLASSES: + final InnerClass[] classes = ((InnerClasses) attribute).getInnerClasses(); + // List inner classes + file.print("
      "); + for (final InnerClass classe : classes) { + String name; + String access; + index = classe.getInnerNameIndex(); + if (index > 0) { + name = ((ConstantUtf8) constant_pool.getConstant(index, Const.CONSTANT_Utf8)) + .getBytes(); + } else { + name = "<anonymous>"; + } + access = Utility.accessToString(classe.getInnerAccessFlags()); + file.print("
    • " + access + " " + + constant_html.referenceConstant(classe.getInnerClassIndex()) + + " in class " + + constant_html.referenceConstant(classe.getOuterClassIndex()) + + " named " + name + "
    • \n"); + } + file.print("
    \n"); + break; + default: // Such as Unknown attribute or Deprecated + file.print("

    " + attribute); + } + file.println("

    "); - - /* Special case: Skip (0-3) padding bytes, i.e., the - * following bytes are 4-byte-aligned + /** + * Disassemble a stream of byte codes and return the + * string representation. + * + * @param stream data input stream + * @return String representation of byte code */ - if((opcode == TABLESWITCH) || (opcode == LOOKUPSWITCH)) { - int remainder = bytes.getIndex() % 4; - no_pad_bytes = (remainder == 0)? 0 : 4 - remainder; - - for(int i=0; i < no_pad_bytes; i++) - bytes.readByte(); - - // Both cases have a field default_offset in common - default_offset = bytes.readInt(); - } - - switch(opcode) { - case TABLESWITCH: - low = bytes.readInt(); - high = bytes.readInt(); - - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - - buf.append(""); - - // Print switch indices in first row (and default) - jump_table = new int[high - low + 1]; - for(int i=0; i < jump_table.length; i++) { - jump_table[i] = offset + bytes.readInt(); - - buf.append(""); - } - buf.append("\n"); - - // Print target and default indices in second row - for(int i=0; i < jump_table.length; i++) - buf.append(""); - buf.append("\n
    " + (low + i) + "default
    " + jump_table[i] + "" + default_offset + "
    \n"); - - break; - - /* Lookup switch has variable length arguments. - */ - case LOOKUPSWITCH: - int npairs = bytes.readInt(); - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - jump_table = new int[npairs]; - default_offset += offset; - - buf.append(""); - - // Print switch indices in first row (and default) - for(int i=0; i < npairs; i++) { - int match = bytes.readInt(); - - jump_table[i] = offset + bytes.readInt(); - buf.append(""); - } - buf.append("\n"); - - // Print target and default indices in second row - for(int i=0; i < npairs; i++) - buf.append(""); - buf.append("\n
    " + match + "default
    " + jump_table[i] + "" + default_offset + "
    \n"); - break; - - /* Two address bytes + offset from start of byte stream form the - * jump target. - */ - case GOTO: case IFEQ: case IFGE: case IFGT: - case IFLE: case IFLT: - case IFNE: case IFNONNULL: case IFNULL: case IF_ACMPEQ: - case IF_ACMPNE: case IF_ICMPEQ: case IF_ICMPGE: case IF_ICMPGT: - case IF_ICMPLE: case IF_ICMPLT: case IF_ICMPNE: case JSR: - - index = (int)(bytes.getIndex() + bytes.readShort() - 1); - - buf.append("" + index + ""); - break; - - /* Same for 32-bit wide jumps - */ - case GOTO_W: case JSR_W: - int windex = bytes.getIndex() + bytes.readInt() - 1; - buf.append("" + - windex + ""); - break; - - /* Index byte references local variable (register) - */ - case ALOAD: case ASTORE: case DLOAD: case DSTORE: case FLOAD: - case FSTORE: case ILOAD: case ISTORE: case LLOAD: case LSTORE: - case RET: - if(wide) { - vindex = bytes.readShort(); - wide=false; // Clear flag - } - else - vindex = bytes.readUnsignedByte(); - - buf.append("%" + vindex); - break; - - /* - * Remember wide byte which is used to form a 16-bit address in the - * following instruction. Relies on that the method is called again with - * the following opcode. - */ - case WIDE: - wide = true; - buf.append("(wide)"); - break; - - /* Array of basic type. - */ - case NEWARRAY: - buf.append("" + TYPE_NAMES[bytes.readByte()] + ""); - break; - - /* Access object/class fields. - */ - case GETFIELD: case GETSTATIC: case PUTFIELD: case PUTSTATIC: - index = bytes.readShort(); - ConstantFieldref c1 = (ConstantFieldref)constant_pool.getConstant(index, CONSTANT_Fieldref); - - class_index = c1.getClassIndex(); - name = constant_pool.getConstantString(class_index, CONSTANT_Class); - name = Utility.compactClassName(name, false); - - index = c1.getNameAndTypeIndex(); - String field_name = constant_pool.constantToString(index, CONSTANT_NameAndType); - - if(name.equals(class_name)) { // Local field - buf.append("" + field_name + "\n"); - } - else - buf.append(constant_html.referenceConstant(class_index) + "." + field_name); - - break; - - /* Operands are references to classes in constant pool - */ - case CHECKCAST: case INSTANCEOF: case NEW: - index = bytes.readShort(); - buf.append(constant_html.referenceConstant(index)); - break; - - /* Operands are references to methods in constant pool - */ - case INVOKESPECIAL: case INVOKESTATIC: case INVOKEVIRTUAL: case INVOKEINTERFACE: - int m_index = bytes.readShort(); - String str; - - if(opcode == INVOKEINTERFACE) { // Special treatment needed - int nargs = bytes.readUnsignedByte(); // Redundant - int reserved = bytes.readUnsignedByte(); // Reserved - - ConstantInterfaceMethodref c=(ConstantInterfaceMethodref)constant_pool.getConstant(m_index, CONSTANT_InterfaceMethodref); - - class_index = c.getClassIndex(); - str = constant_pool.constantToString(c); - index = c.getNameAndTypeIndex(); - } - else { - ConstantMethodref c = (ConstantMethodref)constant_pool.getConstant(m_index, CONSTANT_Methodref); - class_index = c.getClassIndex(); - - str = constant_pool.constantToString(c); - index = c.getNameAndTypeIndex(); - } - - name = Class2HTML.referenceClass(class_index); - str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant(index, CONSTANT_NameAndType))); - - // Get signature, i.e., types - ConstantNameAndType c2 = (ConstantNameAndType)constant_pool. - getConstant(index, CONSTANT_NameAndType); - signature = constant_pool.constantToString(c2.getSignatureIndex(), - CONSTANT_Utf8); - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - String type = Utility.methodSignatureReturnType(signature, false); - - buf.append(name + "." + str + "" + "("); - - // List arguments - for(int i=0; i < args.length; i++) { - buf.append(Class2HTML.referenceType(args[i])); - - if(i < args.length - 1) - buf.append(", "); - } - // Attach return type - buf.append("):" + Class2HTML.referenceType(type)); - - break; - - /* Operands are references to items in constant pool - */ - case LDC_W: case LDC2_W: - index = bytes.readShort(); - - buf.append("" + - Class2HTML.toHTML(constant_pool.constantToString(index, - constant_pool. - getConstant(index).getTag()))+ - ""); - break; - - case LDC: - index = bytes.readUnsignedByte(); - buf.append("" + - Class2HTML.toHTML(constant_pool.constantToString(index, - constant_pool. - getConstant(index).getTag()))+ - ""); - break; - - /* Array of references. - */ - case ANEWARRAY: - index = bytes.readShort(); - - buf.append(constant_html.referenceConstant(index)); - break; - - /* Multidimensional array of references. - */ - case MULTIANEWARRAY: - index = bytes.readShort(); - int dimensions = bytes.readByte(); - buf.append(constant_html.referenceConstant(index) + ":" + dimensions + "-dimensional"); - break; - - /* Increment local variable. - */ - case IINC: - if(wide) { - vindex = bytes.readShort(); - constant = bytes.readShort(); - wide = false; - } - else { - vindex = bytes.readUnsignedByte(); - constant = bytes.readByte(); - } - buf.append("%" + vindex + " " + constant); - break; - - default: - if(NO_OF_OPERANDS[opcode] > 0) { - for(int i=0; i < TYPE_OF_OPERANDS[opcode].length; i++) { - switch(TYPE_OF_OPERANDS[opcode][i]) { - case T_BYTE: - buf.append(bytes.readUnsignedByte()); - break; - - case T_SHORT: // Either branch or index - buf.append(bytes.readShort()); - break; - - case T_INT: - buf.append(bytes.readInt()); - break; - - default: // Never reached - System.err.println("Unreachable default case reached!"); - System.exit(-1); - } - buf.append(" "); - } - } - } - - buf.append("
    " + - ""); - - for(int i=0; stream.available() > 0; i++) { - int offset = stream.getIndex(); - String str = codeToHTML(stream, method_number); - String anchor = ""; - - /* Set an anchor mark if this line is targetted by a goto, jsr, etc. - * Defining an anchor for every line is very inefficient! + private String codeToHTML( final ByteSequence bytes, final int method_number ) throws IOException { + final short opcode = (short) bytes.readUnsignedByte(); + String name; + String signature; + int default_offset = 0; + int low; + int high; + int index; + int class_index; + int vindex; + int constant; + int[] jump_table; + int no_pad_bytes = 0; + int offset; + final StringBuilder buf = new StringBuilder(256); // CHECKSTYLE IGNORE MagicNumber + buf.append("").append(Const.getOpcodeName(opcode)).append(""); - } - - // Mark last line, may be targetted from Attributes window - file.println(""); - file.println("
    Byte
    offset
    InstructionArgument"); + /* Special case: Skip (0-3) padding bytes, i.e., the + * following bytes are 4-byte-aligned */ - if(goto_set.get(offset)) - anchor = ""; - - String anchor2; - if(stream.getIndex() == code.length) // last loop - anchor2 = "" + offset + ""; - else - anchor2 = "" + offset; - - file.println("
    " + anchor2 + "" + anchor + str + "
    "); + if ((opcode == Const.TABLESWITCH) || (opcode == Const.LOOKUPSWITCH)) { + final int remainder = bytes.getIndex() % 4; + no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; + for (int i = 0; i < no_pad_bytes; i++) { + bytes.readByte(); + } + // Both cases have a field default_offset in common + default_offset = bytes.readInt(); + } + switch (opcode) { + case Const.TABLESWITCH: + low = bytes.readInt(); + high = bytes.readInt(); + offset = bytes.getIndex() - 12 - no_pad_bytes - 1; + default_offset += offset; + buf.append(""); + // Print switch indices in first row (and default) + jump_table = new int[high - low + 1]; + for (int i = 0; i < jump_table.length; i++) { + jump_table[i] = offset + bytes.readInt(); + buf.append(""); + } + buf.append("\n"); + // Print target and default indices in second row + for (final int element : jump_table) { + buf.append(""); + } + buf.append("\n
    ").append(low + i).append("default
    ").append(element).append("").append(default_offset).append( + "
    \n"); + break; + /* Lookup switch has variable length arguments. + */ + case Const.LOOKUPSWITCH: + final int npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - no_pad_bytes - 1; + jump_table = new int[npairs]; + default_offset += offset; + buf.append(""); + // Print switch indices in first row (and default) + for (int i = 0; i < npairs; i++) { + final int match = bytes.readInt(); + jump_table[i] = offset + bytes.readInt(); + buf.append(""); + } + buf.append("\n"); + // Print target and default indices in second row + for (int i = 0; i < npairs; i++) { + buf.append(""); + } + buf.append("\n
    ").append(match).append("default
    ").append(jump_table[i]).append("").append(default_offset).append( + "
    \n"); + break; + /* Two address bytes + offset from start of byte stream form the + * jump target. + */ + case Const.GOTO: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + case Const.JSR: + index = bytes.getIndex() + bytes.readShort() - 1; + buf.append("").append(index).append(""); + break; + /* Same for 32-bit wide jumps + */ + case Const.GOTO_W: + case Const.JSR_W: + final int windex = bytes.getIndex() + bytes.readInt() - 1; + buf.append("").append(windex).append(""); + break; + /* Index byte references local variable (register) + */ + case Const.ALOAD: + case Const.ASTORE: + case Const.DLOAD: + case Const.DSTORE: + case Const.FLOAD: + case Const.FSTORE: + case Const.ILOAD: + case Const.ISTORE: + case Const.LLOAD: + case Const.LSTORE: + case Const.RET: + if (wide) { + vindex = bytes.readShort(); + wide = false; // Clear flag + } else { + vindex = bytes.readUnsignedByte(); + } + buf.append("%").append(vindex); + break; + /* + * Remember wide byte which is used to form a 16-bit address in the + * following instruction. Relies on that the method is called again with + * the following opcode. + */ + case Const.WIDE: + wide = true; + buf.append("(wide)"); + break; + /* Array of basic type. + */ + case Const.NEWARRAY: + buf.append("").append(Const.getTypeName(bytes.readByte())).append( + ""); + break; + /* Access object/class fields. + */ + case Const.GETFIELD: + case Const.GETSTATIC: + case Const.PUTFIELD: + case Const.PUTSTATIC: + index = bytes.readShort(); + final ConstantFieldref c1 = (ConstantFieldref) constant_pool.getConstant(index, + Const.CONSTANT_Fieldref); + class_index = c1.getClassIndex(); + name = constant_pool.getConstantString(class_index, Const.CONSTANT_Class); + name = Utility.compactClassName(name, false); + index = c1.getNameAndTypeIndex(); + final String field_name = constant_pool.constantToString(index, Const.CONSTANT_NameAndType); + if (name.equals(class_name)) { // Local field + buf.append("").append(field_name) + .append("\n"); + } else { + buf.append(constant_html.referenceConstant(class_index)).append(".").append( + field_name); + } + break; + /* Operands are references to classes in constant pool + */ + case Const.CHECKCAST: + case Const.INSTANCEOF: + case Const.NEW: + index = bytes.readShort(); + buf.append(constant_html.referenceConstant(index)); + break; + /* Operands are references to methods in constant pool + */ + case Const.INVOKESPECIAL: + case Const.INVOKESTATIC: + case Const.INVOKEVIRTUAL: + case Const.INVOKEINTERFACE: + case Const.INVOKEDYNAMIC: + final int m_index = bytes.readShort(); + String str; + if (opcode == Const.INVOKEINTERFACE) { // Special treatment needed + bytes.readUnsignedByte(); // Redundant + bytes.readUnsignedByte(); // Reserved +// int nargs = bytes.readUnsignedByte(); // Redundant +// int reserved = bytes.readUnsignedByte(); // Reserved + final ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constant_pool + .getConstant(m_index, Const.CONSTANT_InterfaceMethodref); + class_index = c.getClassIndex(); + index = c.getNameAndTypeIndex(); + name = Class2HTML.referenceClass(class_index); + } else if (opcode == Const.INVOKEDYNAMIC) { // Special treatment needed + bytes.readUnsignedByte(); // Reserved + bytes.readUnsignedByte(); // Reserved + final ConstantInvokeDynamic c = (ConstantInvokeDynamic) constant_pool + .getConstant(m_index, Const.CONSTANT_InvokeDynamic); + index = c.getNameAndTypeIndex(); + name = "#" + c.getBootstrapMethodAttrIndex(); + } else { + // UNDONE: Java8 now allows INVOKESPECIAL and INVOKESTATIC to + // reference EITHER a Methodref OR an InterfaceMethodref. + // Not sure if that affects this code or not. (markro) + final ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(m_index, + Const.CONSTANT_Methodref); + class_index = c.getClassIndex(); + index = c.getNameAndTypeIndex(); + name = Class2HTML.referenceClass(class_index); + } + str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant( + index, Const.CONSTANT_NameAndType))); + // Get signature, i.e., types + final ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant(index, + Const.CONSTANT_NameAndType); + signature = constant_pool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8); + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + final String type = Utility.methodSignatureReturnType(signature, false); + buf.append(name).append(".").append(str).append( + "").append("("); + // List arguments + for (int i = 0; i < args.length; i++) { + buf.append(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + buf.append(", "); + } + } + // Attach return type + buf.append("):").append(Class2HTML.referenceType(type)); + break; + /* Operands are references to items in constant pool + */ + case Const.LDC_W: + case Const.LDC2_W: + index = bytes.readShort(); + buf.append("").append( + Class2HTML.toHTML(constant_pool.constantToString(index, + constant_pool.getConstant(index).getTag()))).append(""); + break; + case Const.LDC: + index = bytes.readUnsignedByte(); + buf.append("").append( + Class2HTML.toHTML(constant_pool.constantToString(index, + constant_pool.getConstant(index).getTag()))).append(""); + break; + /* Array of references. + */ + case Const.ANEWARRAY: + index = bytes.readShort(); + buf.append(constant_html.referenceConstant(index)); + break; + /* Multidimensional array of references. + */ + case Const.MULTIANEWARRAY: + index = bytes.readShort(); + final int dimensions = bytes.readByte(); + buf.append(constant_html.referenceConstant(index)).append(":").append(dimensions) + .append("-dimensional"); + break; + /* Increment local variable. + */ + case Const.IINC: + if (wide) { + vindex = bytes.readShort(); + constant = bytes.readShort(); + wide = false; + } else { + vindex = bytes.readUnsignedByte(); + constant = bytes.readByte(); + } + buf.append("%").append(vindex).append(" ").append(constant); + break; + default: + if (Const.getNoOfOperands(opcode) > 0) { + for (int i = 0; i < Const.getOperandTypeCount(opcode); i++) { + switch (Const.getOperandType(opcode, i)) { + case Const.T_BYTE: + buf.append(bytes.readUnsignedByte()); + break; + case Const.T_SHORT: // Either branch or index + buf.append(bytes.readShort()); + break; + case Const.T_INT: + buf.append(bytes.readInt()); + break; + default: // Never reached + throw new IllegalStateException( + "Unreachable default case reached! " + + Const.getOperandType(opcode, i)); + } + buf.append(" "); + } + } + } + buf.append(""); + return buf.toString(); } - } + + /** + * Find all target addresses in code, so that they can be marked + * with <A NAME = ...>. Target addresses are kept in an BitSet object. + */ + private void findGotos( final ByteSequence bytes, final Code code ) throws IOException { + int index; + goto_set = new BitSet(bytes.available()); + int opcode; + /* First get Code attribute from method and the exceptions handled + * (try .. catch) in this method. We only need the line number here. + */ + if (code != null) { + final CodeException[] ce = code.getExceptionTable(); + for (final CodeException cex : ce) { + goto_set.set(cex.getStartPC()); + goto_set.set(cex.getEndPC()); + goto_set.set(cex.getHandlerPC()); + } + // Look for local variables and their range + final Attribute[] attributes = code.getAttributes(); + for (final Attribute attribute : attributes) { + if (attribute.getTag() == Const.ATTR_LOCAL_VARIABLE_TABLE) { + final LocalVariable[] vars = ((LocalVariableTable) attribute) + .getLocalVariableTable(); + for (final LocalVariable var : vars) { + final int start = var.getStartPC(); + final int end = start + var.getLength(); + goto_set.set(start); + goto_set.set(end); + } + break; + } + } + } + // Get target addresses from GOTO, JSR, TABLESWITCH, etc. + for (; bytes.available() > 0;) { + opcode = bytes.readUnsignedByte(); + //System.out.println(getOpcodeName(opcode)); + switch (opcode) { + case Const.TABLESWITCH: + case Const.LOOKUPSWITCH: + //bytes.readByte(); // Skip already read byte + final int remainder = bytes.getIndex() % 4; + final int no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; + int default_offset; + int offset; + for (int j = 0; j < no_pad_bytes; j++) { + bytes.readByte(); + } + // Both cases have a field default_offset in common + default_offset = bytes.readInt(); + if (opcode == Const.TABLESWITCH) { + final int low = bytes.readInt(); + final int high = bytes.readInt(); + offset = bytes.getIndex() - 12 - no_pad_bytes - 1; + default_offset += offset; + goto_set.set(default_offset); + for (int j = 0; j < (high - low + 1); j++) { + index = offset + bytes.readInt(); + goto_set.set(index); + } + } else { // LOOKUPSWITCH + final int npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - no_pad_bytes - 1; + default_offset += offset; + goto_set.set(default_offset); + for (int j = 0; j < npairs; j++) { +// int match = bytes.readInt(); + bytes.readInt(); + index = offset + bytes.readInt(); + goto_set.set(index); + } + } + break; + case Const.GOTO: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + case Const.JSR: + //bytes.readByte(); // Skip already read byte + index = bytes.getIndex() + bytes.readShort() - 1; + goto_set.set(index); + break; + case Const.GOTO_W: + case Const.JSR_W: + //bytes.readByte(); // Skip already read byte + index = bytes.getIndex() + bytes.readInt() - 1; + goto_set.set(index); + break; + default: + bytes.unreadByte(); + codeToHTML(bytes, 0); // Ignore output + } + } + } + + + /** + * Write a single method with the byte code associated with it. + */ + private void writeMethod( final Method method, final int method_number ) throws IOException { + // Get raw signature + final String signature = method.getSignature(); + // Get array of strings containing the argument types + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + // Get return type string + final String type = Utility.methodSignatureReturnType(signature, false); + // Get method name + final String name = method.getName(); + final String html_name = Class2HTML.toHTML(name); + // Get method's access flags + String access = Utility.accessToString(method.getAccessFlags()); + access = Utility.replace(access, " ", " "); + // Get the method's attributes, the Code Attribute in particular + final Attribute[] attributes = method.getAttributes(); + file.print("

    " + access + " " + "" + Class2HTML.referenceType(type) + " " + + html_name + "("); + for (int i = 0; i < args.length; i++) { + file.print(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + file.print(", "); + } + } + file.println(")

    "); + Code c = null; + byte[] code = null; + if (attributes.length > 0) { + file.print("

    Attributes

      \n"); + for (int i = 0; i < attributes.length; i++) { + byte tag = attributes[i].getTag(); + if (tag != Const.ATTR_UNKNOWN) { + file.print("
    • " + + Const.getAttributeName(tag) + "
    • \n"); + } else { + file.print("
    • " + attributes[i] + "
    • "); + } + if (tag == Const.ATTR_CODE) { + c = (Code) attributes[i]; + final Attribute[] attributes2 = c.getAttributes(); + code = c.getCode(); + file.print(""); + } + } + file.println("
    "); + } + if (code != null) { // No code, an abstract method, e.g. + //System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1)); + // Print the byte code + try (ByteSequence stream = new ByteSequence(code)) { + stream.mark(stream.available()); + findGotos(stream, c); + stream.reset(); + file.println("" + + ""); + for (; stream.available() > 0;) { + final int offset = stream.getIndex(); + final String str = codeToHTML(stream, method_number); + String anchor = ""; + /* + * Set an anchor mark if this line is targetted by a goto, jsr, etc. Defining an anchor for every + * line is very inefficient! + */ + if (goto_set.get(offset)) { + anchor = ""; + } + String anchor2; + if (stream.getIndex() == code.length) { + anchor2 = "" + offset + ""; + } else { + anchor2 = "" + offset; + } + file.println(""); + } + } + // Mark last line, may be targetted from Attributes window + file.println(""); + file.println("
    Byte
    offset
    InstructionArgument
    " + anchor2 + "" + anchor + str + "
    "); + } + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java index ac1d8501783..1f0208437bc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java @@ -21,208 +21,217 @@ package com.sun.org.apache.bcel.internal.util; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantClass; +import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref; +import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantString; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Convert constant pool into HTML file. * - * @author M. Dahm + * @version $Id: ConstantHTML.java 1749603 2016-06-21 20:50:19Z ggregory $ * */ -final class ConstantHTML implements com.sun.org.apache.bcel.internal.Constants { - private String class_name; // name of current class - private String class_package; // name of package - private ConstantPool constant_pool; // reference to constant pool - private PrintWriter file; // file to write to - private String[] constant_ref; // String to return for cp[i] - private Constant[] constants; // The constants in the cp - private Method[] methods; +final class ConstantHTML { - ConstantHTML(String dir, String class_name, String class_package, Method[] methods, - ConstantPool constant_pool) throws IOException - { - this.class_name = class_name; - this.class_package = class_package; - this.constant_pool = constant_pool; - this.methods = methods; - constants = constant_pool.getConstantPool(); - file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html")); - constant_ref = new String[constants.length]; - constant_ref[0] = "<unknown>"; + private final String class_name; // name of current class + private final String class_package; // name of package + private final ConstantPool constant_pool; // reference to constant pool + private final PrintWriter file; // file to write to + private final String[] constant_ref; // String to return for cp[i] + private final Constant[] constants; // The constants in the cp + private final Method[] methods; - file.println(""); - // Loop through constants, constants[0] is reserved - for(int i=1; i < constants.length; i++) { - if(i % 2 == 0) - file.print("\n"); + ConstantHTML(final String dir, final String class_name, final String class_package, + final Method[] methods, final ConstantPool constant_pool) throws IOException { + this.class_name = class_name; + this.class_package = class_package; + this.constant_pool = constant_pool; + this.methods = methods; + constants = constant_pool.getConstantPool(); + file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html")); + constant_ref = new String[constants.length]; + constant_ref[0] = "<unknown>"; + file.println("
    "); - else - file.print("
    "); - - if(constants[i] != null) - writeConstant(i); - - file.print("
    "); + // Loop through constants, constants[0] is reserved + for (int i = 1; i < constants.length; i++) { + if (i % 2 == 0) { + file.print("\n"); + } + file.println("
    "); + } else { + file.print("
    "); + } + if (constants[i] != null) { + writeConstant(i); + } + file.print("
    "); + file.close(); } - file.println(""); - file.close(); - } - String referenceConstant(int index) { - return constant_ref[index]; - } - - private void writeConstant(int index) { - byte tag = constants[index].getTag(); - int class_index, name_index; - String ref; - - // The header is always the same - file.println("

    " + index + " " + CONSTANT_NAMES[tag] + "

    "); - - /* For every constant type get the needed parameters and print them appropiately - */ - switch(tag) { - case CONSTANT_InterfaceMethodref: - case CONSTANT_Methodref: - // Get class_index and name_and_type_index, depending on type - if(tag == CONSTANT_Methodref) { - ConstantMethodref c = (ConstantMethodref)constant_pool.getConstant(index, CONSTANT_Methodref); - class_index = c.getClassIndex(); - name_index = c.getNameAndTypeIndex(); - } - else { - ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref)constant_pool.getConstant(index, CONSTANT_InterfaceMethodref); - class_index = c1.getClassIndex(); - name_index = c1.getNameAndTypeIndex(); - } - - // Get method name and its class - String method_name = constant_pool.constantToString(name_index, CONSTANT_NameAndType); - String html_method_name = Class2HTML.toHTML(method_name); - - // Partially compacted class name, i.e., / -> . - String method_class = constant_pool.constantToString(class_index, CONSTANT_Class); - String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. - short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. - short_method_class = Utility.compactClassName(short_method_class, class_package + ".", true); // Remove class package prefix - - // Get method signature - ConstantNameAndType c2 = (ConstantNameAndType)constant_pool.getConstant(name_index, CONSTANT_NameAndType); - String signature = constant_pool.constantToString(c2.getSignatureIndex(), CONSTANT_Utf8); - // Get array of strings containing the argument types - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - - // Get return type string - String type = Utility.methodSignatureReturnType(signature, false); - String ret_type = Class2HTML.referenceType(type); - - StringBuffer buf = new StringBuffer("("); - for(int i=0; i < args.length; i++) { - buf.append(Class2HTML.referenceType(args[i])); - if(i < args.length - 1) - buf.append(", "); - } - buf.append(")"); - - String arg_types = buf.toString(); - - if(method_class.equals(class_name)) // Method is local to class - ref = "" + html_method_name + ""; - else - ref = "" + short_method_class + - "." + html_method_name; - - constant_ref[index] = ret_type + " " + - short_method_class + "." + html_method_name + " " + arg_types; - - file.println("

    " + ret_type + " " + ref + arg_types + " \n

    "); - break; - - case CONSTANT_Fieldref: - // Get class_index and name_and_type_index - ConstantFieldref c3 = (ConstantFieldref)constant_pool.getConstant(index, CONSTANT_Fieldref); - class_index = c3.getClassIndex(); - name_index = c3.getNameAndTypeIndex(); - - // Get method name and its class (compacted) - String field_class = constant_pool.constantToString(class_index, CONSTANT_Class); - String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang. - short_field_class = Utility.compactClassName(short_field_class, class_package + ".", true); // Remove class package prefix - - String field_name = constant_pool.constantToString(name_index, CONSTANT_NameAndType); - - if(field_class.equals(class_name)) // Field is local to class - ref = "" + field_name + ""; - else - ref = "" + - short_field_class + "." + field_name + "\n"; - - constant_ref[index] = "" + - short_field_class + "." + field_name + ""; - - file.println("

    " + ref + "
    \n" + "

    "); - break; - - case CONSTANT_Class: - ConstantClass c4 = (ConstantClass)constant_pool.getConstant(index, CONSTANT_Class); - name_index = c4.getNameIndex(); - String class_name2 = constant_pool.constantToString(index, tag); // / -> . - String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang. - short_class_name = Utility.compactClassName(short_class_name, class_package + ".", true); // Remove class package prefix - - ref = "" + short_class_name + ""; - constant_ref[index] = "" + short_class_name + ""; - - file.println("

    " + ref + "

    \n"); - break; - - case CONSTANT_String: - ConstantString c5 = (ConstantString)constant_pool.getConstant(index, CONSTANT_String); - name_index = c5.getStringIndex(); - - String str = Class2HTML.toHTML(constant_pool.constantToString(index, tag)); - - file.println("

    " + str + "

    \n"); - break; - - case CONSTANT_NameAndType: - ConstantNameAndType c6 = (ConstantNameAndType)constant_pool.getConstant(index, CONSTANT_NameAndType); - name_index = c6.getNameIndex(); - int signature_index = c6.getSignatureIndex(); - - file.println("

    " + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + "

    \n"); - break; - - default: - file.println("

    " + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + "\n"); - } // switch - } - - private final int getMethodNumber(String str) { - for(int i=0; i < methods.length; i++) { - String cmp = methods[i].getName() + methods[i].getSignature(); - if(cmp.equals(str)) - return i; + String referenceConstant( final int index ) { + return constant_ref[index]; + } + + + private void writeConstant( final int index ) { + final byte tag = constants[index].getTag(); + int class_index; + int name_index; + String ref; + // The header is always the same + file.println("

    " + index + " " + Const.getConstantName(tag) + + "

    "); + /* For every constant type get the needed parameters and print them appropiately + */ + switch (tag) { + case Const.CONSTANT_InterfaceMethodref: + case Const.CONSTANT_Methodref: + // Get class_index and name_and_type_index, depending on type + if (tag == Const.CONSTANT_Methodref) { + final ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(index, + Const.CONSTANT_Methodref); + class_index = c.getClassIndex(); + name_index = c.getNameAndTypeIndex(); + } else { + final ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref) constant_pool + .getConstant(index, Const.CONSTANT_InterfaceMethodref); + class_index = c1.getClassIndex(); + name_index = c1.getNameAndTypeIndex(); + } + // Get method name and its class + final String method_name = constant_pool.constantToString(name_index, + Const.CONSTANT_NameAndType); + final String html_method_name = Class2HTML.toHTML(method_name); + // Partially compacted class name, i.e., / -> . + final String method_class = constant_pool.constantToString(class_index, Const.CONSTANT_Class); + String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. + short_method_class = Utility.compactClassName(short_method_class, class_package + + ".", true); // Remove class package prefix + // Get method signature + final ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant( + name_index, Const.CONSTANT_NameAndType); + final String signature = constant_pool.constantToString(c2.getSignatureIndex(), + Const.CONSTANT_Utf8); + // Get array of strings containing the argument types + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + // Get return type string + final String type = Utility.methodSignatureReturnType(signature, false); + final String ret_type = Class2HTML.referenceType(type); + final StringBuilder buf = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + buf.append(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + buf.append(", "); + } + } + buf.append(")"); + final String arg_types = buf.toString(); + if (method_class.equals(class_name)) { + ref = "" + + html_method_name + ""; + } else { + ref = "" + + short_method_class + "." + html_method_name; + } + constant_ref[index] = ret_type + " " + short_method_class + + "." + html_method_name + " " + arg_types; + file.println("

    " + ret_type + " " + ref + arg_types + + " \n

    "); + break; + case Const.CONSTANT_Fieldref: + // Get class_index and name_and_type_index + final ConstantFieldref c3 = (ConstantFieldref) constant_pool.getConstant(index, + Const.CONSTANT_Fieldref); + class_index = c3.getClassIndex(); + name_index = c3.getNameAndTypeIndex(); + // Get method name and its class (compacted) + final String field_class = constant_pool.constantToString(class_index, Const.CONSTANT_Class); + String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang. + short_field_class = Utility.compactClassName(short_field_class, + class_package + ".", true); // Remove class package prefix + final String field_name = constant_pool + .constantToString(name_index, Const.CONSTANT_NameAndType); + if (field_class.equals(class_name)) { + ref = "" + field_name + ""; + } else { + ref = "" + short_field_class + + "." + field_name + "\n"; + } + constant_ref[index] = "" + short_field_class + "." + + field_name + ""; + file.println("

    " + ref + "
    \n" + "

    "); + break; + case Const.CONSTANT_Class: + final ConstantClass c4 = (ConstantClass) constant_pool.getConstant(index, Const.CONSTANT_Class); + name_index = c4.getNameIndex(); + final String class_name2 = constant_pool.constantToString(index, tag); // / -> . + String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang. + short_class_name = Utility.compactClassName(short_class_name, class_package + ".", + true); // Remove class package prefix + ref = "" + short_class_name + + ""; + constant_ref[index] = "" + short_class_name + ""; + file.println("

    " + ref + "

    \n"); + break; + case Const.CONSTANT_String: + final ConstantString c5 = (ConstantString) constant_pool.getConstant(index, + Const.CONSTANT_String); + name_index = c5.getStringIndex(); + final String str = Class2HTML.toHTML(constant_pool.constantToString(index, tag)); + file.println("

    " + str + "

    \n"); + break; + case Const.CONSTANT_NameAndType: + final ConstantNameAndType c6 = (ConstantNameAndType) constant_pool.getConstant(index, + Const.CONSTANT_NameAndType); + name_index = c6.getNameIndex(); + final int signature_index = c6.getSignatureIndex(); + file.println("

    " + + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + + "

    \n"); + break; + default: + file.println("

    " + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + "\n"); + } // switch + } + + + private int getMethodNumber( final String str ) { + for (int i = 0; i < methods.length; i++) { + final String cmp = methods[i].getName() + methods[i].getSignature(); + if (cmp.equals(str)) { + return i; + } + } + return -1; } - return -1; - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java index f755549b902..d9b54fed974 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java @@ -4,399 +4,407 @@ */ package com.sun.org.apache.bcel.internal.util; -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.generic.*; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.generic.ClassGenException; +import com.sun.org.apache.bcel.internal.generic.InstructionHandle; +import com.sun.org.apache.bcel.internal.generic.InstructionList; + /** - * InstructionFinder is a tool to search for given instructions patterns, - * i.e., match sequences of instructions in an instruction list via - * regular expressions. This can be used, e.g., in order to implement - * a peep hole optimizer that looks for code patterns and replaces - * them with faster equivalents. + * InstructionFinder is a tool to search for given instructions patterns, i.e., + * match sequences of instructions in an instruction list via regular + * expressions. This can be used, e.g., in order to implement a peep hole + * optimizer that looks for code patterns and replaces them with faster + * equivalents. * - *

    This class internally uses the - * Regexp package to search for regular expressions. + *

    + * This class internally uses the java.util.regex + * package to search for regular expressions. * * A typical application would look like this: -

    -    InstructionFinder f   = new InstructionFinder(il);
    -    String            pat = "IfInstruction ICONST_0 GOTO ICONST_1 NOP (IFEQ|IFNE)";
    -
    -    for(Iterator i = f.search(pat, constraint); i.hasNext(); ) {
    -      InstructionHandle[] match = (InstructionHandle[])i.next();
    -      ...
    -      il.delete(match[1], match[5]);
    -      ...
    -    }
    -
    - * @author M. Dahm - * @see Instruction + * + *
    + *
    + *
    + *   InstructionFinder f   = new InstructionFinder(il);
    + *   String            pat = "IfInstruction ICONST_0 GOTO ICONST_1 NOP (IFEQ|IFNE)";
    + *
    + *   for (Iterator i = f.search(pat, constraint); i.hasNext(); ) {
    + *   InstructionHandle[] match = (InstructionHandle[])i.next();
    + *   ...
    + *   il.delete(match[1], match[5]);
    + *   ...
    + *   }
    + *
    + *
    + * 
    + * + * @version $Id: InstructionFinder.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see com.sun.org.apache.bcel.internal.generic.Instruction * @see InstructionList */ public class InstructionFinder { - private static final int OFFSET = 32767; // char + OFFSET is outside of LATIN-1 - private static final int NO_OPCODES = 256; // Potential number, some are not used - private static final HashMap map = new HashMap(); // Map + private static final int OFFSET = 32767; // char + OFFSET is outside of LATIN-1 + private static final int NO_OPCODES = 256; // Potential number, some are not used + private static final Map map = new HashMap<>(); + private final InstructionList il; + private String il_string; // instruction list as string + private InstructionHandle[] handles; // map instruction - private InstructionList il; - private String il_string; // instruction list as string - private InstructionHandle[] handles; // map instruction list to array - /** - * @param il instruction list to search for given patterns - */ - public InstructionFinder(InstructionList il) { - this.il = il; - reread(); - } - - /** - * Reread the instruction list, e.g., after you've altered the list upon a match. - */ - public final void reread() { - int size = il.getLength(); - char[] buf = new char[size]; // Create a string with length equal to il length - handles = il.getInstructionHandles(); - - // Map opcodes to characters - for(int i=0; i < size; i++) - buf[i] = makeChar(handles[i].getInstruction().getOpcode()); - - il_string = new String(buf); - } - - /** - * Map symbolic instruction names like "getfield" to a single character. - * - * @param pattern instruction pattern in lower case - * @return encoded string for a pattern such as "BranchInstruction". - */ - private static final String mapName(String pattern) { - String result = (String)map.get(pattern); - - if(result != null) - return result; - - for(short i=0; i < NO_OPCODES; i++) - if(pattern.equals(Constants.OPCODE_NAMES[i])) - return "" + makeChar(i); - - throw new RuntimeException("Instruction unknown: " + pattern); - } - - /** - * Replace symbolic names of instructions with the appropiate character and remove - * all white space from string. Meta characters such as +, * are ignored. - * - * @param pattern The pattern to compile - * @return translated regular expression string - */ - private static final String compilePattern(String pattern) { - String lower = pattern.toLowerCase(); - StringBuffer buf = new StringBuffer(); - int size = pattern.length(); - - for(int i=0; i < size; i++) { - char ch = lower.charAt(i); - - if(Character.isLetterOrDigit(ch)) { - StringBuffer name = new StringBuffer(); - - while((Character.isLetterOrDigit(ch) || ch == '_') && i < size) { - name.append(ch); - - if(++i < size) - ch = lower.charAt(i); - else - break; - } - - i--; - - buf.append(mapName(name.toString())); - } else if(!Character.isWhitespace(ch)) - buf.append(ch); - } - - return buf.toString(); - } - - /** - * @return the matched piece of code as an array of instruction (handles) - */ - private InstructionHandle[] getMatch(int matched_from, int match_length) { - InstructionHandle[] match = new InstructionHandle[match_length]; - System.arraycopy(handles, matched_from, match, 0, match_length); - - return match; - } - - /** - * Search for the given pattern in the instruction list. You can search for any valid - * opcode via its symbolic name, e.g. "istore". You can also use a super class or - * an interface name to match a whole set of instructions, e.g. "BranchInstruction" or - * "LoadInstruction". "istore" is also an alias for all "istore_x" instructions. Additional - * aliases are "if" for "ifxx", "if_icmp" for "if_icmpxx", "if_acmp" for "if_acmpxx". - * - * Consecutive instruction names must be separated by white space which will be removed - * during the compilation of the pattern. - * - * For the rest the usual pattern matching rules for regular expressions apply.

    - * Example pattern: - *

    -     search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
    -   * 
    - * - *

    If you alter the instruction list upon a match such that other - * matching areas are affected, you should call reread() to update - * the finder and call search() again, because the matches are cached. - * - * @param pattern the instruction pattern to search for, where case is ignored - * @param from where to start the search in the instruction list - * @param constraint optional CodeConstraint to check the found code pattern for - * user-defined constraints - * @return iterator of matches where e.nextElement() returns an array of instruction handles - * describing the matched area - */ - public final Iterator search(String pattern, InstructionHandle from, - CodeConstraint constraint) - { - String search = compilePattern(pattern); - int start = -1; - - for(int i=0; i < handles.length; i++) { - if(handles[i] == from) { - start = i; // Where to start search from (index) - break; - } - } - - if(start == -1) - throw new ClassGenException("Instruction handle " + from + - " not found in instruction list."); - - Pattern regex = Pattern.compile(search); - List matches = new ArrayList<>(); - Matcher matcher = regex.matcher(il_string); - while(start < il_string.length() && matcher.find(start)) { - int startExpr = matcher.start(); - int endExpr = matcher.end(); - int lenExpr = endExpr - startExpr; - InstructionHandle[] match = getMatch(startExpr, lenExpr); - - if((constraint == null) || constraint.checkCode(match)) - matches.add(match); - start = endExpr; - } - - return matches.iterator(); - } - - /** - * Start search beginning from the start of the given instruction list. - * - * @param pattern the instruction pattern to search for, where case is ignored - * @return iterator of matches where e.nextElement() - * returns an array of instruction handles describing the matched - * area - */ - public final Iterator search(String pattern) { - return search(pattern, il.getStart(), null); - } - - /** - * Start search beginning from `from'. - * - * @param pattern the instruction pattern to search for, where case is ignored - * @param from where to start the search in the instruction list - * @return iterator of matches where e.nextElement() returns an array of instruction handles - * describing the matched area - */ - public final Iterator search(String pattern, InstructionHandle from) { - return search(pattern, from, null); - } - - /** - * Start search beginning from the start of the given instruction list. - * Check found matches with the constraint object. - * - * @param pattern the instruction pattern to search for, case is ignored - * @param constraint constraints to be checked on matching code - * @return instruction handle or `null' if the match failed - */ - public final Iterator search(String pattern, CodeConstraint constraint) { - return search(pattern, il.getStart(), constraint); - } - - /** - * Convert opcode number to char. - */ - private static final char makeChar(short opcode) { - return (char)(opcode + OFFSET); - } - - /** - * @return the inquired instruction list - */ - public final InstructionList getInstructionList() { return il; } - - /** - * Code patterns found may be checked using an additional - * user-defined constraint object whether they really match the needed criterion. - * I.e., check constraints that can not expressed with regular expressions. - * - */ - public interface CodeConstraint { + // list to array /** - * @param match array of instructions matching the requested pattern - * @return true if the matched area is really useful + * @param il + * instruction list to search for given patterns */ - public boolean checkCode(InstructionHandle[] match); - } - - // Initialize pattern map - - static { - map.put("arithmeticinstruction", "(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)"); - map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial)"); - map.put("arrayinstruction", "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)"); - map.put("gotoinstruction", "(goto|goto_w)"); - map.put("conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)"); - map.put("localvariableinstruction", "(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)"); - map.put("loadinstruction", "(fload|dload|lload|iload|aload)"); - map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)"); - map.put("cpinstruction", "(ldc2_w|invokeinterface|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); - map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)"); - map.put("branchinstruction", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); - map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)"); - map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)"); - map.put("select", "(tableswitch|lookupswitch)"); - map.put("ifinstruction", "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)"); - map.put("jsrinstruction", "(jsr|jsr_w)"); - map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)"); - map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)"); - map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)"); - map.put("typedinstruction", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); - map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)"); - map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)"); - map.put("indexedinstruction", "(lload|lstore|fload|ldc2_w|invokeinterface|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); - map.put("pushinstruction", "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)"); - map.put("stackproducer", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); - map.put("stackconsumer", "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); - map.put("exceptionthrower", "(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|ldc|invokestatic|daload)"); - map.put("loadclass", "(multianewarray|invokeinterface|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); - map.put("instructiontargeter", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); - - // Some aliases - map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)"); - map.put("if_acmp", "(if_acmpeq|if_acmpne)"); - map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)"); - - // Precompile some aliases first - map.put("iconst", precompile(Constants.ICONST_0, Constants.ICONST_5, Constants.ICONST_M1)); - map.put("lconst", new String(new char[] { '(', makeChar(Constants.LCONST_0), '|', - makeChar(Constants.LCONST_1), ')' })); - map.put("dconst", new String(new char[] { '(', makeChar(Constants.DCONST_0), '|', - makeChar(Constants.DCONST_1), ')' })); - map.put("fconst", new String(new char[] { '(', makeChar(Constants.FCONST_0), '|', - makeChar(Constants.FCONST_1), ')' })); - - map.put("iload", precompile(Constants.ILOAD_0, Constants.ILOAD_3, Constants.ILOAD)); - map.put("dload", precompile(Constants.DLOAD_0, Constants.DLOAD_3, Constants.DLOAD)); - map.put("fload", precompile(Constants.FLOAD_0, Constants.FLOAD_3, Constants.FLOAD)); - map.put("aload", precompile(Constants.ALOAD_0, Constants.ALOAD_3, Constants.ALOAD)); - - map.put("istore", precompile(Constants.ISTORE_0, Constants.ISTORE_3, Constants.ISTORE)); - map.put("dstore", precompile(Constants.DSTORE_0, Constants.DSTORE_3, Constants.DSTORE)); - map.put("fstore", precompile(Constants.FSTORE_0, Constants.FSTORE_3, Constants.FSTORE)); - map.put("astore", precompile(Constants.ASTORE_0, Constants.ASTORE_3, Constants.ASTORE)); - - // Compile strings - - for(Iterator i = map.keySet().iterator(); i.hasNext(); ) { - String key = (String)i.next(); - String value = (String)map.get(key); - - char ch = value.charAt(1); // Omit already precompiled patterns - if(ch < OFFSET) { - map.put(key, compilePattern(value)); // precompile all patterns - } + public InstructionFinder(final InstructionList il) { + this.il = il; + reread(); } - // Add instruction alias to match anything - StringBuffer buf = new StringBuffer("("); - - for(short i=0; i < NO_OPCODES; i++) { - if(Constants.NO_OF_OPERANDS[i] != Constants.UNDEFINED) { // Not an invalid opcode - buf.append(makeChar(i)); - - if(i < NO_OPCODES - 1) - buf.append('|'); - } - } - buf.append(')'); - - map.put("instruction", buf.toString()); - } - - private static String precompile(short from, short to, short extra) { - StringBuffer buf = new StringBuffer("("); - - for(short i=from; i <= to; i++) { - buf.append(makeChar(i)); - buf.append('|'); + /** + * Reread the instruction list, e.g., after you've altered the list upon a + * match. + */ + public final void reread() { + final int size = il.getLength(); + final char[] buf = new char[size]; // Create a string with length equal to il length + handles = il.getInstructionHandles(); + // Map opcodes to characters + for (int i = 0; i < size; i++) { + buf[i] = makeChar(handles[i].getInstruction().getOpcode()); + } + il_string = new String(buf); } - buf.append(makeChar(extra)); - buf.append(")"); - return buf.toString(); - } - /* - * Internal debugging routines. - */ - private static final String pattern2string(String pattern) { - return pattern2string(pattern, true); - } - - private static final String pattern2string(String pattern, boolean make_string) { - StringBuffer buf = new StringBuffer(); - - for(int i=0; i < pattern.length(); i++) { - char ch = pattern.charAt(i); - - if(ch >= OFFSET) { - if(make_string) - buf.append(Constants.OPCODE_NAMES[ch - OFFSET]); - else - buf.append((int)(ch - OFFSET)); - } else - buf.append(ch); + /** + * Map symbolic instruction names like "getfield" to a single character. + * + * @param pattern + * instruction pattern in lower case + * @return encoded string for a pattern such as "BranchInstruction". + */ + private static String mapName( final String pattern ) { + final String result = map.get(pattern); + if (result != null) { + return result; + } + for (short i = 0; i < NO_OPCODES; i++) { + if (pattern.equals(Const.getOpcodeName(i))) { + return "" + makeChar(i); + } + } + throw new RuntimeException("Instruction unknown: " + pattern); } - return buf.toString(); - } + + /** + * Replace symbolic names of instructions with the appropiate character and + * remove all white space from string. Meta characters such as +, * are + * ignored. + * + * @param pattern + * The pattern to compile + * @return translated regular expression string + */ + private static String compilePattern( final String pattern ) { + //Bug: BCEL-77 - Instructions are assumed to be english, to avoid odd Locale issues + final String lower = pattern.toLowerCase(Locale.ENGLISH); + final StringBuilder buf = new StringBuilder(); + final int size = pattern.length(); + for (int i = 0; i < size; i++) { + char ch = lower.charAt(i); + if (Character.isLetterOrDigit(ch)) { + final StringBuilder name = new StringBuilder(); + while ((Character.isLetterOrDigit(ch) || ch == '_') && i < size) { + name.append(ch); + if (++i < size) { + ch = lower.charAt(i); + } else { + break; + } + } + i--; + buf.append(mapName(name.toString())); + } else if (!Character.isWhitespace(ch)) { + buf.append(ch); + } + } + return buf.toString(); + } + + + /** + * @return the matched piece of code as an array of instruction (handles) + */ + private InstructionHandle[] getMatch( final int matched_from, final int match_length ) { + final InstructionHandle[] match = new InstructionHandle[match_length]; + System.arraycopy(handles, matched_from, match, 0, match_length); + return match; + } + + + /** + * Search for the given pattern in the instruction list. You can search for + * any valid opcode via its symbolic name, e.g. "istore". You can also use a + * super class or an interface name to match a whole set of instructions, e.g. + * "BranchInstruction" or "LoadInstruction". "istore" is also an alias for all + * "istore_x" instructions. Additional aliases are "if" for "ifxx", "if_icmp" + * for "if_icmpxx", "if_acmp" for "if_acmpxx". + * + * Consecutive instruction names must be separated by white space which will + * be removed during the compilation of the pattern. + * + * For the rest the usual pattern matching rules for regular expressions + * apply. + *

    + * Example pattern: + * + *

    +     * search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
    +     * 
    + * + *

    + * If you alter the instruction list upon a match such that other matching + * areas are affected, you should call reread() to update the finder and call + * search() again, because the matches are cached. + * + * @param pattern + * the instruction pattern to search for, where case is ignored + * @param from + * where to start the search in the instruction list + * @param constraint + * optional CodeConstraint to check the found code pattern for + * user-defined constraints + * @return iterator of matches where e.nextElement() returns an array of + * instruction handles describing the matched area + */ + public final Iterator search( final String pattern, + final InstructionHandle from, final CodeConstraint constraint ) { + final String search = compilePattern(pattern); + int start = -1; + for (int i = 0; i < handles.length; i++) { + if (handles[i] == from) { + start = i; // Where to start search from (index) + break; + } + } + if (start == -1) { + throw new ClassGenException("Instruction handle " + from + + " not found in instruction list."); + } + final Pattern regex = Pattern.compile(search); + final List matches = new ArrayList<>(); + final Matcher matcher = regex.matcher(il_string); + while (start < il_string.length() && matcher.find(start)) { + final int startExpr = matcher.start(); + final int endExpr = matcher.end(); + final int lenExpr = endExpr - startExpr; + final InstructionHandle[] match = getMatch(startExpr, lenExpr); + if ((constraint == null) || constraint.checkCode(match)) { + matches.add(match); + } + start = endExpr; + } + return matches.iterator(); + } + + + /** + * Start search beginning from the start of the given instruction list. + * + * @param pattern + * the instruction pattern to search for, where case is ignored + * @return iterator of matches where e.nextElement() returns an array of + * instruction handles describing the matched area + */ + public final Iterator search( final String pattern ) { + return search(pattern, il.getStart(), null); + } + + + /** + * Start search beginning from `from'. + * + * @param pattern + * the instruction pattern to search for, where case is ignored + * @param from + * where to start the search in the instruction list + * @return iterator of matches where e.nextElement() returns an array of + * instruction handles describing the matched area + */ + public final Iterator search( final String pattern, + final InstructionHandle from ) { + return search(pattern, from, null); + } + + + /** + * Start search beginning from the start of the given instruction list. Check + * found matches with the constraint object. + * + * @param pattern + * the instruction pattern to search for, case is ignored + * @param constraint + * constraints to be checked on matching code + * @return instruction handle or `null' if the match failed + */ + public final Iterator search( final String pattern, + final CodeConstraint constraint ) { + return search(pattern, il.getStart(), constraint); + } + + + /** + * Convert opcode number to char. + */ + private static char makeChar( final short opcode ) { + return (char) (opcode + OFFSET); + } + + + /** + * @return the inquired instruction list + */ + public final InstructionList getInstructionList() { + return il; + } + + /** + * Code patterns found may be checked using an additional user-defined + * constraint object whether they really match the needed criterion. I.e., + * check constraints that can not expressed with regular expressions. + * + */ + public interface CodeConstraint { + + /** + * @param match + * array of instructions matching the requested pattern + * @return true if the matched area is really useful + */ + boolean checkCode( InstructionHandle[] match ); + } + + // Initialize pattern map + static { + map.put("arithmeticinstruction","(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)"); + map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial|invokedynamic)"); + map.put("arrayinstruction", "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)"); + map.put("gotoinstruction", "(goto|goto_w)"); + map.put("conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)"); + map.put("localvariableinstruction","(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)"); + map.put("loadinstruction", "(fload|dload|lload|iload|aload)"); + map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)"); + map.put("cpinstruction", "(ldc2_w|invokeinterface|invokedynamic|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); + map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)"); + map.put("branchinstruction", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); + map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)"); + map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)"); + map.put("select", "(tableswitch|lookupswitch)"); + map.put("ifinstruction", "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)"); + map.put("jsrinstruction", "(jsr|jsr_w)"); + map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)"); + map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)"); + map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)"); + map.put("typedinstruction", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); + map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)"); + map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)"); + map.put("indexedinstruction", "(lload|lstore|fload|ldc2_w|invokeinterface|invokedynamic|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); + map.put("pushinstruction", "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)"); + map.put("stackproducer", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|invokedynamic|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); + map.put("stackconsumer", "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); + map.put("exceptionthrower","(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|invokedynamic|ldc|invokestatic|daload)"); + map.put("loadclass", "(multianewarray|invokeinterface|invokedynamic|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); + map.put("instructiontargeter", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); + // Some aliases + map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)"); + map.put("if_acmp", "(if_acmpeq|if_acmpne)"); + map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)"); + // Precompile some aliases first + map.put("iconst", precompile(Const.ICONST_0, Const.ICONST_5, Const.ICONST_M1)); + map.put("lconst", new String(new char[] { '(', makeChar(Const.LCONST_0), '|', makeChar(Const.LCONST_1), ')' })); + map.put("dconst", new String(new char[] { '(', makeChar(Const.DCONST_0), '|', makeChar(Const.DCONST_1), ')' })); + map.put("fconst", new String(new char[] { '(', makeChar(Const.FCONST_0), '|', makeChar(Const.FCONST_1), '|', makeChar(Const.FCONST_2), ')' })); + map.put("lload", precompile(Const.LLOAD_0, Const.LLOAD_3, Const.LLOAD)); + map.put("iload", precompile(Const.ILOAD_0, Const.ILOAD_3, Const.ILOAD)); + map.put("dload", precompile(Const.DLOAD_0, Const.DLOAD_3, Const.DLOAD)); + map.put("fload", precompile(Const.FLOAD_0, Const.FLOAD_3, Const.FLOAD)); + map.put("aload", precompile(Const.ALOAD_0, Const.ALOAD_3, Const.ALOAD)); + map.put("lstore", precompile(Const.LSTORE_0, Const.LSTORE_3, Const.LSTORE)); + map.put("istore", precompile(Const.ISTORE_0, Const.ISTORE_3, Const.ISTORE)); + map.put("dstore", precompile(Const.DSTORE_0, Const.DSTORE_3, Const.DSTORE)); + map.put("fstore", precompile(Const.FSTORE_0, Const.FSTORE_3, Const.FSTORE)); + map.put("astore", precompile(Const.ASTORE_0, Const.ASTORE_3, Const.ASTORE)); + // Compile strings + for (final Map.Entry entry : map.entrySet()) { + final String key = entry.getKey(); + final String value = entry.getValue(); + final char ch = value.charAt(1); // Omit already precompiled patterns + if (ch < OFFSET) { + map.put(key, compilePattern(value)); // precompile all patterns + } + } + // Add instruction alias to match anything + final StringBuilder buf = new StringBuilder("("); + for (short i = 0; i < NO_OPCODES; i++) { + if (Const.getNoOfOperands(i) != Const.UNDEFINED) { // Not an invalid opcode + buf.append(makeChar(i)); + if (i < NO_OPCODES - 1) { + buf.append('|'); + } + } + } + buf.append(')'); + map.put("instruction", buf.toString()); + } + + + private static String precompile( final short from, final short to, final short extra ) { + final StringBuilder buf = new StringBuilder("("); + for (short i = from; i <= to; i++) { + buf.append(makeChar(i)); + buf.append('|'); + } + buf.append(makeChar(extra)); + buf.append(")"); + return buf.toString(); + } + + + /* + * Internal debugging routines. + */ +// private static final String pattern2string( String pattern ) { +// return pattern2string(pattern, true); +// } + + +// private static final String pattern2string( String pattern, boolean make_string ) { +// StringBuffer buf = new StringBuffer(); +// for (int i = 0; i < pattern.length(); i++) { +// char ch = pattern.charAt(i); +// if (ch >= OFFSET) { +// if (make_string) { +// buf.append(Constants.getOpcodeName(ch - OFFSET)); +// } else { +// buf.append((ch - OFFSET)); +// } +// } else { +// buf.append(ch); +// } +// } +// return buf.toString(); +// } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java index b2c6725c1e1..d3a368d952a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java @@ -21,146 +21,143 @@ package com.sun.org.apache.bcel.internal.util; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Code; +import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.ExceptionTable; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Convert methods and fields into HTML file. * - * @author M. Dahm + * @version $Id: MethodHTML.java 1749603 2016-06-21 20:50:19Z ggregory $ * */ -final class MethodHTML implements com.sun.org.apache.bcel.internal.Constants { - private String class_name; // name of current class - private PrintWriter file; // file to write to - private ConstantHTML constant_html; - private AttributeHTML attribute_html; +final class MethodHTML { - MethodHTML(String dir, String class_name, - Method[] methods, Field[] fields, - ConstantHTML constant_html, AttributeHTML attribute_html) throws IOException - { - this.class_name = class_name; - this.attribute_html = attribute_html; - this.constant_html = constant_html; + private final String class_name; // name of current class + private final PrintWriter file; // file to write to + private final ConstantHTML constant_html; + private final AttributeHTML attribute_html; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html")); - file.println(""); - file.println("" + - ""); - for(int i=0; i < fields.length; i++) - writeField(fields[i]); - file.println("
    Access flagsTypeField name
    "); - - file.println("" + - "" + - ""); - for(int i=0; i < methods.length; i++) - writeMethod(methods[i], i); - - file.println("
    Access flagsReturn typeMethod nameArguments
    "); - file.close(); - } - - /** - * Print field of class. - * - * @param field field to print - * @exception java.io.IOException - */ - private void writeField(Field field) throws IOException { - String type = Utility.signatureToString(field.getSignature()); - String name = field.getName(); - String access = Utility.accessToString(field.getAccessFlags()); - Attribute[] attributes; - - access = Utility.replace(access, " ", " "); - - file.print("" + access + "\n" + - Class2HTML.referenceType(type) + "" + - name + ""); - - attributes = field.getAttributes(); - - // Write them to the Attributes.html file with anchor "[]" - for(int i=0; i < attributes.length; i++) - attribute_html.writeAttribute(attributes[i], name + "@" + i); - - for(int i=0; i < attributes.length; i++) { - if(attributes[i].getTag() == ATTR_CONSTANT_VALUE) { // Default value - String str = ((ConstantValue)attributes[i]).toString(); - - // Reference attribute in _attributes.html - file.print("= " + str + "\n"); - break; - } - } - - file.println(""); - } - - private final void writeMethod(Method method, int method_number) throws IOException { - // Get raw signature - String signature = method.getSignature(); - // Get array of strings containing the argument types - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - // Get return type string - String type = Utility.methodSignatureReturnType(signature, false); - // Get method name - String name = method.getName(), html_name; - // Get method's access flags - String access = Utility.accessToString(method.getAccessFlags()); - // Get the method's attributes, the Code Attribute in particular - Attribute[] attributes = method.getAttributes(); - - /* HTML doesn't like names like and spaces are places to break - * lines. Both we don't want... - */ - access = Utility.replace(access, " ", " "); - html_name = Class2HTML.toHTML(name); - - file.print("" + - access + ""); - - file.print("" + Class2HTML.referenceType(type) + "" + - "" + html_name + "\n("); - - for(int i=0; i < args.length; i++) { - file.print(Class2HTML.referenceType(args[i])); - if(i < args.length - 1) - file.print(", "); - } - - file.print(")"); - - // Check for thrown exceptions - for(int i=0; i < attributes.length; i++) { - attribute_html.writeAttribute(attributes[i], "method" + method_number + "@" + i, - method_number); - - byte tag = attributes[i].getTag(); - if(tag == ATTR_EXCEPTIONS) { - file.print("throws"); - int[] exceptions = ((ExceptionTable)attributes[i]).getExceptionIndexTable(); - - for(int j=0; j < exceptions.length; j++) { - file.print(constant_html.referenceConstant(exceptions[j])); - - if(j < exceptions.length - 1) - file.print(", "); + MethodHTML(final String dir, final String class_name, final Method[] methods, final Field[] fields, + final ConstantHTML constant_html, final AttributeHTML attribute_html) throws IOException { + this.class_name = class_name; + this.attribute_html = attribute_html; + this.constant_html = constant_html; + file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html")); + file.println(""); + file.println("" + + ""); + for (final Field field : fields) { + writeField(field); + } + file.println("
    Access flagsTypeField name
    "); + file.println("" + + "" + + ""); + for (int i = 0; i < methods.length; i++) { + writeMethod(methods[i], i); + } + file.println("
    Access flagsReturn typeMethod nameArguments
    "); + file.close(); + } + + + /** + * Print field of class. + * + * @param field field to print + * @throws java.io.IOException + */ + private void writeField( final Field field ) throws IOException { + final String type = Utility.signatureToString(field.getSignature()); + final String name = field.getName(); + String access = Utility.accessToString(field.getAccessFlags()); + Attribute[] attributes; + access = Utility.replace(access, " ", " "); + file.print("" + access + "\n" + + Class2HTML.referenceType(type) + "" + name + + ""); + attributes = field.getAttributes(); + // Write them to the Attributes.html file with anchor "[]" + for (int i = 0; i < attributes.length; i++) { + attribute_html.writeAttribute(attributes[i], name + "@" + i); + } + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].getTag() == Const.ATTR_CONSTANT_VALUE) { // Default value + final String str = ((ConstantValue) attributes[i]).toString(); + // Reference attribute in _attributes.html + file.print("= " + str + "\n"); + break; + } + } + file.println(""); + } + + + private void writeMethod( final Method method, final int method_number ) { + // Get raw signature + final String signature = method.getSignature(); + // Get array of strings containing the argument types + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + // Get return type string + final String type = Utility.methodSignatureReturnType(signature, false); + // Get method name + final String name = method.getName(); + String html_name; + // Get method's access flags + String access = Utility.accessToString(method.getAccessFlags()); + // Get the method's attributes, the Code Attribute in particular + final Attribute[] attributes = method.getAttributes(); + /* HTML doesn't like names like and spaces are places to break + * lines. Both we don't want... + */ + access = Utility.replace(access, " ", " "); + html_name = Class2HTML.toHTML(name); + file.print("" + access + ""); + file.print("" + Class2HTML.referenceType(type) + "" + "" + html_name + + "\n("); + for (int i = 0; i < args.length; i++) { + file.print(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + file.print(", "); + } + } + file.print(")"); + // Check for thrown exceptions + for (int i = 0; i < attributes.length; i++) { + attribute_html.writeAttribute(attributes[i], "method" + method_number + "@" + i, + method_number); + final byte tag = attributes[i].getTag(); + if (tag == Const.ATTR_EXCEPTIONS) { + file.print("throws"); + final int[] exceptions = ((ExceptionTable) attributes[i]).getExceptionIndexTable(); + for (int j = 0; j < exceptions.length; j++) { + file.print(constant_html.referenceConstant(exceptions[j])); + if (j < exceptions.length - 1) { + file.print(", "); + } + } + file.println(""); + } else if (tag == Const.ATTR_CODE) { + final Attribute[] c_a = ((Code) attributes[i]).getAttributes(); + for (int j = 0; j < c_a.length; j++) { + attribute_html.writeAttribute(c_a[j], "method" + method_number + "@" + i + "@" + + j, method_number); + } + } } - file.println(""); - } else if(tag == ATTR_CODE) { - Attribute[] c_a = ((Code)attributes[i]).getAttributes(); - - for(int j=0; j < c_a.length; j++) - attribute_html.writeAttribute(c_a[j], "method" + method_number + "@" + i + "@" + j, - method_number); - } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java index f38198a236b..00d1ed562b5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,52 +17,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.util; - import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** - * Abstract definition of a class repository. Instances may be used - * to load classes from different sources and may be used in the + * Abstract definition of a class repository. Instances may be used to load + * classes from different sources and may be used in the * Repository.setRepository method. * * @see com.sun.org.apache.bcel.internal.Repository - * @author M. Dahm - * @author David Dixon-Peugh + * @version $Id: Repository.java 1747278 2016-06-07 17:28:43Z britter $ */ -public interface Repository extends java.io.Serializable { - /** - * Store the provided class under "clazz.getClassName()" - */ - public void storeClass(JavaClass clazz); +public interface Repository { - /** - * Remove class from repository - */ - public void removeClass(JavaClass clazz); + /** + * Store the provided class under "clazz.getClassName()" + */ + void storeClass(JavaClass clazz); - /** - * Find the class with the name provided, if the class - * isn't there, return NULL. - */ - public JavaClass findClass(String className); + /** + * Remove class from repository + */ + void removeClass(JavaClass clazz); - /** - * Find the class with the name provided, if the class - * isn't there, make an attempt to load it. - */ - public JavaClass loadClass(String className) - throws java.lang.ClassNotFoundException; + /** + * Find the class with the name provided, if the class isn't there, return + * NULL. + */ + JavaClass findClass(String className); - /** - * Find the JavaClass instance for the given run-time class object - */ - public JavaClass loadClass(Class clazz) - throws java.lang.ClassNotFoundException; + /** + * Find the class with the name provided, if the class isn't there, make an + * attempt to load it. + */ + JavaClass loadClass(String className) throws java.lang.ClassNotFoundException; - /** Clear all entries from cache. - */ - public void clear(); + /** + * Find the JavaClass instance for the given run-time class object + */ + JavaClass loadClass(Class clazz) throws java.lang.ClassNotFoundException; + + /** + * Clear all entries from cache. + */ + void clear(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SecuritySupport.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SecuritySupport.java deleted file mode 100644 index 3d8447e95b6..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SecuritySupport.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FilenameFilter; -import java.lang.ClassLoader; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ListResourceBundle; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -/** - * This class is duplicated for each subpackage so keep it in sync. It is - * package private and therefore is not exposed as part of any API. - * - * @xerces.internal - */ -public final class SecuritySupport { - - private static final SecuritySupport securitySupport = new SecuritySupport(); - - /** - * Return an instance of this class. - */ - public static SecuritySupport getInstance() { - return securitySupport; - } - - static ClassLoader getContextClassLoader() { - return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { - } - return cl; - } - }); - } - - static ClassLoader getSystemClassLoader() { - return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) { - } - return cl; - } - }); - } - - static ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) { - } - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - public static String getSystemProperty(final String propName) { - return (String) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - static FileInputStream getFileInputStream(final File file) - throws FileNotFoundException { - try { - return (FileInputStream) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws FileNotFoundException { - return new FileInputStream(file); - } - }); - } catch (PrivilegedActionException e) { - throw (FileNotFoundException) e.getException(); - } - } - - /** - * Gets a resource bundle using the specified base name, the default locale, - * and the caller's class loader. - * - * @param bundle the base name of the resource bundle, a fully qualified - * class name - * @return a resource bundle for the given base name and the default locale - */ - public static ListResourceBundle getResourceBundle(String bundle) { - return getResourceBundle(bundle, Locale.getDefault()); - } - - /** - * Gets a resource bundle using the specified base name and locale, and the - * caller's class loader. - * - * @param bundle the base name of the resource bundle, a fully qualified - * class name - * @param locale the locale for which a resource bundle is desired - * @return a resource bundle for the given base name and locale - */ - public static ListResourceBundle getResourceBundle(final String bundle, final Locale locale) { - return AccessController.doPrivileged(new PrivilegedAction() { - public ListResourceBundle run() { - try { - return (ListResourceBundle) ResourceBundle.getBundle(bundle, locale); - } catch (MissingResourceException e) { - try { - return (ListResourceBundle) ResourceBundle.getBundle(bundle, new Locale("en", "US")); - } catch (MissingResourceException e2) { - throw new MissingResourceException( - "Could not load any resource bundle by " + bundle, bundle, ""); - } - } - } - }); - } - - public static String[] getFileList(final File f, final FilenameFilter filter) { - return ((String[]) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return f.list(filter); - } - })); - } - - public static boolean getFileExists(final File f) { - return ((Boolean) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return f.exists() ? Boolean.TRUE : Boolean.FALSE; - } - })).booleanValue(); - } - - static long getLastModified(final File f) { - return ((Long) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return f.lastModified(); - } - })).longValue(); - } - - - /** - * Figure out which ClassLoader to use. - */ - public static ClassLoader findClassLoader() - { - if (System.getSecurityManager()!=null) { - //this will ensure bootclassloader is used - return null; - } else { - return SecuritySupport.class.getClassLoader(); - } - } // findClassLoader():ClassLoader - - private SecuritySupport() { - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java index 42fa078a37c..bde982d7251 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,136 +17,161 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.util; +import java.io.IOException; +import java.io.InputStream; -import java.io.*; - +import com.sun.org.apache.bcel.internal.classfile.ClassParser; +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import java.lang.ref.SoftReference; import java.util.HashMap; - -import com.sun.org.apache.bcel.internal.classfile.*; +import java.util.Map; /** - * This repository is used in situations where a Class is created - * outside the realm of a ClassLoader. Classes are loaded from - * the file systems using the paths specified in the given - * class path. By default, this is the value returned by - * ClassPath.getClassPath(). - *
    - * It is designed to be used as a singleton, however it - * can also be used with custom classpaths. - * -/** - * Abstract definition of a class repository. Instances may be used - * to load classes from different sources and may be used in the - * Repository.setRepository method. + * This repository is used in situations where a Class is created outside the + * realm of a ClassLoader. Classes are loaded from the file systems using the + * paths specified in the given class path. By default, this is the value + * returned by ClassPath.getClassPath().
    + * This repository uses a factory design, allowing it to maintain a collection + * of different classpaths, and as such It is designed to be used as a singleton + * per classpath. * * @see com.sun.org.apache.bcel.internal.Repository * - * @author M. Dahm - * @author David Dixon-Peugh + * @version $Id: SyntheticRepository.java 1748124 2016-06-13 08:02:16Z ggregory + * $ */ public class SyntheticRepository implements Repository { - private static HashMap _instances = new HashMap(); // CLASSPATH X REPOSITORY - - private HashMap _loadedClasses = new HashMap(); // CLASSNAME X JAVACLASS + // CLASSNAME X JAVACLASS + private final Map> loadedClasses = new HashMap<>(); private SyntheticRepository() { } - public static SyntheticRepository getInstance() { - return new SyntheticRepository(); - } - - /** - * Store a new JavaClass instance into this Repository. - */ - public void storeClass(JavaClass clazz) { - _loadedClasses.put(clazz.getClassName(), clazz); - clazz.setRepository(this); - } - - /** - * Remove class from repository - */ - public void removeClass(JavaClass clazz) { - _loadedClasses.remove(clazz.getClassName()); - } - - /** - * Find an already defined (cached) JavaClass object by name. - */ - public JavaClass findClass(String className) { - return (JavaClass)_loadedClasses.get(className); - } - - /** - * Load a JavaClass object for the given class name using - * the CLASSPATH environment variable. - */ - public JavaClass loadClass(String className) - throws ClassNotFoundException - { - if(className == null || className.equals("")) { - throw new IllegalArgumentException("Invalid class name " + className); + public static SyntheticRepository getInstance() { + return new SyntheticRepository(); } - className = className.replace('/', '.'); // Just in case, canonical form - - IOException e = new IOException("Couldn't find: " + className + ".class"); - throw new ClassNotFoundException("Exception while looking for class " + - className + ": " + e.toString()); - } - - /** - * Try to find class source via getResourceAsStream(). - * @see Class - * @return JavaClass object for given runtime class - */ - public JavaClass loadClass(Class clazz) throws ClassNotFoundException { - String className = clazz.getName(); - String name = className; - int i = name.lastIndexOf('.'); - - if(i > 0) { - name = name.substring(i + 1); + /** + * Store a new JavaClass instance into this Repository. + */ + @Override + public void storeClass(final JavaClass clazz) { + loadedClasses.put(clazz.getClassName(), new SoftReference<>(clazz)); + clazz.setRepository(this); } - return loadClass(clazz.getResourceAsStream(name + ".class"), className); - } - - private JavaClass loadClass(InputStream is, String className) - throws ClassNotFoundException - { - JavaClass clazz = findClass(className); - - if(clazz != null) { - return clazz; + /** + * Remove class from repository + */ + @Override + public void removeClass(final JavaClass clazz) { + loadedClasses.remove(clazz.getClassName()); } - try { - if(is != null) { - ClassParser parser = new ClassParser(is, className); - clazz = parser.parse(); - - storeClass(clazz); - - return clazz; - } - } catch(IOException e) { - throw new ClassNotFoundException("Exception while looking for class " + - className + ": " + e.toString()); + /** + * Find an already defined (cached) JavaClass object by name. + */ + @Override + public JavaClass findClass(final String className) { + final SoftReference ref = loadedClasses.get(className); + if (ref == null) { + return null; + } + return ref.get(); } - throw new ClassNotFoundException("SyntheticRepository could not load " + - className); - } + /** + * Finds a JavaClass object by name. If it is already in this Repository, the + * Repository version is returned. + * + * @param className the name of the class + * @return the JavaClass object + * @throws ClassNotFoundException if the class is not in the Repository + */ + @Override + public JavaClass loadClass(String className) throws ClassNotFoundException { + if ((className == null) || className.isEmpty()) { + throw new IllegalArgumentException("Invalid class name " + className); + } + className = className.replace('/', '.'); // Just in case, canonical form + final JavaClass clazz = findClass(className); + if (clazz != null) { + return clazz; + } - /** Clear all entries from cache. - */ - public void clear() { - _loadedClasses.clear(); - } + IOException e = new IOException("Couldn't find: " + className + ".class"); + throw new ClassNotFoundException("Exception while looking for class " + + className + ": " + e, e); + } + + /** + * Find the JavaClass object for a runtime Class object. If a class with the + * same name is already in this Repository, the Repository version is + * returned. Otherwise, getResourceAsStream() is called on the Class object + * to find the class's representation. If the representation is found, it is + * added to the Repository. + * + * @see Class + * @param clazz the runtime Class object + * @return JavaClass object for given runtime class + * @throws ClassNotFoundException if the class is not in the Repository, and + * its representation could not be found + */ + @Override + public JavaClass loadClass(final Class clazz) throws ClassNotFoundException { + final String className = clazz.getName(); + final JavaClass repositoryClass = findClass(className); + if (repositoryClass != null) { + return repositoryClass; + } + String name = className; + final int i = name.lastIndexOf('.'); + if (i > 0) { + name = name.substring(i + 1); + } + JavaClass cls = null; + try (InputStream clsStream = clazz.getResourceAsStream(name + ".class")) { + return cls = loadClass(clsStream, className); + } catch (final IOException e) { + return cls; + } + + } + + + private JavaClass loadClass(final InputStream is, final String className) + throws ClassNotFoundException { + try { + if (is != null) { + final ClassParser parser = new ClassParser(is, className); + final JavaClass clazz = parser.parse(); + storeClass(clazz); + return clazz; + } + } catch (final IOException e) { + throw new ClassNotFoundException("Exception while looking for class " + + className + ": " + e, e); + } finally { + if (is != null) { + try { + is.close(); + } catch (final IOException e) { + // ignored + } + } + } + throw new ClassNotFoundException("SyntheticRepository could not load " + + className); + } + + /** + * Clear all entries from cache. + */ + @Override + public void clear() { + loadedClasses.clear(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/package.html b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/package.html index b14ec463502..e710072cbaa 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/package.html +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/package.html @@ -1,14 +1,30 @@ +

    This package contains utility classes for the -Byte Code Engineering +Byte Code Engineering Library, namely:

    @@ -17,7 +33,7 @@ Library, namely:

  • A converter for class files to HTML
  • A tool to find instructions patterns via regular expressions
  • A class to find classes as defined in the CLASSPATH
  • -
  • A class loader that allows to create clases at run time
  • +
  • A class loader that allows to create classes at run time
  • diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Constants.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Constants.java index 22bc7616a2c..a1489c2c5a8 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Constants.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -23,13 +23,68 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.ArithmeticInstruction; +import com.sun.org.apache.bcel.internal.generic.ArrayInstruction; +import com.sun.org.apache.bcel.internal.generic.ConversionInstruction; +import com.sun.org.apache.bcel.internal.generic.Instruction; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; +import com.sun.org.apache.bcel.internal.generic.LocalVariableInstruction; +import com.sun.org.apache.bcel.internal.generic.ReturnInstruction; +import com.sun.org.apache.bcel.internal.generic.StackInstruction; /** * @author Jacek Ambroziak * @author Santiago Pericas-Geertsen */ -public interface Constants extends InstructionConstants { +public interface Constants { + public static final Instruction ACONST_NULL = InstructionConst.ACONST_NULL; + public static final Instruction ATHROW = InstructionConst.ATHROW; + public static final Instruction DCMPG = InstructionConst.DCMPG; + public static final Instruction DCONST_0 = InstructionConst.DCONST_0; + public static final Instruction ICONST_0 = InstructionConst.ICONST_0; + public static final Instruction ICONST_1 = InstructionConst.ICONST_1; + public static final Instruction NOP = InstructionConst.NOP; + + + public static final StackInstruction DUP = InstructionConst.DUP; + public static final StackInstruction DUP2 = InstructionConst.DUP2; + public static final StackInstruction DUP_X1 = InstructionConst.DUP_X1; + public static final StackInstruction DUP_X2 = InstructionConst.DUP_X2; + public static final StackInstruction POP = InstructionConst.POP; + public static final StackInstruction POP2 = InstructionConst.POP2; + public static final StackInstruction SWAP = InstructionConst.SWAP; + + public static final LocalVariableInstruction ALOAD_0 = InstructionConst.ALOAD_0; + public static final LocalVariableInstruction ALOAD_1 = InstructionConst.ALOAD_1; + public static final LocalVariableInstruction ALOAD_2 = InstructionConst.ALOAD_2; + public static final LocalVariableInstruction ILOAD_1 = InstructionConst.ILOAD_1; + public static final LocalVariableInstruction ILOAD_2 = InstructionConst.ILOAD_2; + + public static final ArithmeticInstruction DADD = InstructionConst.DADD; + public static final ArithmeticInstruction IXOR = InstructionConst.IXOR; + + public static final ArrayInstruction AASTORE = InstructionConst.AASTORE; + public static final ArrayInstruction IASTORE = InstructionConst.IASTORE; + + public static final ConversionInstruction D2F = InstructionConst.D2F; + public static final ConversionInstruction D2I = InstructionConst.D2I; + public static final ConversionInstruction D2L = InstructionConst.D2L; + public static final ConversionInstruction F2D = InstructionConst.F2D; + public static final ConversionInstruction I2B = InstructionConst.I2B; + public static final ConversionInstruction I2C = InstructionConst.I2C; + public static final ConversionInstruction I2D = InstructionConst.I2D; + public static final ConversionInstruction I2F = InstructionConst.I2F; + public static final ConversionInstruction I2L = InstructionConst.I2L; + public static final ConversionInstruction I2S = InstructionConst.I2S; + public static final ConversionInstruction L2D = InstructionConst.L2D; + public static final ConversionInstruction L2I = InstructionConst.L2I; + + + public static final ReturnInstruction ARETURN = InstructionConst.ARETURN; + public static final ReturnInstruction IRETURN = InstructionConst.IRETURN; + public static final ReturnInstruction RETURN = InstructionConst.RETURN; + + // Error categories used to report errors to Parser.reportError() @@ -86,17 +141,17 @@ public interface Constants extends InstructionConstants { = "java.lang.String"; public static final int ACC_PUBLIC - = com.sun.org.apache.bcel.internal.Constants.ACC_PUBLIC; + = com.sun.org.apache.bcel.internal.Const.ACC_PUBLIC; public static final int ACC_SUPER - = com.sun.org.apache.bcel.internal.Constants.ACC_SUPER; + = com.sun.org.apache.bcel.internal.Const.ACC_SUPER; public static final int ACC_FINAL - = com.sun.org.apache.bcel.internal.Constants.ACC_FINAL; + = com.sun.org.apache.bcel.internal.Const.ACC_FINAL; public static final int ACC_PRIVATE - = com.sun.org.apache.bcel.internal.Constants.ACC_PRIVATE; + = com.sun.org.apache.bcel.internal.Const.ACC_PRIVATE; public static final int ACC_PROTECTED - = com.sun.org.apache.bcel.internal.Constants.ACC_PROTECTED; + = com.sun.org.apache.bcel.internal.Const.ACC_PROTECTED; public static final int ACC_STATIC - = com.sun.org.apache.bcel.internal.Constants.ACC_STATIC; + = com.sun.org.apache.bcel.internal.Const.ACC_STATIC; public static final String MODULE_SIG = "Ljava/lang/Module;"; diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java index dfaa2f7469b..b55d2a8f982 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -26,7 +26,7 @@ import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.InvokeInstruction; import com.sun.org.apache.bcel.internal.generic.LDC; @@ -824,7 +824,7 @@ class FunctionCall extends Expression { } il.append(new NEW(cpg.addClass(_className))); - il.append(InstructionConstants.DUP); + il.append(InstructionConst.DUP); for (int i = 0; i < n; i++) { final Expression arg = argument(i); @@ -935,7 +935,7 @@ class FunctionCall extends Expression { ADD_READS, ADD_READS_SIG); il.append(new INVOKEVIRTUAL(index)); - il.append(InstructionConstants.POP); + il.append(InstructionConst.POP); methodGen.markChunkEnd(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/AttributeSetMethodGenerator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/AttributeSetMethodGenerator.java index 79c4aad1996..a750f366672 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/AttributeSetMethodGenerator.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/AttributeSetMethodGenerator.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -52,7 +51,7 @@ public final class AttributeSetMethodGenerator extends MethodGenerator { } public AttributeSetMethodGenerator(String methodName, ClassGenerator classGen) { - super(com.sun.org.apache.bcel.internal.Constants.ACC_PRIVATE, + super(com.sun.org.apache.bcel.internal.Const.ACC_PRIVATE, com.sun.org.apache.bcel.internal.generic.Type.VOID, argTypes, argNames, methodName, classGen.getClassName(), diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/IntType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/IntType.java index a1f81ed6f0e..68933d14778 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/IntType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/IntType.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -41,7 +40,7 @@ import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; import com.sun.org.apache.bcel.internal.generic.ISTORE; import com.sun.org.apache.bcel.internal.generic.Instruction; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.NEW; import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants; @@ -247,27 +246,27 @@ public final class IntType extends NumberType { } public Instruction ADD() { - return InstructionConstants.IADD; + return InstructionConst.IADD; } public Instruction SUB() { - return InstructionConstants.ISUB; + return InstructionConst.ISUB; } public Instruction MUL() { - return InstructionConstants.IMUL; + return InstructionConst.IMUL; } public Instruction DIV() { - return InstructionConstants.IDIV; + return InstructionConst.IDIV; } public Instruction REM() { - return InstructionConstants.IREM; + return InstructionConst.IREM; } public Instruction NEG() { - return InstructionConstants.INEG; + return InstructionConst.INEG; } public Instruction LOAD(int slot) { diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java index 929a8dca4d2..28fdd1bfd17 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,7 +23,7 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler.util; import java.io.DataOutputStream; import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; import com.sun.org.apache.bcel.internal.generic.Instruction; import com.sun.org.apache.bcel.internal.generic.Visitor; @@ -43,7 +42,7 @@ abstract class MarkerInstruction extends Instruction { * generated byte code. */ public MarkerInstruction() { - super(Constants.UNDEFINED, (short) 0); + super(Const.UNDEFINED, (short) 0); } /** diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java index 1c101c1b4bb..d6f96c6cedc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ import java.util.Map; import java.util.Stack; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.Field; import com.sun.org.apache.bcel.internal.classfile.Method; import com.sun.org.apache.bcel.internal.generic.ALOAD; @@ -55,7 +55,7 @@ import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; import com.sun.org.apache.bcel.internal.generic.ISTORE; import com.sun.org.apache.bcel.internal.generic.Instruction; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; import com.sun.org.apache.bcel.internal.generic.InstructionHandle; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.InstructionTargeter; @@ -87,8 +87,6 @@ public class MethodGenerator extends MethodGen private static final String END_ELEMENT_SIG = START_ELEMENT_SIG; - private InstructionList _mapTypeSub; - private static final int DOM_INDEX = 1; private static final int ITERATOR_INDEX = 2; private static final int HANDLER_INDEX = 3; @@ -1315,8 +1313,8 @@ public class MethodGenerator extends MethodGen // other two are used for references to fields in the CopyLocals object InstructionHandle outlinedMethodCallSetup = oldMethCopyInIL.append(new NEW(cpg.addClass(argTypeName))); - oldMethCopyInIL.append(InstructionConstants.DUP); - oldMethCopyInIL.append(InstructionConstants.DUP); + oldMethCopyInIL.append(InstructionConst.DUP); + oldMethCopyInIL.append(InstructionConst.DUP); oldMethCopyInIL.append( new INVOKESPECIAL(cpg.addMethodref(argTypeName, "", "()V"))); @@ -1332,8 +1330,8 @@ public class MethodGenerator extends MethodGen outlinedMethodName, outlinedMethodGen.getSignature()))); } else { - oldMethCopyOutIL.append(InstructionConstants.THIS); - oldMethCopyOutIL.append(InstructionConstants.SWAP); + oldMethCopyOutIL.append(InstructionConst.THIS); + oldMethCopyOutIL.append(InstructionConst.SWAP); outlinedMethodRef = oldMethCopyOutIL.append( new INVOKEVIRTUAL(cpg.addMethodref( @@ -1479,7 +1477,7 @@ public class MethodGenerator extends MethodGen // CopyLocals prior to invocation of the // outlined method. oldMethCopyInIL.append( - InstructionConstants.DUP); + InstructionConst.DUP); InstructionHandle copyInLoad = oldMethCopyInIL.append( loadLocal(oldLocalVarIndex, varType)); @@ -1498,7 +1496,7 @@ public class MethodGenerator extends MethodGen // CopyLocals to the new local in the outlined // method newMethCopyInIL.append( - InstructionConstants.ALOAD_1); + InstructionConst.ALOAD_1); newMethCopyInIL.append(new GETFIELD(fieldRef)); newMethCopyInIL.append( storeLocal(newLocalVarIndex, varType)); @@ -1510,7 +1508,7 @@ public class MethodGenerator extends MethodGen // variable into a field in CopyLocals // method newMethCopyOutIL.append( - InstructionConstants.ALOAD_1); + InstructionConst.ALOAD_1); newMethCopyOutIL.append( loadLocal(newLocalVarIndex, varType)); newMethCopyOutIL.append(new PUTFIELD(fieldRef)); @@ -1520,7 +1518,7 @@ public class MethodGenerator extends MethodGen // method following invocation of the outlined // method. oldMethCopyOutIL.append( - InstructionConstants.DUP); + InstructionConst.DUP); oldMethCopyOutIL.append(new GETFIELD(fieldRef)); InstructionHandle copyOutStore = oldMethCopyOutIL.append( @@ -1667,7 +1665,7 @@ public class MethodGenerator extends MethodGen } // POP the reference to the CopyLocals object from the stack - oldMethCopyOutIL.append(InstructionConstants.POP); + oldMethCopyOutIL.append(InstructionConst.POP); // Now that the generation of the outlined code is complete, update // the old local variables with new start and end ranges, as required. @@ -1708,7 +1706,7 @@ public class MethodGenerator extends MethodGen // Insert the copying code into the outlined method newIL.insert(newMethCopyInIL); newIL.append(newMethCopyOutIL); - newIL.append(InstructionConstants.RETURN); + newIL.append(InstructionConst.RETURN); // Discard instructions in outlineable chunk from old method try { @@ -1999,8 +1997,8 @@ public class MethodGenerator extends MethodGen switch (inst.getOpcode()) { // Instructions that may have 16-bit or 32-bit branch targets. // The size of the branch offset might increase by two bytes. - case Constants.GOTO: - case Constants.JSR: + case Const.GOTO: + case Const.JSR: maxOffsetChange = maxOffsetChange + 2; break; // Instructions that contain padding for alignment purposes @@ -2008,29 +2006,29 @@ public class MethodGenerator extends MethodGen // accuracy, we should be able to discount any padding already // added to these instructions by InstructionList.setPosition(), // their APIs do not expose that information. - case Constants.TABLESWITCH: - case Constants.LOOKUPSWITCH: + case Const.TABLESWITCH: + case Const.LOOKUPSWITCH: maxOffsetChange = maxOffsetChange + 3; break; // Instructions that might be rewritten by this method as a // conditional branch followed by an unconditional branch. // The unconditional branch would require five bytes. - case Constants.IF_ACMPEQ: - case Constants.IF_ACMPNE: - case Constants.IF_ICMPEQ: - case Constants.IF_ICMPGE: - case Constants.IF_ICMPGT: - case Constants.IF_ICMPLE: - case Constants.IF_ICMPLT: - case Constants.IF_ICMPNE: - case Constants.IFEQ: - case Constants.IFGE: - case Constants.IFGT: - case Constants.IFLE: - case Constants.IFLT: - case Constants.IFNE: - case Constants.IFNONNULL: - case Constants.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: maxOffsetChange = maxOffsetChange + 5; break; } @@ -2077,7 +2075,7 @@ public class MethodGenerator extends MethodGen // InstructionList, add a new no-op to act as the target // of the new IF if (nextHandle == null) { - nextHandle = il.append(gotoHandle, NOP); + nextHandle = il.append(gotoHandle, InstructionConst.NOP); } // Make the new IF instruction branch around the GOTO diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java index 4a2e034afc9..19ccd36d2bb 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -33,7 +32,7 @@ import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; import com.sun.org.apache.bcel.internal.generic.Instruction; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; import com.sun.org.apache.bcel.internal.generic.NEW; @@ -296,27 +295,27 @@ public final class RealType extends NumberType { } public Instruction ADD() { - return InstructionConstants.DADD; + return InstructionConst.DADD; } public Instruction SUB() { - return InstructionConstants.DSUB; + return InstructionConst.DSUB; } public Instruction MUL() { - return InstructionConstants.DMUL; + return InstructionConst.DMUL; } public Instruction DIV() { - return InstructionConstants.DDIV; + return InstructionConst.DDIV; } public Instruction REM() { - return InstructionConstants.DREM; + return InstructionConst.DREM; } public Instruction NEG() { - return InstructionConstants.DNEG; + return InstructionConst.DNEG; } public Instruction LOAD(int slot) { @@ -332,7 +331,7 @@ public final class RealType extends NumberType { } public Instruction CMP(boolean less) { - return less ? InstructionConstants.DCMPG : InstructionConstants.DCMPL; + return less ? InstructionConst.DCMPG : InstructionConst.DCMPL; } public Instruction DUP() { diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHMessages.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHMessages.java index cdc4268d47e..8c796a6bcc9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHMessages.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHMessages.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,9 +20,9 @@ package com.sun.org.apache.xpath.internal.res; -import com.sun.org.apache.bcel.internal.util.SecuritySupport; import com.sun.org.apache.xml.internal.res.XMLMessages; -import java.util.ListResourceBundle; +import java.util.ResourceBundle; +import jdk.xml.internal.SecuritySupport; /** * A utility class for issuing XPath error messages. @@ -35,7 +34,7 @@ public class XPATHMessages extends XMLMessages { /** * The language specific resource object for XPath messages. */ - private static ListResourceBundle XPATHBundle = null; + private static ResourceBundle XPATHBundle = null; /** * The class name of the XPath error message string table. */ @@ -99,7 +98,7 @@ public class XPATHMessages extends XMLMessages { * * @return The formatted message string. */ - public static final String createXPATHMsg(ListResourceBundle fResourceBundle, + private static final String createXPATHMsg(ResourceBundle fResourceBundle, String msgKey, Object args[]) //throws Exception { diff --git a/jaxp/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java b/jaxp/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java index b75a612f839..4c27bba6012 100644 --- a/jaxp/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java +++ b/jaxp/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.text.MessageFormat; import java.util.Locale; +import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; @@ -42,6 +43,8 @@ import java.util.ResourceBundle; * This class contains utility methods for reading resources in the JAXP packages */ public class SecuritySupport { + public final static String NEWLINE = getSystemProperty("line.separator", "\n"); + /** * Cache for properties in java.home/conf/jaxp.properties */ @@ -71,7 +74,7 @@ public class SecuritySupport { } /** - * Reads JAXP system property with privilege + * Reads a system property with privilege * * @param propName the name of the property * @return the value of the property @@ -83,13 +86,51 @@ public class SecuritySupport { } /** - * Reads a system property. + * Reads a system property with privilege + * + * @param propName the name of the property + * @return the value of the property + */ + public static String getSystemProperty(final String propName, String defValue) { + String value = getSystemProperty(propName); + if (value == null) { + return defValue; + } + return value; + } + + /** + * Reads a system property with specified type. * * @param the type of the property value * @param type the type of the property value * @param propName the name of the property * @param defValue the default value - * @return the value of the property, or the default value of no system + * @return the value of the property, or the default value if no system + * property is found + */ + public static T getSystemProperty(Class type, String propName, String defValue) { + String value = getSystemProperty(propName); + if (value == null) { + value = defValue; + } + if (Integer.class.isAssignableFrom(type)) { + return type.cast(Integer.parseInt(value)); + } else if (Boolean.class.isAssignableFrom(type)) { + return type.cast(Boolean.parseBoolean(value)); + } + return type.cast(value); + } + + /** + * Reads JAXP system property in this order: system property, + * $java.home/conf/jaxp.properties if the system property is not specified + * + * @param the type of the property value + * @param type the type of the property value + * @param propName the name of the property + * @param defValue the default value + * @return the value of the property, or the default value if no system * property is found */ public static T getJAXPSystemProperty(Class type, String propName, String defValue) { @@ -136,7 +177,7 @@ public class SecuritySupport { String configFile = getSystemProperty("java.home") + File.separator + "conf" + File.separator + "jaxp.properties"; File f = new File(configFile); - if (getFileExists(f)) { + if (isFileExists(f)) { is = getFileInputStream(f); cacheProps.load(is); } @@ -158,13 +199,28 @@ public class SecuritySupport { return value; } -//------------------- private methods --------------------------- - static boolean getFileExists(final File f) { + /** + * Tests whether the file denoted by this abstract pathname is a directory. + * @param f the file to be tested + * @return true if it is a directory, false otherwise + */ + public static boolean isDirectory(final File f) { return (AccessController.doPrivileged((PrivilegedAction) () - -> f.exists() ? Boolean.TRUE : Boolean.FALSE)); + -> f.isDirectory())); } - static FileInputStream getFileInputStream(final File file) + /** + * Tests whether the file exists. + * + * @param f the file to be tested + * @return true if the file exists, false otherwise + */ + public static boolean isFileExists(final File f) { + return (AccessController.doPrivileged((PrivilegedAction) () + -> f.exists())); + } + + public static FileInputStream getFileInputStream(final File file) throws FileNotFoundException { try { return AccessController.doPrivileged((PrivilegedExceptionAction) () @@ -173,4 +229,34 @@ public class SecuritySupport { throw (FileNotFoundException) e.getException(); } } + + /** + * Gets a resource bundle using the specified base name, the default locale, and the caller's class loader. + * @param bundle the base name of the resource bundle, a fully qualified class name + * @return a resource bundle for the given base name and the default locale + */ + public static ResourceBundle getResourceBundle(String bundle) { + return getResourceBundle(bundle, Locale.getDefault()); + } + + /** + * Gets a resource bundle using the specified base name and locale, and the caller's class loader. + * @param bundle the base name of the resource bundle, a fully qualified class name + * @param locale the locale for which a resource bundle is desired + * @return a resource bundle for the given base name and locale + */ + public static ResourceBundle getResourceBundle(final String bundle, final Locale locale) { + return AccessController.doPrivileged((PrivilegedAction) () -> { + try { + return ResourceBundle.getBundle(bundle, locale); + } catch (MissingResourceException e) { + try { + return ResourceBundle.getBundle(bundle, new Locale("en", "US")); + } catch (MissingResourceException e2) { + throw new MissingResourceException( + "Could not load any resource bundle by " + bundle, bundle, ""); + } + } + }); + } } diff --git a/jaxp/src/java.xml/share/legal/bcel.md b/jaxp/src/java.xml/share/legal/bcel.md index 8c6a3cf0e40..bb434b09d2c 100644 --- a/jaxp/src/java.xml/share/legal/bcel.md +++ b/jaxp/src/java.xml/share/legal/bcel.md @@ -1,12 +1,12 @@ -## Apache Byte Code Engineering Library (BCEL) v5.2 +## Apache Commons Byte Code Engineering Library (BCEL) Version 6.0 -### Apache BCEL Notice +### Apache Commons BCEL Notice
     
         =========================================================================
         ==  NOTICE file corresponding to the section 4 d of                    ==
         ==  the Apache License, Version 2.0,                                   ==
    -    ==  in this case for the Apache Jakarta-BCEL distribution.             ==
    +    ==  in this case for the Apache Commons BCEL distribution.             ==
         =========================================================================
     
        This product includes software developed by
    
    From 0f6e2890e736595f0eba1a3ea53b5afc92e78064 Mon Sep 17 00:00:00 2001
    From: Jonathan Gibbons 
    Date: Mon, 14 Aug 2017 13:54:10 -0700
    Subject: [PATCH 33/42] 8186156: Fix a11y and HTML issues in java.net and
     javax.net packages
    
    Reviewed-by: lancea, mchung
    ---
     .../share/classes/java/net/InetAddress.java   | 15 +++---
     .../java.base/share/classes/java/net/URI.java | 51 ++++++++++---------
     .../share/classes/java/net/URLConnection.java | 25 ++-------
     .../share/classes/java/net/URLPermission.java | 41 +++++++--------
     .../java/net/doc-files/net-properties.html    |  4 +-
     .../classes/javax/net/ssl/SSLEngine.java      |  4 +-
     .../classes/javax/net/ssl/SSLParameters.java  |  2 +-
     .../classes/javax/net/ssl/SSLSocket.java      |  4 +-
     8 files changed, 68 insertions(+), 78 deletions(-)
    
    diff --git a/jdk/src/java.base/share/classes/java/net/InetAddress.java b/jdk/src/java.base/share/classes/java/net/InetAddress.java
    index 95b38875d9c..d4815f486df 100644
    --- a/jdk/src/java.base/share/classes/java/net/InetAddress.java
    +++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java
    @@ -72,10 +72,13 @@ import sun.net.util.IPAddressUtil;
      *
      * 

    Address types

    * - *
    + *
    * + * + * + * * - * + * * - * + * * * - *
    Description of unicast and multicast address types
    Address TypeDescription
    unicast
    unicastAn identifier for a single interface. A packet sent to * a unicast address is delivered to the interface identified by * that address. @@ -94,12 +97,12 @@ import sun.net.util.IPAddressUtil; * IP address loops around and becomes IP input on the local * host. This address is often used when testing a * client.
    multicast
    multicastAn identifier for a set of interfaces (typically belonging * to different nodes). A packet sent to a multicast address is * delivered to all interfaces identified by that address.
    + * * *

    IP address scope

    * @@ -163,8 +166,7 @@ import sun.net.util.IPAddressUtil; *

    Two Java security properties control the TTL values used for * positive and negative host name resolution caching: * - *

    - *
    + *
    *
    networkaddress.cache.ttl
    *
    Indicates the caching policy for successful name lookups from * the name service. The value is specified as an integer to indicate @@ -183,7 +185,6 @@ import sun.net.util.IPAddressUtil; * A value of -1 indicates "cache forever". *
    *
    - *
    * * @author Chris Warth * @see java.net.InetAddress#getByAddress(byte[]) diff --git a/jdk/src/java.base/share/classes/java/net/URI.java b/jdk/src/java.base/share/classes/java/net/URI.java index eab652cbbf5..5199a3dd2bb 100644 --- a/jdk/src/java.base/share/classes/java/net/URI.java +++ b/jdk/src/java.base/share/classes/java/net/URI.java @@ -132,23 +132,23 @@ import java.lang.NullPointerException; // for javadoc * *

    All told, then, a URI instance has the following nine components: * - *

    + *
    * * - * + * * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * * - *
    Describes the components of a URI:scheme,scheme-specific-part,authority,user-info,host,port,path,query,fragment
    ComponentType
    ComponentType
    scheme{@code String}
    scheme-specific-part    {@code String}
    authority{@code String}
    user-info{@code String}
    host{@code String}
    port{@code int}
    path{@code String}
    query{@code String}
    fragment{@code String}
    scheme{@code String}
    scheme-specific-part{@code String}
    authority{@code String}
    user-info{@code String}
    host{@code String}
    port{@code int}
    path{@code String}
    query{@code String}
    fragment{@code String}
    + * * * In a given instance any particular component is either undefined or * defined with a distinct value. Undefined string components are @@ -253,32 +253,35 @@ import java.lang.NullPointerException; // for javadoc * which are taken from that specification, are used below to describe these * constraints: * - *
    + *
    * - * - * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * * - *
    Describes categories alpha,digit,alphanum,unreserved,punct,reserved,escaped,and other
    alpha
    CategoryDescription
    alphaThe US-ASCII alphabetic characters, * {@code 'A'} through {@code 'Z'} * and {@code 'a'} through {@code 'z'}
    digit
    digitThe US-ASCII decimal digit characters, * {@code '0'} through {@code '9'}
    alphanum
    alphanumAll alpha and digit characters
    unreserved    
    unreservedAll alphanum characters together with those in the string * {@code "_-!.~'()*"}
    punct
    punctThe characters in the string {@code ",;:$&+="}
    reserved
    reservedAll punct characters together with those in the string * {@code "?/[]@"}
    escaped
    escapedEscaped octets, that is, triplets consisting of the percent * character ({@code '%'}) followed by two hexadecimal digits * ({@code '0'}-{@code '9'}, {@code 'A'}-{@code 'F'}, and * {@code 'a'}-{@code 'f'})
    other
    otherThe Unicode characters that are not in the US-ASCII character set, * are not control characters (according to the {@link * java.lang.Character#isISOControl(char) Character.isISOControl} @@ -287,7 +290,7 @@ import java.lang.NullPointerException; // for javadoc * method)  (Deviation from RFC 2396, which is * limited to US-ASCII)
    + * * *

    The set of all legal URI characters consists of * the unreserved, reserved, escaped, and other diff --git a/jdk/src/java.base/share/classes/java/net/URLConnection.java b/jdk/src/java.base/share/classes/java/net/URLConnection.java index e54a0b1a126..a5c30df3d4b 100644 --- a/jdk/src/java.base/share/classes/java/net/URLConnection.java +++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java @@ -51,31 +51,16 @@ import sun.security.action.GetPropertyAction; * The abstract class {@code URLConnection} is the superclass * of all classes that represent a communications link between the * application and a URL. Instances of this class can be used both to - * read from and to write to the resource referenced by the URL. In - * general, creating a connection to a URL is a multistep process: - * - *

    - * - * - * - * - * - * - * - * - * - *
    Describes the process of creating a connection to a URL: openConnection() and connect() over time.
    {@code openConnection()}{@code connect()}
    Manipulate parameters that affect the connection to the remote - * resource.Interact with the resource; query header fields and - * contents.
    - * ----------------------------> - *
    time
    + * read from and to write to the resource referenced by the URL. * + *

    + * In general, creating a connection to a URL is a multistep process: *

      *
    1. The connection object is created by invoking the - * {@code openConnection} method on a URL. + * {@link URL#openConnection() openConnection} method on a URL. *
    2. The setup parameters and general request properties are manipulated. *
    3. The actual connection to the remote object is made, using the - * {@code connect} method. + * {@link #connect() connect} method. *
    4. The remote object becomes available. The header fields and the contents * of the remote object can be accessed. *
    diff --git a/jdk/src/java.base/share/classes/java/net/URLPermission.java b/jdk/src/java.base/share/classes/java/net/URLPermission.java index 43a8bd43066..31441749659 100644 --- a/jdk/src/java.base/share/classes/java/net/URLPermission.java +++ b/jdk/src/java.base/share/classes/java/net/URLPermission.java @@ -72,22 +72,22 @@ import java.security.Permission; * separated by '/' characters. path may also be empty. The path is specified * in a similar way to the path in {@link java.io.FilePermission}. There are * three different ways as the following examples show: - * + *
    * * - * + * * - * - * + * + * * * - * + * * * - * + * *
    URL Examples
    Example urlDescription
    Example urlDescription
    http://www.oracle.com/a/b/c.html
    http://www.oracle.com/a/b/c.htmlA url which identifies a specific (single) resource
    http://www.oracle.com/a/b/*
    http://www.oracle.com/a/b/*The '*' character refers to all resources in the same "directory" - in * other words all resources with the same number of path components, and * which only differ in the final path component, represented by the '*'. *
    http://www.oracle.com/a/b/-
    http://www.oracle.com/a/b/-The '-' character refers to all resources recursively below the * preceding path (eg. http://www.oracle.com/a/b/c/d/e.html matches this * example). @@ -114,11 +114,12 @@ import java.security.Permission; * methods and permitted request headers of the permission (respectively). The two lists * are separated by a colon ':' character and elements of each list are comma separated. * Some examples are: - *
    - *         "POST,GET,DELETE"
    - *         "GET:X-Foo-Request,X-Bar-Request"
    - *         "POST,GET:Header1,Header2"
    - * 
    + *
      + *
    • "POST,GET,DELETE" + *
    • "GET:X-Foo-Request,X-Bar-Request" + *
    • "POST,GET:Header1,Header2" + *
    + *

    * The first example specifies the methods: POST, GET and DELETE, but no request headers. * The second example specifies one request method and two headers. The third * example specifies two request methods, and two headers. @@ -253,16 +254,16 @@ public final class URLPermission extends Permission { * * * - * + * * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * * *
    Examples of Path Matching
    this's pathp's pathmatch
    this's pathp's pathmatch
    /a/b/a/byes
    /a/b/*/a/b/cyes
    /a/b/*/a/b/c/dno
    /a/b/-/a/b/c/dyes
    /a/b/-/a/b/c/d/eyes
    /a/b/-/a/b/c/*yes
    /a/b/*/a/b/c/-no
    /a/b/a/byes
    /a/b/*/a/b/cyes
    /a/b/c/dno
    /a/b/c/-no
    /a/b/-/a/b/c/dyes
    /a/b/c/d/eyes
    /a/b/c/*yes
    */ diff --git a/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html b/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html index 003749ba7f2..acf653ebaed 100644 --- a/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html +++ b/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html @@ -23,7 +23,7 @@ or visit www.oracle.com if you need additional information or have any questions. --> - + Networking Properties @@ -35,7 +35,7 @@ alter the mechanisms and behavior of the various classes of the java.net package. Some are checked only once at startup of the VM, and therefore are best set using the -D option of the java command, while others have a more dynamic nature and can also be changed using -the System.setProperty() API. +the System.setProperty() API. The purpose of this document is to list and detail all of these properties.

    If there is no special note, a property value is checked every time it is used.

    diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java index b765128cd85..3eec4282ba6 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java @@ -1292,7 +1292,7 @@ public abstract class SSLEngine { * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 , the * Application-Layer Protocol Negotiation (ALPN), can negotiate * application-level values between peers. - *

    + * * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. @@ -1317,7 +1317,7 @@ public abstract class SSLEngine { * Like {@link #getHandshakeSession()}, * a connection may be in the middle of a handshake. The * application protocol may or may not yet be available. - *

    + * * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java index 19b05f9de8a..1c3c947035e 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java @@ -646,7 +646,7 @@ public class SSLParameters { * requested by the peer, the underlying protocol will determine what * action to take. (For example, ALPN will send a * {@code "no_application_protocol"} alert and terminate the connection.) - *

    + * * @implSpec * This method will make a copy of the {@code protocols} array. * diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java index 6f8e20d9538..ccaea95b167 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java @@ -702,7 +702,7 @@ public abstract class SSLSocket extends Socket * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 , the * Application-Layer Protocol Negotiation (ALPN), can negotiate * application-level values between peers. - *

    + * * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. @@ -727,7 +727,7 @@ public abstract class SSLSocket extends Socket * Like {@link #getHandshakeSession()}, * a connection may be in the middle of a handshake. The * application protocol may or may not yet be available. - *

    + * * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. From b6f3d9355790197c9edbcc1828c7903ec02f2925 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 14 Aug 2017 13:57:15 -0700 Subject: [PATCH 34/42] 8186160: Fix a11y issues in java.security package Reviewed-by: wetmore --- .../classes/java/security/DrbgParameters.java | 14 +++++----- .../share/classes/java/security/Provider.java | 14 +++++----- .../java/security/cert/X509Extension.java | 28 +++++++++---------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/security/DrbgParameters.java b/jdk/src/java.base/share/classes/java/security/DrbgParameters.java index 05723baa916..4dba498faf1 100644 --- a/jdk/src/java.base/share/classes/java/security/DrbgParameters.java +++ b/jdk/src/java.base/share/classes/java/security/DrbgParameters.java @@ -263,18 +263,18 @@ public class DrbgParameters { * Capability effective = ((DrbgParametes.Initiate) s.getParameters()) * .getCapability(); * - * + *
    * * * - * - * + * + * * * - * - * - * - * + * + * + * + * * *
    requested and effective capabilities
    Requested ValuePossible Effective ValuesRequested ValuePossible Effective Values
    NONENONE, RESEED_ONLY, PR_AND_RESEED
    RESEED_ONLYRESEED_ONLY, PR_AND_RESEED
    PR_AND_RESEEDPR_AND_RESEED
    NONENONE, RESEED_ONLY, PR_AND_RESEED
    RESEED_ONLYRESEED_ONLY, PR_AND_RESEED
    PR_AND_RESEEDPR_AND_RESEED
    *

    diff --git a/jdk/src/java.base/share/classes/java/security/Provider.java b/jdk/src/java.base/share/classes/java/security/Provider.java index cf20bfec3ac..83ce4ff9aa2 100644 --- a/jdk/src/java.base/share/classes/java/security/Provider.java +++ b/jdk/src/java.base/share/classes/java/security/Provider.java @@ -61,19 +61,19 @@ import java.util.function.Function; * security framework. Services of this type cannot be added, removed, * or modified by applications. * The following attributes are automatically placed in each Provider object: - * + *
    * * - * + * * - * - * + * + * * - * + * * - * + * * - * + * * * *
    Attributes Automatically Placed in a Provider Object
    NameValue
    NameValue
    {@code Provider.id name}
    {@code Provider.id name}{@code String.valueOf(provider.getName())}
    {@code Provider.id version}
    {@code Provider.id version}{@code String.valueOf(provider.getVersionStr())}
    {@code Provider.id info}
    {@code Provider.id info}{@code String.valueOf(provider.getInfo())}
    {@code Provider.id className}
    {@code Provider.id className}{@code provider.getClass().getName()}
    diff --git a/jdk/src/java.base/share/classes/java/security/cert/X509Extension.java b/jdk/src/java.base/share/classes/java/security/cert/X509Extension.java index b7533a2c697..b8aa25fb9ca 100644 --- a/jdk/src/java.base/share/classes/java/security/cert/X509Extension.java +++ b/jdk/src/java.base/share/classes/java/security/cert/X509Extension.java @@ -153,33 +153,33 @@ public interface X509Extension { * by periods. * *

    For example:
    - * + *
    * * * - * - * + * + * * - * - * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * * *
    Examples of OIDs and extension names
    OID (Object Identifier)Extension Name
    OID (Object Identifier)Extension Name
    2.5.29.14
    2.5.29.14SubjectKeyIdentifier
    2.5.29.15
    2.5.29.15KeyUsage
    2.5.29.16
    2.5.29.16PrivateKeyUsage
    2.5.29.17
    2.5.29.17SubjectAlternativeName
    2.5.29.18
    2.5.29.18IssuerAlternativeName
    2.5.29.19
    2.5.29.19BasicConstraints
    2.5.29.30
    2.5.29.30NameConstraints
    2.5.29.33
    2.5.29.33PolicyMappings
    2.5.29.35
    2.5.29.35AuthorityKeyIdentifier
    2.5.29.36
    2.5.29.36PolicyConstraints
    From 925357af091b9df9740e6dac2235b975cc1e6353 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 14 Aug 2017 17:19:31 -0700 Subject: [PATCH 35/42] 8184940: JDK 9 rejects zip files where the modified day or month is 0 Reviewed-by: martin --- .../share/classes/java/util/zip/ZipUtils.java | 25 +++- .../share/classes/jdk/nio/zipfs/ZipUtils.java | 25 +++- jdk/test/java/util/zip/ZipFile/ZeroDate.java | 112 ++++++++++++++++ jdk/test/jdk/nio/zipfs/ZeroDate.java | 120 ++++++++++++++++++ 4 files changed, 268 insertions(+), 14 deletions(-) create mode 100644 jdk/test/java/util/zip/ZipFile/ZeroDate.java create mode 100644 jdk/test/jdk/nio/zipfs/ZeroDate.java diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java index 8c682a813b6..e618ef18a78 100644 --- a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java @@ -81,13 +81,24 @@ class ZipUtils { * Converts DOS time to Java time (number of milliseconds since epoch). */ public static long dosToJavaTime(long dtime) { - LocalDateTime ldt = LocalDateTime.of( - (int) (((dtime >> 25) & 0x7f) + 1980), - (int) ((dtime >> 21) & 0x0f), - (int) ((dtime >> 16) & 0x1f), - (int) ((dtime >> 11) & 0x1f), - (int) ((dtime >> 5) & 0x3f), - (int) ((dtime << 1) & 0x3e)); + int year; + int month; + int day; + int hour = (int) ((dtime >> 11) & 0x1f); + int minute = (int) ((dtime >> 5) & 0x3f); + int second = (int) ((dtime << 1) & 0x3e); + if ((dtime >> 16) == 0) { + // Interpret the 0 DOS date as 1979-11-30 for compatibility with + // other implementations. + year = 1979; + month = 11; + day = 30; + } else { + year = (int) (((dtime >> 25) & 0x7f) + 1980); + month = (int) ((dtime >> 21) & 0x0f); + day = (int) ((dtime >> 16) & 0x1f); + } + LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second); return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond( ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS); } diff --git a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java index b87a63d87cb..3c45090dbe2 100644 --- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java +++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java @@ -106,13 +106,24 @@ class ZipUtils { * Converts DOS time to Java time (number of milliseconds since epoch). */ public static long dosToJavaTime(long dtime) { - LocalDateTime ldt = LocalDateTime.of( - (int) (((dtime >> 25) & 0x7f) + 1980), - (int) ((dtime >> 21) & 0x0f), - (int) ((dtime >> 16) & 0x1f), - (int) ((dtime >> 11) & 0x1f), - (int) ((dtime >> 5) & 0x3f), - (int) ((dtime << 1) & 0x3e)); + int year; + int month; + int day; + int hour = (int) ((dtime >> 11) & 0x1f); + int minute = (int) ((dtime >> 5) & 0x3f); + int second = (int) ((dtime << 1) & 0x3e); + if ((dtime >> 16) == 0) { + // Interpret the 0 DOS date as 1979-11-30 for compatibility with + // other implementations. + year = 1979; + month = 11; + day = 30; + } else { + year = (int) (((dtime >> 25) & 0x7f) + 1980); + month = (int) ((dtime >> 21) & 0x0f); + day = (int) ((dtime >> 16) & 0x1f); + } + LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second); return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond( ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS); } diff --git a/jdk/test/java/util/zip/ZipFile/ZeroDate.java b/jdk/test/java/util/zip/ZipFile/ZeroDate.java new file mode 100644 index 00000000000..aef545002e0 --- /dev/null +++ b/jdk/test/java/util/zip/ZipFile/ZeroDate.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.util.zip.ZipFile.CENOFF; +import static java.util.zip.ZipFile.CENTIM; +import static java.util.zip.ZipFile.ENDHDR; +import static java.util.zip.ZipFile.ENDOFF; +import static java.util.zip.ZipFile.LOCTIM; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +/* @test + * @bug 8184940 + * @summary JDK 9 rejects zip files where the modified day or month is 0 + * @author Liam Miller-Cushon + */ +public class ZeroDate { + + public static void main(String[] args) throws Exception { + // create a zip file, and read it in as a byte array + Path path = Files.createTempFile("bad", ".zip"); + try (OutputStream os = Files.newOutputStream(path); + ZipOutputStream zos = new ZipOutputStream(os)) { + ZipEntry e = new ZipEntry("x"); + zos.putNextEntry(e); + zos.write((int) 'x'); + } + int len = (int) Files.size(path); + byte[] data = new byte[len]; + try (InputStream is = Files.newInputStream(path)) { + is.read(data); + } + Files.delete(path); + + // year, month, day are zero + testDate(data.clone(), 0, LocalDate.of(1979, 11, 30)); + // only year is zero + testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5)); + } + + private static void testDate(byte[] data, int date, LocalDate expected) throws IOException { + // set the datetime + int endpos = data.length - ENDHDR; + int cenpos = u16(data, endpos + ENDOFF); + int locpos = u16(data, cenpos + CENOFF); + writeU32(data, cenpos + CENTIM, date); + writeU32(data, locpos + LOCTIM, date); + + // ensure that the archive is still readable, and the date is 1979-11-30 + Path path = Files.createTempFile("out", ".zip"); + try (OutputStream os = Files.newOutputStream(path)) { + os.write(data); + } + try (ZipFile zf = new ZipFile(path.toFile())) { + ZipEntry ze = zf.entries().nextElement(); + Instant actualInstant = ze.getLastModifiedTime().toInstant(); + Instant expectedInstant = + expected.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant(); + if (!actualInstant.equals(expectedInstant)) { + throw new AssertionError( + String.format("actual: %s, expected: %s", actualInstant, expectedInstant)); + } + } finally { + Files.delete(path); + } + } + + static int u8(byte[] data, int offset) { + return data[offset] & 0xff; + } + + static int u16(byte[] data, int offset) { + return u8(data, offset) + (u8(data, offset + 1) << 8); + } + + private static void writeU32(byte[] data, int pos, int value) { + data[pos] = (byte) (value & 0xff); + data[pos + 1] = (byte) ((value >> 8) & 0xff); + data[pos + 2] = (byte) ((value >> 16) & 0xff); + data[pos + 3] = (byte) ((value >> 24) & 0xff); + } +} diff --git a/jdk/test/jdk/nio/zipfs/ZeroDate.java b/jdk/test/jdk/nio/zipfs/ZeroDate.java new file mode 100644 index 00000000000..1a65c9b39b6 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/ZeroDate.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.util.zip.ZipFile.CENOFF; +import static java.util.zip.ZipFile.CENTIM; +import static java.util.zip.ZipFile.ENDHDR; +import static java.util.zip.ZipFile.ENDOFF; +import static java.util.zip.ZipFile.LOCTIM; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Collections; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/* @test + * @bug 8184940 + * @summary JDK 9 rejects zip files where the modified day or month is 0 + * @author Liam Miller-Cushon + */ +public class ZeroDate { + + public static void main(String[] args) throws Exception { + // create a zip file, and read it in as a byte array + Path path = Files.createTempFile("bad", ".zip"); + try (OutputStream os = Files.newOutputStream(path); + ZipOutputStream zos = new ZipOutputStream(os)) { + ZipEntry e = new ZipEntry("x"); + zos.putNextEntry(e); + zos.write((int) 'x'); + } + int len = (int) Files.size(path); + byte[] data = new byte[len]; + try (InputStream is = Files.newInputStream(path)) { + is.read(data); + } + Files.delete(path); + + // year, month, day are zero + testDate(data.clone(), 0, LocalDate.of(1979, 11, 30)); + // only year is zero + testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5)); + } + + private static void testDate(byte[] data, int date, LocalDate expected) throws IOException { + // set the datetime + int endpos = data.length - ENDHDR; + int cenpos = u16(data, endpos + ENDOFF); + int locpos = u16(data, cenpos + CENOFF); + writeU32(data, cenpos + CENTIM, date); + writeU32(data, locpos + LOCTIM, date); + + // ensure that the archive is still readable, and the date is 1979-11-30 + Path path = Files.createTempFile("out", ".zip"); + try (OutputStream os = Files.newOutputStream(path)) { + os.write(data); + } + URI uri = URI.create("jar:file://" + path.toAbsolutePath()); + try (FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) { + Path entry = fs.getPath("x"); + Instant actualInstant = + Files.readAttributes(entry, BasicFileAttributes.class) + .lastModifiedTime() + .toInstant(); + Instant expectedInstant = + expected.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant(); + if (!actualInstant.equals(expectedInstant)) { + throw new AssertionError( + String.format("actual: %s, expected: %s", actualInstant, expectedInstant)); + } + } finally { + Files.delete(path); + } + } + + static int u8(byte[] data, int offset) { + return data[offset] & 0xff; + } + + static int u16(byte[] data, int offset) { + return u8(data, offset) + (u8(data, offset + 1) << 8); + } + + private static void writeU32(byte[] data, int pos, int value) { + data[pos] = (byte) (value & 0xff); + data[pos + 1] = (byte) ((value >> 8) & 0xff); + data[pos + 2] = (byte) ((value >> 16) & 0xff); + data[pos + 3] = (byte) ((value >> 24) & 0xff); + } +} From f413915e196bb834016724f63937d2119afa7a9a Mon Sep 17 00:00:00 2001 From: John Jiang Date: Mon, 14 Aug 2017 21:24:45 -0700 Subject: [PATCH 36/42] 8185620: MSCAPI test leaves too many entries in keystore Deletes the added entries before exiting Reviewed-by: vinnie --- .../sun/security/mscapi/SmallPrimeExponentP.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/jdk/test/sun/security/mscapi/SmallPrimeExponentP.java b/jdk/test/sun/security/mscapi/SmallPrimeExponentP.java index 38d37966f23..535d32d5310 100644 --- a/jdk/test/sun/security/mscapi/SmallPrimeExponentP.java +++ b/jdk/test/sun/security/mscapi/SmallPrimeExponentP.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,9 @@ public class SmallPrimeExponentP { CertAndKeyGen ckg = new CertAndKeyGen("RSA", "SHA1withRSA"); ckg.setRandom(new MySecureRandom(seed)); + String alias = "anything"; + int count = 0; + boolean see63 = false; boolean see65 = false; while (!see63 || !see65) { @@ -78,12 +81,19 @@ public class SmallPrimeExponentP { see65 = true; } } - ks.setKeyEntry("anything", k, null, new X509Certificate[]{ + ks.setKeyEntry(alias, k, null, new X509Certificate[]{ ckg.getSelfCertificate(new X500Name("CN=Me"), 1000) }); + count++; } } - ks.store(null, null); + + // Because of JDK-8185844, it has to reload the key store after + // deleting an entry. + for (int i = 0; i < count; i++) { + ks.deleteEntry(alias); + ks.load(null, null); + } } static class MySecureRandom extends SecureRandom { From 55fe55c4ff83fb65ac59628b017ae6acd913611f Mon Sep 17 00:00:00 2001 From: John Jiang Date: Tue, 15 Aug 2017 19:19:50 -0700 Subject: [PATCH 37/42] 8179614: Test for jarsigner on verifying jars that are signed and timestamped by other JDK releases A test on checking the compatibility on jarsigner cross different JDK releases Reviewed-by: mullan --- .../compatibility/Compatibility.java | 1183 +++++++++++++++++ .../compatibility/DetailsOutputStream.java | 79 ++ .../jarsigner/compatibility/HtmlHelper.java | 102 ++ .../jarsigner/compatibility/JdkUtils.java | 61 + .../compatibility/PhaseOutputStream.java | 162 +++ .../tools/jarsigner/compatibility/README | 215 +++ .../jarsigner/compatibility/java.security | 2 + 7 files changed, 1804 insertions(+) create mode 100644 jdk/test/sun/security/tools/jarsigner/compatibility/Compatibility.java create mode 100644 jdk/test/sun/security/tools/jarsigner/compatibility/DetailsOutputStream.java create mode 100644 jdk/test/sun/security/tools/jarsigner/compatibility/HtmlHelper.java create mode 100644 jdk/test/sun/security/tools/jarsigner/compatibility/JdkUtils.java create mode 100644 jdk/test/sun/security/tools/jarsigner/compatibility/PhaseOutputStream.java create mode 100644 jdk/test/sun/security/tools/jarsigner/compatibility/README create mode 100644 jdk/test/sun/security/tools/jarsigner/compatibility/java.security diff --git a/jdk/test/sun/security/tools/jarsigner/compatibility/Compatibility.java b/jdk/test/sun/security/tools/jarsigner/compatibility/Compatibility.java new file mode 100644 index 00000000000..a285a0257c5 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/compatibility/Compatibility.java @@ -0,0 +1,1183 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary This test is used to verify the compatibility on jarsigner cross + * different JDK releases. It also can be used to check jar signing (w/ + * and w/o TSA) and verifying on some specific key algorithms and digest + * algorithms. + * Note that, this is a manual test. For more details about the test and + * its usages, please look through README. + * + * @modules java.base/sun.security.pkcs + * java.base/sun.security.timestamp + * java.base/sun.security.tools.keytool + * java.base/sun.security.util + * java.base/sun.security.x509 + * @library /test/lib /lib/testlibrary ../warnings + * @compile -source 1.6 -target 1.6 JdkUtils.java + * @run main/manual/othervm Compatibility + */ + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.JarUtils; + +public class Compatibility { + + private static final String TEST_JAR_NAME = "test.jar"; + + private static final String TEST_SRC = System.getProperty("test.src"); + private static final String TEST_CLASSES = System.getProperty("test.classes"); + private static final String TEST_JDK = System.getProperty("test.jdk"); + private static final String TEST_JARSIGNER = jarsignerPath(TEST_JDK); + + private static final String PROXY_HOST = System.getProperty("proxyHost"); + private static final String PROXY_PORT = System.getProperty("proxyPort", "80"); + + // An alternative security properties file. + // The test provides a default one, which only contains two lines: + // jdk.certpath.disabledAlgorithms=MD2, MD5 + // jdk.jar.disabledAlgorithms=MD2, MD5 + private static final String JAVA_SECURITY = System.getProperty( + "javaSecurityFile", TEST_SRC + "/java.security"); + + private static final String PASSWORD = "testpass"; + private static final String KEYSTORE = "testKeystore"; + + private static final String RSA = "RSA"; + private static final String DSA = "DSA"; + private static final String EC = "EC"; + private static final String[] KEY_ALGORITHMS = new String[] { + RSA, + DSA, + EC}; + + private static final String SHA1 = "SHA-1"; + private static final String SHA256 = "SHA-256"; + private static final String SHA512 = "SHA-512"; + private static final String DEFAULT = "DEFAULT"; + private static final String[] DIGEST_ALGORITHMS = new String[] { + SHA1, + SHA256, + SHA512, + DEFAULT}; + + private static final boolean[] EXPIRED = new boolean[] { + false, + true}; + + private static final Calendar CALENDAR = Calendar.getInstance(); + private static final DateFormat DATE_FORMAT + = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + + // The certificate validity period in minutes. The default value is 1440 + // minutes, namely 1 day. + private static final int CERT_VALIDITY + = Integer.valueOf(System.getProperty("certValidity", "1440")); + static { + if (CERT_VALIDITY < 1 || CERT_VALIDITY > 1440) { + throw new RuntimeException( + "certValidity if out of range [1, 1440]: " + CERT_VALIDITY); + } + } + + // If true, an additional verifying will be triggered after all of + // valid certificates expire. The default value is false. + public static final boolean DELAY_VERIFY + = Boolean.valueOf(System.getProperty("delayVerify", "false")); + + private static long lastCertStartTime; + + private static DetailsOutputStream detailsOutput; + + public static void main(String[] args) throws Throwable { + // Backups stdout and stderr. + PrintStream origStdOut = System.out; + PrintStream origStdErr = System.err; + + detailsOutput = new DetailsOutputStream(); + + // Redirects the system output to a custom one. + PrintStream printStream = new PrintStream(detailsOutput); + System.setOut(printStream); + System.setErr(printStream); + + List tsaList = tsaInfoList(); + if (tsaList.size() == 0) { + throw new RuntimeException("TSA service is mandatory."); + } + + List jdkInfoList = jdkInfoList(); + List certList = createCertificates(jdkInfoList); + createJar(); + List signItems = test(jdkInfoList, tsaList, certList); + + boolean failed = generateReport(tsaList, signItems); + + // Restores the original stdout and stderr. + System.setOut(origStdOut); + System.setErr(origStdErr); + + if (failed) { + throw new RuntimeException("At least one test case failed. " + + "Please check the failed row(s) in report.html " + + "or failedReport.html."); + } + } + + // Creates a jar file that contains an empty file. + private static void createJar() throws IOException { + String testFile = "test"; + new File(testFile).createNewFile(); + JarUtils.createJar(TEST_JAR_NAME, testFile); + } + + // Creates a key store that includes a set of valid/expired certificates + // with various algorithms. + private static List createCertificates(List jdkInfoList) + throws Throwable { + List certList = new ArrayList(); + Set expiredCertFilter = new HashSet(); + + for(JdkInfo jdkInfo : jdkInfoList) { + for(String keyAlgorithm : KEY_ALGORITHMS) { + for(String digestAlgorithm : DIGEST_ALGORITHMS) { + for(int keySize : keySizes(keyAlgorithm)) { + for(boolean expired : EXPIRED) { + // It creates only one expired certificate for one + // key algorithm. + if (expired + && !expiredCertFilter.add(keyAlgorithm)) { + continue; + } + + CertInfo certInfo = new CertInfo( + jdkInfo.version, + keyAlgorithm, + digestAlgorithm, + keySize, + expired); + if (!certList.contains(certInfo)) { + String alias = createCertificate( + jdkInfo.jdkPath, certInfo); + if (alias != null) { + certList.add(certInfo); + } + } + } + } + } + } + } + + return certList; + } + + // Creates/Updates a key store that adds a certificate with specific algorithm. + private static String createCertificate(String jdkPath, CertInfo certInfo) + throws Throwable { + String alias = certInfo.alias(); + + List arguments = new ArrayList(); + arguments.add("-J-Djava.security.properties=" + JAVA_SECURITY); + arguments.add("-v"); + arguments.add("-storetype"); + arguments.add("jks"); + arguments.add("-genkey"); + arguments.add("-keyalg"); + arguments.add(certInfo.keyAlgorithm); + String sigalg = sigalg(certInfo.digestAlgorithm, certInfo.keyAlgorithm); + if (sigalg != null) { + arguments.add("-sigalg"); + arguments.add(sigalg); + } + if (certInfo.keySize != 0) { + arguments.add("-keysize"); + arguments.add(certInfo.keySize + ""); + } + arguments.add("-dname"); + arguments.add("CN=Test"); + arguments.add("-alias"); + arguments.add(alias); + arguments.add("-keypass"); + arguments.add(PASSWORD); + arguments.add("-storepass"); + arguments.add(PASSWORD); + + arguments.add("-startdate"); + arguments.add(startDate(certInfo.expired)); + arguments.add("-validity"); + arguments.add("1"); + arguments.add("-keystore"); + arguments.add(KEYSTORE); + + OutputAnalyzer outputAnalyzer = execTool( + jdkPath + "/bin/keytool", + arguments.toArray(new String[arguments.size()])); + if (outputAnalyzer.getExitValue() == 0 + && !outputAnalyzer.getOutput().matches("[Ee]xception")) { + return alias; + } else { + return null; + } + } + + private static String sigalg(String digestAlgorithm, String keyAlgorithm) { + if (digestAlgorithm == DEFAULT) { + return null; + } + + String keyName = keyAlgorithm == EC ? "ECDSA" : keyAlgorithm; + return digestAlgorithm.replace("-", "") + "with" + keyName; + } + + // The validity period of a certificate always be 1 day. For creating an + // expired certificate, the start date is the time before 1 day, then the + // certificate expires immediately. And for creating a valid certificate, + // the start date is the time before (1 day - CERT_VALIDITY minutes), then + // the certificate will expires in CERT_VALIDITY minutes. + private static String startDate(boolean expiredCert) { + CALENDAR.setTime(new Date()); + CALENDAR.add(Calendar.DAY_OF_MONTH, -1); + if (!expiredCert) { + CALENDAR.add(Calendar.MINUTE, CERT_VALIDITY); + } + Date startDate = CALENDAR.getTime(); + lastCertStartTime = startDate.getTime(); + return DATE_FORMAT.format(startDate); + } + + // Retrieves JDK info from the file which is specified by property jdkListFile, + // or from property jdkList if jdkListFile is not available. + private static List jdkInfoList() throws Throwable { + String[] jdkList = list("jdkList"); + if (jdkList.length == 0) { + jdkList = new String[] { TEST_JDK }; + } + + List jdkInfoList = new ArrayList(); + for (String jdkPath : jdkList) { + JdkInfo jdkInfo = new JdkInfo(jdkPath); + // The JDK version must be unique. + if (!jdkInfoList.contains(jdkInfo)) { + jdkInfoList.add(jdkInfo); + } else { + System.out.println("The JDK version is duplicate: " + jdkPath); + } + } + return jdkInfoList; + } + + // Retrieves TSA info from the file which is specified by property tsaListFile, + // or from property tsaList if tsaListFile is not available. + private static List tsaInfoList() throws IOException { + String[] tsaList = list("tsaList"); + + List tsaInfoList = new ArrayList(); + for (int i = 0; i < tsaList.length; i++) { + String[] values = tsaList[i].split(";digests="); + + String[] digests = new String[0]; + if (values.length == 2) { + digests = values[1].split(","); + } + + TsaInfo bufTsa = new TsaInfo(i, values[0]); + + for (String digest : digests) { + bufTsa.addDigest(digest); + } + + tsaInfoList.add(bufTsa); + } + + return tsaInfoList; + } + + private static String[] list(String listProp) + throws IOException { + String listFileProp = listProp + "File"; + String listFile = System.getProperty(listFileProp); + if (!isEmpty(listFile)) { + System.out.println(listFileProp + "=" + listFile); + List list = new ArrayList(); + BufferedReader reader = new BufferedReader( + new FileReader(listFile)); + String line; + while ((line = reader.readLine()) != null) { + String item = line.trim(); + if (!item.isEmpty()) { + list.add(item); + } + } + reader.close(); + return list.toArray(new String[list.size()]); + } + + String list = System.getProperty(listProp); + System.out.println(listProp + "=" + list); + return !isEmpty(list) ? list.split("#") : new String[0]; + } + + private static boolean isEmpty(String str) { + return str == null || str.isEmpty(); + } + + // A JDK (signer) signs a jar with a variety of algorithms, and then all of + // JDKs (verifiers), including the signer itself, try to verify the signed + // jars respectively. + private static List test(List jdkInfoList, + List tsaInfoList, List certList) + throws Throwable { + detailsOutput.transferPhase(); + List signItems = signing(jdkInfoList, tsaInfoList, certList); + + detailsOutput.transferPhase(); + for (SignItem signItem : signItems) { + for (JdkInfo verifierInfo : jdkInfoList) { + // JDK 6 doesn't support EC + if (!verifierInfo.isJdk6() + || signItem.certInfo.keyAlgorithm != EC) { + verifying(signItem, VerifyItem.build(verifierInfo)); + } + } + } + + if (DELAY_VERIFY) { + detailsOutput.transferPhase(); + System.out.print("Waiting for delay verifying"); + long lastCertExpirationTime = lastCertStartTime + 24 * 60 * 60 * 1000; + while (System.currentTimeMillis() < lastCertExpirationTime) { + TimeUnit.SECONDS.sleep(30); + System.out.print("."); + } + System.out.println(); + + System.out.println("Delay verifying starts"); + for (SignItem signItem : signItems) { + for (VerifyItem verifyItem : signItem.verifyItems) { + verifying(signItem, verifyItem); + } + } + } + + detailsOutput.transferPhase(); + + return signItems; + } + + private static List signing(List jdkInfos, + List tsaList, List certList) throws Throwable { + List signItems = new ArrayList(); + + Set signFilter = new HashSet(); + + for (JdkInfo signerInfo : jdkInfos) { + for (String keyAlgorithm : KEY_ALGORITHMS) { + // JDK 6 doesn't support EC + if (signerInfo.isJdk6() && keyAlgorithm == EC) { + continue; + } + + for (String digestAlgorithm : DIGEST_ALGORITHMS) { + String sigalg = sigalg(digestAlgorithm, keyAlgorithm); + // If the signature algorithm is not supported by the JDK, + // it cannot try to sign jar with this algorithm. + if (sigalg != null && !signerInfo.isSupportedSigalg(sigalg)) { + continue; + } + + // If the JDK doesn't support option -tsadigestalg, the + // associated cases just be ignored. + if (digestAlgorithm != DEFAULT + && !signerInfo.supportsTsadigestalg) { + continue; + } + + for (int keySize : keySizes(keyAlgorithm)) { + for (boolean expired : EXPIRED) { + CertInfo certInfo = new CertInfo( + signerInfo.version, + keyAlgorithm, + digestAlgorithm, + keySize, + expired); + if (!certList.contains(certInfo)) { + continue; + } + + String tsadigestalg = digestAlgorithm != DEFAULT + ? digestAlgorithm + : null; + + for (TsaInfo tsaInfo : tsaList) { + // It has to ignore the digest algorithm, which + // is not supported by the TSA server. + if(!tsaInfo.isDigestSupported(tsadigestalg)) { + continue; + } + + String tsaUrl = tsaInfo.tsaUrl; + if (TsaFilter.filter( + signerInfo.version, + digestAlgorithm, + expired, + tsaInfo.index)) { + tsaUrl = null; + } + + String signedJar = "JDK_" + + signerInfo.version + "-CERT_" + + certInfo + + (tsaUrl == null + ? "" + : "-TSA_" + tsaInfo.index); + + // It has to ignore the same jar signing. + if (!signFilter.add(signedJar)) { + continue; + } + + SignItem signItem = SignItem.build() + .certInfo(certInfo) + .version(signerInfo.version) + .signatureAlgorithm(sigalg) + .tsaDigestAlgorithm( + tsaUrl == null + ? null + : tsadigestalg) + .tsaIndex( + tsaUrl == null + ? -1 + : tsaInfo.index) + .signedJar(signedJar); + String signingId = signingId(signItem); + detailsOutput.writeAnchorName(signingId, + "Signing: " + signingId); + + OutputAnalyzer signOA = signJar( + signerInfo.jarsignerPath, + sigalg, + tsadigestalg, + tsaUrl, + certInfo.alias(), + signedJar); + Status signingStatus = signingStatus(signOA); + signItem.status(signingStatus); + + if (signingStatus != Status.ERROR) { + // Using the testing JDK, which is specified + // by jtreg option "-jdk", to verify the + // signed jar and extract the signature + // algorithm and timestamp digest algorithm. + String output = verifyJar(TEST_JARSIGNER, + signedJar).getOutput(); + signItem.extractedSignatureAlgorithm( + extract(output, + " *Signature algorithm.*", + ".*: |,.*")); + signItem.extractedTsaDigestAlgorithm( + extract(output, + " *Timestamp digest algorithm.*", + ".*: ")); + } + + signItems.add(signItem); + } + } + } + } + } + } + + return signItems; + } + + private static void verifying(SignItem signItem, VerifyItem verifyItem) + throws Throwable { + boolean delayVerify = verifyItem.status == Status.NONE; + String verifyingId = verifyingId(signItem, verifyItem, !delayVerify); + detailsOutput.writeAnchorName(verifyingId, "Verifying: " + verifyingId); + + OutputAnalyzer verifyOA = verifyJar(verifyItem.jdkInfo.jarsignerPath, + signItem.signedJar); + Status verifyingStatus = verifyingStatus(verifyOA); + + // It checks if the default timestamp digest algorithm is SHA-256. + if (verifyingStatus != Status.ERROR + && signItem.tsaDigestAlgorithm == null) { + verifyingStatus = signItem.extractedTsaDigestAlgorithm != null + && !signItem.extractedTsaDigestAlgorithm.matches("SHA-?256") + ? Status.ERROR + : verifyingStatus; + if (verifyingStatus == Status.ERROR) { + System.out.println("The default tsa digest is not SHA-256: " + + signItem.extractedTsaDigestAlgorithm); + } + } + + if (delayVerify) { + signItem.addVerifyItem(verifyItem.status(verifyingStatus)); + } else { + verifyItem.delayStatus(verifyingStatus); + } + } + + // Return key sizes according to the specified key algorithm. + private static int[] keySizes(String keyAlgorithm) { + if (keyAlgorithm == RSA || keyAlgorithm == DSA) { + return new int[] { 1024, 2048, 0 }; + } else if (keyAlgorithm == EC) { + return new int[] { 384, 571, 0 }; + } + + return null; + } + + // Determines the status of signing. + private static Status signingStatus(OutputAnalyzer outputAnalyzer) { + if (outputAnalyzer.getExitValue() == 0) { + if (outputAnalyzer.getOutput().contains(Test.WARNING)) { + return Status.WARNING; + } else { + return Status.NORMAL; + } + } else { + return Status.ERROR; + } + } + + // Determines the status of verifying. + private static Status verifyingStatus(OutputAnalyzer outputAnalyzer) { + if (outputAnalyzer.getExitValue() == 0) { + String output = outputAnalyzer.getOutput(); + if (!output.contains(Test.JAR_VERIFIED)) { + return Status.ERROR; + } else if (output.contains(Test.WARNING)) { + return Status.WARNING; + } else { + return Status.NORMAL; + } + } else { + return Status.ERROR; + } + } + + // Extracts string from text by specified patterns. + private static String extract(String text, String linePattern, + String replacePattern) { + Matcher lineMatcher = Pattern.compile(linePattern).matcher(text); + if (lineMatcher.find()) { + String line = lineMatcher.group(0); + return line.replaceAll(replacePattern, ""); + } else { + return null; + } + } + + // Using specified jarsigner to sign the pre-created jar with specified + // algorithms. + private static OutputAnalyzer signJar(String jarsignerPath, String sigalg, + String tsadigestalg, String tsa, String alias, String signedJar) + throws Throwable { + List arguments = new ArrayList(); + + if (PROXY_HOST != null && PROXY_PORT != null) { + arguments.add("-J-Dhttp.proxyHost=" + PROXY_HOST); + arguments.add("-J-Dhttp.proxyPort=" + PROXY_PORT); + arguments.add("-J-Dhttps.proxyHost=" + PROXY_HOST); + arguments.add("-J-Dhttps.proxyPort=" + PROXY_PORT); + } + arguments.add("-J-Djava.security.properties=" + JAVA_SECURITY); + arguments.add("-debug"); + arguments.add("-verbose"); + if (sigalg != null) { + arguments.add("-sigalg"); + arguments.add(sigalg); + } + if (tsa != null) { + arguments.add("-tsa"); + arguments.add(tsa); + } + if (tsadigestalg != null) { + arguments.add("-tsadigestalg"); + arguments.add(tsadigestalg); + } + arguments.add("-keystore"); + arguments.add(KEYSTORE); + arguments.add("-storepass"); + arguments.add(PASSWORD); + arguments.add("-signedjar"); + arguments.add(signedJar + ".jar"); + arguments.add(TEST_JAR_NAME); + arguments.add(alias); + + OutputAnalyzer outputAnalyzer = execTool( + jarsignerPath, + arguments.toArray(new String[arguments.size()])); + return outputAnalyzer; + } + + // Using specified jarsigner to verify the signed jar. + private static OutputAnalyzer verifyJar(String jarsignerPath, + String signedJar) throws Throwable { + OutputAnalyzer outputAnalyzer = execTool( + jarsignerPath, + "-J-Djava.security.properties=" + JAVA_SECURITY, + "-debug", + "-verbose", + "-certs", + "-keystore", KEYSTORE, + "-verify", signedJar + ".jar"); + return outputAnalyzer; + } + + // Generates the test result report. + private static boolean generateReport(List tsaList, + List signItems) throws IOException { + System.out.println("Report is being generated..."); + + StringBuilder report = new StringBuilder(); + report.append(HtmlHelper.startHtml()); + report.append(HtmlHelper.startPre()); + // Generates TSA URLs + report.append("TSA list:\n"); + for(TsaInfo tsaInfo : tsaList) { + report.append( + String.format("%d=%s%n", tsaInfo.index, tsaInfo.tsaUrl)); + } + report.append(HtmlHelper.endPre()); + + report.append(HtmlHelper.startTable()); + // Generates report headers. + List headers = new ArrayList(); + headers.add("[Certificate]"); + headers.add("[Signer JDK]"); + headers.add("[Signature Algorithm]"); + headers.add("[TSA Digest]"); + headers.add("[TSA]"); + headers.add("[Signing Status]"); + headers.add("[Verifier JDK]"); + headers.add("[Verifying Status]"); + if (DELAY_VERIFY) { + headers.add("[Delay Verifying Status]"); + } + headers.add("[Failed]"); + report.append(HtmlHelper.htmlRow( + headers.toArray(new String[headers.size()]))); + + StringBuilder failedReport = new StringBuilder(report.toString()); + + boolean failed = false; + + // Generates report rows. + for (SignItem signItem : signItems) { + for (VerifyItem verifyItem : signItem.verifyItems) { + String reportRow = reportRow(signItem, verifyItem); + report.append(reportRow); + boolean isFailedCase = isFailed(signItem, verifyItem); + if (isFailedCase) { + failedReport.append(reportRow); + } + failed = failed || isFailedCase; + } + } + + report.append(HtmlHelper.endTable()); + report.append(HtmlHelper.endHtml()); + generateFile("report.html", report.toString()); + if (failed) { + failedReport.append(HtmlHelper.endTable()); + failedReport.append(HtmlHelper.endPre()); + failedReport.append(HtmlHelper.endHtml()); + generateFile("failedReport.html", failedReport.toString()); + } + + System.out.println("Report is generated."); + return failed; + } + + private static void generateFile(String path, String content) + throws IOException { + FileWriter writer = new FileWriter(new File(path)); + writer.write(content); + writer.close(); + } + + private static String jarsignerPath(String jdkPath) { + return jdkPath + "/bin/jarsigner"; + } + + // Executes the specified function on JdkUtils by the specified JDK. + private static String execJdkUtils(String jdkPath, String method, + String... args) throws Throwable { + String[] cmd = new String[args.length + 5]; + cmd[0] = jdkPath + "/bin/java"; + cmd[1] = "-cp"; + cmd[2] = TEST_CLASSES; + cmd[3] = JdkUtils.class.getName(); + cmd[4] = method; + System.arraycopy(args, 0, cmd, 5, args.length); + return ProcessTools.executeCommand(cmd).getOutput(); + } + + // Executes the specified JDK tools, such as keytool and jarsigner, and + // ensures the output is in US English. + private static OutputAnalyzer execTool(String toolPath, String... args) + throws Throwable { + String[] cmd = new String[args.length + 4]; + cmd[0] = toolPath; + cmd[1] = "-J-Duser.language=en"; + cmd[2] = "-J-Duser.country=US"; + cmd[3] = "-J-Djava.security.egd=file:/dev/./urandom"; + System.arraycopy(args, 0, cmd, 4, args.length); + return ProcessTools.executeCommand(cmd); + } + + private static class JdkInfo { + + private final String jdkPath; + private final String jarsignerPath; + private final String version; + private final boolean supportsTsadigestalg; + + private Map sigalgMap = new HashMap(); + + private JdkInfo(String jdkPath) throws Throwable { + this.jdkPath = jdkPath; + version = execJdkUtils(jdkPath, JdkUtils.M_JAVA_RUNTIME_VERSION); + if (version == null || version.trim().isEmpty()) { + throw new RuntimeException( + "Cannot determine the JDK version: " + jdkPath); + } + jarsignerPath = jarsignerPath(jdkPath); + supportsTsadigestalg = execTool(jarsignerPath, "-help") + .getOutput().contains("-tsadigestalg"); + } + + private boolean isSupportedSigalg(String sigalg) throws Throwable { + if (!sigalgMap.containsKey(sigalg)) { + boolean isSupported = "true".equalsIgnoreCase( + execJdkUtils( + jdkPath, + JdkUtils.M_IS_SUPPORTED_SIGALG, + sigalg)); + sigalgMap.put(sigalg, isSupported); + } + + return sigalgMap.get(sigalg); + } + + private boolean isJdk6() { + return version.startsWith("1.6"); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((version == null) ? 0 : version.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + JdkInfo other = (JdkInfo) obj; + if (version == null) { + if (other.version != null) + return false; + } else if (!version.equals(other.version)) + return false; + return true; + } + } + + private static class TsaInfo { + + private final int index; + private final String tsaUrl; + private Set digestList = new HashSet(); + + private TsaInfo(int index, String tsa) { + this.index = index; + this.tsaUrl = tsa; + } + + private void addDigest(String digest) { + if (!ignore(digest)) { + digestList.add(digest); + } + } + + private static boolean ignore(String digest) { + return !SHA1.equalsIgnoreCase(digest) + && !SHA256.equalsIgnoreCase(digest) + && !SHA512.equalsIgnoreCase(digest); + } + + private boolean isDigestSupported(String digest) { + return digest == null || digestList.isEmpty() + || digestList.contains(digest); + } + } + + private static class CertInfo { + + private final String jdkVersion; + private final String keyAlgorithm; + private final String digestAlgorithm; + private final int keySize; + private final boolean expired; + + private CertInfo(String jdkVersion, String keyAlgorithm, + String digestAlgorithm, int keySize, boolean expired) { + this.jdkVersion = jdkVersion; + this.keyAlgorithm = keyAlgorithm; + this.digestAlgorithm = digestAlgorithm; + this.keySize = keySize; + this.expired = expired; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((digestAlgorithm == null) ? 0 : digestAlgorithm.hashCode()); + result = prime * result + (expired ? 1231 : 1237); + result = prime * result + + ((jdkVersion == null) ? 0 : jdkVersion.hashCode()); + result = prime * result + + ((keyAlgorithm == null) ? 0 : keyAlgorithm.hashCode()); + result = prime * result + keySize; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CertInfo other = (CertInfo) obj; + if (digestAlgorithm == null) { + if (other.digestAlgorithm != null) + return false; + } else if (!digestAlgorithm.equals(other.digestAlgorithm)) + return false; + if (expired != other.expired) + return false; + if (jdkVersion == null) { + if (other.jdkVersion != null) + return false; + } else if (!jdkVersion.equals(other.jdkVersion)) + return false; + if (keyAlgorithm == null) { + if (other.keyAlgorithm != null) + return false; + } else if (!keyAlgorithm.equals(other.keyAlgorithm)) + return false; + if (keySize != other.keySize) + return false; + return true; + } + + private String alias() { + return jdkVersion + "_" + toString(); + } + + @Override + public String toString() { + return keyAlgorithm + "_" + digestAlgorithm + + (keySize == 0 ? "" : "_" + keySize) + + (expired ? "_Expired" : ""); + } + } + + // It does only one timestamping for the same JDK, digest algorithm and + // TSA service with an arbitrary valid/expired certificate. + private static class TsaFilter { + + private static final Set SET = new HashSet(); + + private static boolean filter(String signerVersion, + String digestAlgorithm, boolean expiredCert, int tsaIndex) { + return !SET.add(new Condition(signerVersion, digestAlgorithm, + expiredCert, tsaIndex)); + } + + private static class Condition { + + private final String signerVersion; + private final String digestAlgorithm; + private final boolean expiredCert; + private final int tsaIndex; + + private Condition(String signerVersion, String digestAlgorithm, + boolean expiredCert, int tsaIndex) { + this.signerVersion = signerVersion; + this.digestAlgorithm = digestAlgorithm; + this.expiredCert = expiredCert; + this.tsaIndex = tsaIndex; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((digestAlgorithm == null) ? 0 : digestAlgorithm.hashCode()); + result = prime * result + (expiredCert ? 1231 : 1237); + result = prime * result + + ((signerVersion == null) ? 0 : signerVersion.hashCode()); + result = prime * result + tsaIndex; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Condition other = (Condition) obj; + if (digestAlgorithm == null) { + if (other.digestAlgorithm != null) + return false; + } else if (!digestAlgorithm.equals(other.digestAlgorithm)) + return false; + if (expiredCert != other.expiredCert) + return false; + if (signerVersion == null) { + if (other.signerVersion != null) + return false; + } else if (!signerVersion.equals(other.signerVersion)) + return false; + if (tsaIndex != other.tsaIndex) + return false; + return true; + } + }} + + private static enum Status { + + // No action due to pre-action fails. + NONE, + + // jar is signed/verified with error + ERROR, + + // jar is signed/verified with warning + WARNING, + + // jar is signed/verified without any warning and error + NORMAL + } + + private static class SignItem { + + private CertInfo certInfo; + private String version; + private String signatureAlgorithm; + // Signature algorithm that is extracted from verification output. + private String extractedSignatureAlgorithm; + private String tsaDigestAlgorithm; + // TSA digest algorithm that is extracted from verification output. + private String extractedTsaDigestAlgorithm; + private int tsaIndex; + private Status status; + private String signedJar; + + private List verifyItems = new ArrayList(); + + private static SignItem build() { + return new SignItem(); + } + + private SignItem certInfo(CertInfo certInfo) { + this.certInfo = certInfo; + return this; + } + + private SignItem version(String version) { + this.version = version; + return this; + } + + private SignItem signatureAlgorithm(String signatureAlgorithm) { + this.signatureAlgorithm = signatureAlgorithm; + return this; + } + + private SignItem extractedSignatureAlgorithm( + String extractedSignatureAlgorithm) { + this.extractedSignatureAlgorithm = extractedSignatureAlgorithm; + return this; + } + + private SignItem tsaDigestAlgorithm(String tsaDigestAlgorithm) { + this.tsaDigestAlgorithm = tsaDigestAlgorithm; + return this; + } + + private SignItem extractedTsaDigestAlgorithm( + String extractedTsaDigestAlgorithm) { + this.extractedTsaDigestAlgorithm = extractedTsaDigestAlgorithm; + return this; + } + + private SignItem tsaIndex(int tsaIndex) { + this.tsaIndex = tsaIndex; + return this; + } + + private SignItem status(Status status) { + this.status = status; + return this; + } + + private SignItem signedJar(String signedJar) { + this.signedJar = signedJar; + return this; + } + + private void addVerifyItem(VerifyItem verifyItem) { + verifyItems.add(verifyItem); + } + } + + private static class VerifyItem { + + private JdkInfo jdkInfo; + private Status status = Status.NONE; + private Status delayStatus = Status.NONE; + + private static VerifyItem build(JdkInfo jdkInfo) { + VerifyItem verifyItem = new VerifyItem(); + verifyItem.jdkInfo = jdkInfo; + return verifyItem; + } + + private VerifyItem status(Status status) { + this.status = status; + return this; + } + + private VerifyItem delayStatus(Status status) { + this.delayStatus = status; + return this; + } + } + + // The identifier for a specific signing. + private static String signingId(SignItem signItem) { + return signItem.signedJar; + } + + // The identifier for a specific verifying. + private static String verifyingId(SignItem signItem, VerifyItem verifyItem, + boolean delayVerify) { + return "S_" + signingId(signItem) + "-" + (delayVerify ? "DV" : "V") + + "_" + verifyItem.jdkInfo.version; + } + + private static String reportRow(SignItem signItem, VerifyItem verifyItem) { + List values = new ArrayList(); + values.add(signItem.certInfo.toString()); + values.add(signItem.version); + values.add(null2Default(signItem.signatureAlgorithm, + signItem.extractedSignatureAlgorithm)); + values.add(signItem.tsaIndex == -1 + ? "" + : null2Default(signItem.tsaDigestAlgorithm, + signItem.extractedTsaDigestAlgorithm)); + values.add(signItem.tsaIndex == -1 ? "" : signItem.tsaIndex + ""); + values.add(HtmlHelper.anchorLink( + PhaseOutputStream.fileName(PhaseOutputStream.Phase.SIGNING), + signingId(signItem), + signItem.status.toString())); + values.add(verifyItem.jdkInfo.version); + values.add(HtmlHelper.anchorLink( + PhaseOutputStream.fileName(PhaseOutputStream.Phase.VERIFYING), + verifyingId(signItem, verifyItem, false), + verifyItem.status.toString())); + if (DELAY_VERIFY) { + values.add(HtmlHelper.anchorLink( + PhaseOutputStream.fileName( + PhaseOutputStream.Phase.DELAY_VERIFYING), + verifyingId(signItem, verifyItem, true), + verifyItem.delayStatus.toString())); + } + values.add(isFailed(signItem, verifyItem) ? "X" : ""); + return HtmlHelper.htmlRow(values.toArray(new String[values.size()])); + } + + private static boolean isFailed(SignItem signItem, + VerifyItem verifyItem) { + return signItem.status == Status.ERROR + || verifyItem.status == Status.ERROR + || verifyItem.delayStatus == Status.ERROR; + } + + // If a value is null, then displays the default value or N/A. + private static String null2Default(String value, String defaultValue) { + return value == null + ? DEFAULT + "(" + (defaultValue == null + ? "N/A" + : defaultValue) + ")" + : value; + } +} diff --git a/jdk/test/sun/security/tools/jarsigner/compatibility/DetailsOutputStream.java b/jdk/test/sun/security/tools/jarsigner/compatibility/DetailsOutputStream.java new file mode 100644 index 00000000000..f125322c37b --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/compatibility/DetailsOutputStream.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +/* + * A custom output stream that redirects the testing outputs to a file, called + * details.out. It also calls another output stream to save some outputs to + * other files. + */ +public class DetailsOutputStream extends FileOutputStream { + + private PhaseOutputStream phaseOutputStream = new PhaseOutputStream(); + + public DetailsOutputStream() throws FileNotFoundException { + super("details.out", true); + } + + public void transferPhase() throws IOException { + if (phaseOutputStream.isCorePhase()) { + phaseOutputStream.write(HtmlHelper.endHtml()); + phaseOutputStream.write(HtmlHelper.endPre()); + } + + phaseOutputStream.transfer(); + + if (phaseOutputStream.isCorePhase()) { + phaseOutputStream.write(HtmlHelper.startHtml()); + phaseOutputStream.write(HtmlHelper.startPre()); + } + } + + @Override + public void write(byte[] b) throws IOException { + super.write(b); + phaseOutputStream.write(b); + } + + @Override + public void write(int b) throws IOException { + super.write(b); + phaseOutputStream.write(b); + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + super.write(b, off, len); + phaseOutputStream.write(b, off, len); + } + + public void writeAnchorName(String name, String text) throws IOException { + super.write((text).getBytes()); + super.write('\n'); + phaseOutputStream.write(HtmlHelper.anchorName(name, text)); + phaseOutputStream.write('\n'); + } +} diff --git a/jdk/test/sun/security/tools/jarsigner/compatibility/HtmlHelper.java b/jdk/test/sun/security/tools/jarsigner/compatibility/HtmlHelper.java new file mode 100644 index 00000000000..d00cf02f0d5 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/compatibility/HtmlHelper.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A helper that is used for creating HTML elements. + */ +public class HtmlHelper { + + private static final String STYLE + = "style=\"font-family: Courier New; " + + "font-size: 12px; " + + "white-space: pre-wrap\""; + + public static String htmlRow(String... values) { + StringBuilder row = new StringBuilder(); + row.append(startTr()); + for (String value : values) { + row.append(startTd()); + row.append(value); + row.append(endTd()); + } + row.append(endTr()); + return row.toString(); + } + + public static String startHtml() { + return startTag("html"); + } + + public static String endHtml() { + return endTag("html"); + } + + public static String startPre() { + return startTag("pre " + STYLE); + } + + public static String endPre() { + return endTag("pre"); + } + + public static String startTable() { + return startTag("table " + STYLE); + } + + public static String endTable() { + return endTag("table"); + } + + public static String startTr() { + return startTag("tr"); + } + + public static String endTr() { + return endTag("tr"); + } + + public static String startTd() { + return startTag("td"); + } + + public static String endTd() { + return endTag("td"); + } + + public static String startTag(String tag) { + return "<" + tag + ">"; + } + + public static String endTag(String tag) { + return ""; + } + + public static String anchorName(String name, String text) { + return "" + text + ""; + } + + public static String anchorLink(String file, String anchorName, + String text) { + return "" + text + ""; + } +} diff --git a/jdk/test/sun/security/tools/jarsigner/compatibility/JdkUtils.java b/jdk/test/sun/security/tools/jarsigner/compatibility/JdkUtils.java new file mode 100644 index 00000000000..cd990161b92 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/compatibility/JdkUtils.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.NoSuchAlgorithmException; +import java.security.Signature; + +/* + * This class is used for returning some specific JDK information. + */ +public class JdkUtils { + + static final String M_JAVA_RUNTIME_VERSION = "javaRuntimeVersion"; + static final String M_IS_SUPPORTED_SIGALG = "isSupportedSigalg"; + + // Returns the JDK build version. + static String javaRuntimeVersion() { + return System.getProperty("java.runtime.version"); + } + + // Checks if the specified signature algorithm is supported by the JDK. + static boolean isSupportedSigalg(String sigalg) { + boolean isSupported = false; + try { + isSupported = Signature.getInstance(sigalg) != null; + } catch (NoSuchAlgorithmException e) { } + + if (!isSupported) { + System.out.println(sigalg + " is not supported yet."); + } + + return isSupported; + } + + public static void main(String[] args) { + if (M_JAVA_RUNTIME_VERSION.equals(args[0])) { + System.out.print(javaRuntimeVersion()); + } else if (M_IS_SUPPORTED_SIGALG.equals(args[0])) { + System.out.print(isSupportedSigalg(args[1])); + } + } +} diff --git a/jdk/test/sun/security/tools/jarsigner/compatibility/PhaseOutputStream.java b/jdk/test/sun/security/tools/jarsigner/compatibility/PhaseOutputStream.java new file mode 100644 index 00000000000..f99822ca1f8 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/compatibility/PhaseOutputStream.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/* + * A custom output stream that saves the testing details to different files + * according to the current testing phase. + */ +public class PhaseOutputStream extends OutputStream { + + public enum Phase { + PRE_SIGNING, // before jar signing + SIGNING, // jar signing + VERIFYING, // jar verifying + DELAY_VERIFYING, // jar verifying after certificates expire + POST_VERIFYING; // after jar verifying + } + + private OutputStream signingOut = null; + private OutputStream verifyingOut = null; + private OutputStream delayVerifyingOut = null; + + private Phase currentPhase = Phase.PRE_SIGNING; + + public void transfer() { + switch (currentPhase) { + case PRE_SIGNING: + currentPhase = Phase.SIGNING; + break; + case SIGNING: + currentPhase = Phase.VERIFYING; + break; + case VERIFYING: + currentPhase = Compatibility.DELAY_VERIFY + ? Phase.DELAY_VERIFYING + : Phase.POST_VERIFYING; + break; + case DELAY_VERIFYING: + currentPhase = Phase.POST_VERIFYING; + break; + case POST_VERIFYING: + currentPhase = Phase.POST_VERIFYING; + break; + } + } + + // The core phases are SIGNING, VERIFYING and DELAY_VERIFYING. + public boolean isCorePhase() { + return currentPhase != PhaseOutputStream.Phase.PRE_SIGNING + && currentPhase != PhaseOutputStream.Phase.POST_VERIFYING; + } + + public Phase currentPhase() { + return currentPhase; + } + + @Override + public void write(int b) throws IOException { + OutputStream output = phaseOut(); + if (output != null) { + output.write(b); + } + } + + @Override + public void write(byte[] b) throws IOException { + OutputStream output = phaseOut(); + if (output != null) { + output.write(b); + } + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + OutputStream output = phaseOut(); + if (output != null) { + output.write(b, off, len); + } + } + + public void write(String str) throws IOException { + write(str.getBytes()); + } + + private OutputStream phaseOut() throws FileNotFoundException { + switch (currentPhase) { + case SIGNING: + return signingOut == null + ? signingOut = createOutput(Phase.SIGNING) + : signingOut; + case VERIFYING: + return verifyingOut == null + ? verifyingOut = createOutput(Phase.VERIFYING) + : verifyingOut; + case DELAY_VERIFYING: + return delayVerifyingOut == null + ? delayVerifyingOut = createOutput(Phase.DELAY_VERIFYING) + : delayVerifyingOut; + default: + return null; + } + } + + @Override + public void flush() throws IOException { + flush(signingOut); + flush(verifyingOut); + flush(delayVerifyingOut); + } + + private void flush(OutputStream output) throws IOException { + if (output != null) { + output.flush(); + } + } + + @Override + public void close() throws IOException { + close(signingOut); + close(verifyingOut); + close(delayVerifyingOut); + } + + private void close(OutputStream output) throws IOException { + if (output != null) { + output.close(); + } + } + + private static OutputStream createOutput(Phase phase) + throws FileNotFoundException { + return new FileOutputStream(fileName(phase), true); + } + + public static String fileName(Phase phase) { + return phase.name() + ".html"; + } +} diff --git a/jdk/test/sun/security/tools/jarsigner/compatibility/README b/jdk/test/sun/security/tools/jarsigner/compatibility/README new file mode 100644 index 00000000000..7868788c2e6 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/compatibility/README @@ -0,0 +1,215 @@ +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. + +##### Summary ##### +This test is used to verify the compatibility on jarsigner cross different JDK +releases. It also can be used to check jar signing (w/ and w/o TSA) and verifying +on some specific key algorithms and digest algorithms. + +##### Output ##### +The test will generate a report, at JTwork/scratch/report.html, to display the +key parameters for signing and the status of signing and verifying. And it will +generate another report, at JTwork/scratch/failedReport.html, to collect all of +failed cases. + +Please note that, the test may output a great deal of logs if the jdk list and +TSA list are big, and that would lead to jtreg output overflow. So, it redirects +stdout and stderr to file JTwork/scratch/details.out. + +##### Report Columns ##### +Certificate + Certificate identifier. The identifier consists of specific attributes of + the certificate. Generally, the naming convention is: + KeyAlgorithm_DigestAlgorithm_[KeySize][_Expired] + +Signer JDK + The JDK version that signs jar. + +Signature Algorithm + The signature algorithm used by signing. + +TSA Digest + The timestamp digest algorithm used by signing. + +TSA + TSA URL index. All of TSA URLs and their indices can be found at the top + of this report. + +Signing Status + Signing process result status. The status are the followings: + [1]NONE, no action. + [2]NORMAL, no any error and warning. + [3]WARNING, no any error but some warnings raise. + [4]ERROR, some errors raise. + +Verifier JDK + The JDK version that verifies signed jars. + +Verifying Status + Verifying process result status. The status are the same as those for + "Status of Signing". + +Delay Verifying Status + Delay verifying process result status. The status are the same as those + for "Status of Signing". + +Failed + It highlights which case fails. The failed cases (rows) are marked with + letter X. + +##### Usages ##### +jtreg [-options] \ + -jdk: + [-DproxyHost= \ + -DproxyPort= \ + -DtsaListFile= \ + -DtsaList= \ + -DjdkListFile= \ + -DjdkList= \ + -DjavaSecurityFile= \ + -DdelayVerify= \ + -DcertValidity=<[1, 1440]>] \ + /jdk/test/sun/security/tools/jarsigner/compatibility/Compatibility.java + +Besides the common jtreg options, like -jdk, this test introduces a set of +properties for receiving users' inputs and making the test more flexible. These +properties are: +proxyHost= + This property indicates proxy host. + +proxyPort= + This property indicates proxy port. The default value is 80. + +tsaListFile= + This property indicates a local file, which contains a set of TSA URLs and + the supported digest algorithms (by optional parameter digests). The format + of the file content looks like the below, + http://path/to/tsa1 + http://path/to/tsa2;digests=SHA-1,SHA-256 + https://path/to/tsa3 + ... + + If a TSA line does not list the supported digest algorithms, that means + the TSA supports SHA-1, SHA-256 and SHA-512. Because the test only focus + on SHA-1, SHA-256 and SHA-512. So, if other digest algorithms, like SHA-224 + and SHA-384, are listed, they just be ignored. + +tsaList= + This property directly lists a set of TSAs in command. "#" is the delimiter. + Note that, if both of tsaListFile and tsaList are specified, only property + jdkListFile is selected. If neither of tsaListFile and tsaList is specified, + the test will fails immediately. + +jdkListFile= + This property indicates a local file, which contains a set of local JDK + paths. The style of the file content looks like the below, + /path/to/jdk1 + /path/to/jdk2 + /path/to/jdk3 + ... + +jdkList= + This property directly lists a set of local JDK paths in command. "#" is + the delimiter. + Note that, if both of jdkListFile and jdkList are specified, only property + jdkListFile is selected. If neither of jdkListFile nor jdkList is specified, + the testing JDK, which is specified by jtreg option -jdk will be used as + the only one JDK in the JDK list. + +javaSecurityFile= + This property indicates an alternative java security properties file. The + default file is the path of file java.scurity that is distributed with + this test. + +delayVerify= + This property indicates if doing an additional verifying after all of valid + certificates expire. The default value is false. + +certValidity=<[1, 1440]> + This property indicates the remaining validity period in minutes for valid + certificates. The value range is [1, 1440]. The default value is 1440. + Note that, if delayVerify is false, this property doesn't take effect. + +The testing JDK, which is specified by jtreg option "-jdk", should include the +fix for JDK-8163304. Otherwise, the signature algorithm and timestamp digest +algorithm cannot be extracted from verification output. And this JDK should +support as many as possible signature algorithms. Anyway the latest JDK build +is always recommended. + +##### Examples ##### +$ cat /path/to/jdkList +/path/to/jdk6u171-b05 +/path/to/jdk7u161-b05 +/path/to/jdk8u144-b01 +/path/to/jdk9-179 + +$ cat /path/to/tsaList +http://timestamp.comodoca.com/rfc3161 +http://sha256timestamp.ws.symantec.com/sha256/timestamp +http://tsa.starfieldtech.com +http://timestamp.entrust.net/TSS/RFC3161sha1TS;digests=SHA-1,SHA-256 +http://timestamp.entrust.net/TSS/RFC3161sha2TS;digests=SHA-1,SHA-256 +http://rfc3161timestamp.globalsign.com/advanced;digests=SHA-256,SHA-512 +http://rfc3161timestamp.globalsign.com/standard +http://timestamp.globalsign.com/scripts/timstamp.dll +http://timestamp.globalsign.com/?signature=sha2;digests=SHA-256,SHA-512 +http://timestamp.digicert.com +http://time.certum.pl +http://tsa.swisssign.net +http://zeitstempel.dfn.de +https://tsp.iaik.tugraz.at/tsp/TspRequest + +$ jtreg -va -nr -timeout:100 \ + -jdk:/path/to/latest/jdk \ + -DproxyHost= -DproxyPort= \ + -DjdkListFile=/path/to/jdkList \ + -DtsaListFile=/path/to/tsaList \ + -DdelayVerify=true -DcertValidity=60 \ + /jdk/test/sun/security/tools/jarsigner/compatibility/Compatibility.java + +The above is a comprehensive usage example. File "jdkList" lists the paths of +testing JDK builds, and file "tsaList" lists the URLs of TSA services. Some TSAs, +like http://timestamp.entrust.net/TSS/RFC3161sha1TS, specify the supported digest +algorithms. Other TSAs, which don't specify parameter digests, are regarded to +support SHA-1, SHA-256 and SHA-512. The test uses a proxy to access TSA services. +And it enables delay verifying and set the certificate validity period to 60 +minutes. So, after the first verification is done, the test will wait for all +of valid certificates expire and then does verification again. + +If don't want to provide such JDK list and TSA list files, the test allows to +specify JDKs and TSAs (via properties jdkList and tsaList respectively) in the +command directly, like the below style, +$ jtreg -va -nr -timeout:100 \ + -jdk:/path/to/latest/jdk \ + -DproxyHost= -DproxyPort= \ + -DjdkList=/path/to/jdk6u171-b05#/path/to/jdk7u161-b05#/path/to/jdk8u144-b01#/path/to/jdk9-179 \ + -DtsaList=http://timestamp.comodoca.com/rfc3161#http://timestamp.entrust.net/TSS/RFC3161sha1TS;digests=SHA-1,SHA-256 \ + -DdelayVerify=true -DcertValidity=60 \ + /jdk/test/sun/security/tools/jarsigner/compatibility/Compatibility.java + +Furthermore, here introduces one of the simplest usages. It doesn't specify any +JDK list, so the testing JDK, which is specified by jtreg option "-jdk", will +be tested. And it doesn't apply delay verifying, and no proxy is used, and use +only one TSA. Now, the command is pretty simple and looks like the followings, +$ jtreg -va -nr -timeout:100 \ + -jdk:/path/to/latest/jdk \ + -DtsaList=http://timestamp.comodoca.com/rfc3161 \ + /jdk/test/sun/security/tools/jarsigner/compatibility/Compatibility.java \ No newline at end of file diff --git a/jdk/test/sun/security/tools/jarsigner/compatibility/java.security b/jdk/test/sun/security/tools/jarsigner/compatibility/java.security new file mode 100644 index 00000000000..b8623c1f3db --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/compatibility/java.security @@ -0,0 +1,2 @@ +jdk.certpath.disabledAlgorithms=MD2, MD5 +jdk.jar.disabledAlgorithms=MD2, MD5 \ No newline at end of file From 997d77996c628ab6be2edfd23b5f635a59f32681 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 16 Aug 2017 10:55:05 +0100 Subject: [PATCH 38/42] 8181422: ClassCastException in HTTP Client Added missing AsyncSSLTunnelConnection Reviewed-by: michaelm --- .../http/AbstractAsyncSSLConnection.java | 85 +++++ .../incubator/http/AsyncSSLConnection.java | 44 +-- .../http/AsyncSSLTunnelConnection.java | 206 +++++++++++ .../jdk/incubator/http/ExchangeImpl.java | 4 +- .../jdk/incubator/http/Http2Connection.java | 21 +- .../jdk/incubator/http/HttpConnection.java | 7 +- .../http/PlainTunnelingConnection.java | 41 ++- .../jdk/incubator/http/SSLConnection.java | 4 +- .../incubator/http/SSLTunnelConnection.java | 13 + jdk/test/java/net/httpclient/ProxyTest.java | 11 +- .../java/net/httpclient/http2/ProxyTest2.java | 323 ++++++++++++++++++ .../http2/server/Http2TestServer.java | 12 +- .../server/Http2TestServerConnection.java | 11 +- 13 files changed, 725 insertions(+), 57 deletions(-) create mode 100644 jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractAsyncSSLConnection.java create mode 100644 jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLTunnelConnection.java create mode 100644 jdk/test/java/net/httpclient/http2/ProxyTest2.java diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractAsyncSSLConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractAsyncSSLConnection.java new file mode 100644 index 00000000000..07223e61f25 --- /dev/null +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractAsyncSSLConnection.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 jdk.incubator.http; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.util.concurrent.CompletableFuture; +import javax.net.ssl.SSLEngine; +import jdk.incubator.http.internal.common.ExceptionallyCloseable; + + +/** + * Asynchronous version of SSLConnection. + * + * There are two concrete implementations of this class: AsyncSSLConnection + * and AsyncSSLTunnelConnection. + * This abstraction is useful when downgrading from HTTP/2 to HTTP/1.1 over + * an SSL connection. See ExchangeImpl::get in the case where an ALPNException + * is thrown. + * + * Note: An AsyncSSLConnection wraps a PlainHttpConnection, while an + * AsyncSSLTunnelConnection wraps a PlainTunnelingConnection. + * If both these wrapped classes where made to inherit from a + * common abstraction then it might be possible to merge + * AsyncSSLConnection and AsyncSSLTunnelConnection back into + * a single class - and simply use different factory methods to + * create different wrappees, but this is left up for further cleanup. + * + */ +abstract class AbstractAsyncSSLConnection extends HttpConnection + implements AsyncConnection, ExceptionallyCloseable { + + + AbstractAsyncSSLConnection(InetSocketAddress addr, HttpClientImpl client) { + super(addr, client); + } + + abstract SSLEngine getEngine(); + abstract AsyncSSLDelegate sslDelegate(); + abstract HttpConnection plainConnection(); + abstract HttpConnection downgrade(); + + @Override + final boolean isSecure() { + return true; + } + + // Blocking read functions not used here + @Override + protected final ByteBuffer readImpl() throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + // whenReceivedResponse only used in HTTP/1.1 (Http1Exchange) + // AbstractAsyncSSLConnection is only used with HTTP/2 + @Override + final CompletableFuture whenReceivingResponse() { + throw new UnsupportedOperationException("Not supported."); + } + +} diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java index b1e6063951f..f6c095526ee 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java @@ -35,14 +35,12 @@ import java.util.function.Supplier; import javax.net.ssl.SSLEngine; import jdk.incubator.http.internal.common.ByteBufferReference; -import jdk.incubator.http.internal.common.ExceptionallyCloseable; import jdk.incubator.http.internal.common.Utils; /** * Asynchronous version of SSLConnection. */ -class AsyncSSLConnection extends HttpConnection - implements AsyncConnection, ExceptionallyCloseable { +class AsyncSSLConnection extends AbstractAsyncSSLConnection { final AsyncSSLDelegate sslDelegate; final PlainHttpConnection plainConnection; @@ -61,15 +59,14 @@ class AsyncSSLConnection extends HttpConnection plainConnection.configureMode(mode); } - private CompletableFuture configureModeAsync(Void ignore) { - CompletableFuture cf = new CompletableFuture<>(); - try { - configureMode(Mode.ASYNC); - cf.complete(null); - } catch (Throwable t) { - cf.completeExceptionally(t); - } - return cf; + @Override + PlainHttpConnection plainConnection() { + return plainConnection; + } + + @Override + AsyncSSLDelegate sslDelegate() { + return sslDelegate; } @Override @@ -91,11 +88,6 @@ class AsyncSSLConnection extends HttpConnection return plainConnection.connected() && sslDelegate.connected(); } - @Override - boolean isSecure() { - return true; - } - @Override boolean isProxied() { return false; @@ -172,6 +164,7 @@ class AsyncSSLConnection extends HttpConnection plainConnection.channel().shutdownOutput(); } + @Override SSLEngine getEngine() { return sslDelegate.getEngine(); } @@ -184,18 +177,6 @@ class AsyncSSLConnection extends HttpConnection plainConnection.setAsyncCallbacks(sslDelegate::asyncReceive, errorReceiver, sslDelegate::getNetBuffer); } - // Blocking read functions not used here - - @Override - protected ByteBuffer readImpl() throws IOException { - throw new UnsupportedOperationException("Not supported."); - } - - @Override - CompletableFuture whenReceivingResponse() { - throw new UnsupportedOperationException("Not supported."); - } - @Override public void startReading() { plainConnection.startReading(); @@ -206,4 +187,9 @@ class AsyncSSLConnection extends HttpConnection public void stopAsyncReading() { plainConnection.stopAsyncReading(); } + + @Override + SSLConnection downgrade() { + return new SSLConnection(this); + } } diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLTunnelConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLTunnelConnection.java new file mode 100644 index 00000000000..7afb87f5191 --- /dev/null +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLTunnelConnection.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 jdk.incubator.http; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.Supplier; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import jdk.incubator.http.internal.common.ByteBufferReference; +import jdk.incubator.http.internal.common.Utils; + +/** + * An SSL tunnel built on a Plain (CONNECT) TCP tunnel. + */ +class AsyncSSLTunnelConnection extends AbstractAsyncSSLConnection { + + final PlainTunnelingConnection plainConnection; + final AsyncSSLDelegate sslDelegate; + final String serverName; + + @Override + public void connect() throws IOException, InterruptedException { + plainConnection.connect(); + configureMode(Mode.ASYNC); + startReading(); + sslDelegate.connect(); + } + + @Override + boolean connected() { + return plainConnection.connected() && sslDelegate.connected(); + } + + @Override + public CompletableFuture connectAsync() { + throw new InternalError(); + } + + AsyncSSLTunnelConnection(InetSocketAddress addr, + HttpClientImpl client, + String[] alpn, + InetSocketAddress proxy) + { + super(addr, client); + this.serverName = Utils.getServerName(addr); + this.plainConnection = new PlainTunnelingConnection(addr, proxy, client); + this.sslDelegate = new AsyncSSLDelegate(plainConnection, client, alpn, serverName); + } + + @Override + synchronized void configureMode(Mode mode) throws IOException { + super.configureMode(mode); + plainConnection.configureMode(mode); + } + + @Override + SSLParameters sslParameters() { + return sslDelegate.getSSLParameters(); + } + + @Override + public String toString() { + return "AsyncSSLTunnelConnection: " + super.toString(); + } + + @Override + PlainTunnelingConnection plainConnection() { + return plainConnection; + } + + @Override + AsyncSSLDelegate sslDelegate() { + return sslDelegate; + } + + @Override + ConnectionPool.CacheKey cacheKey() { + return ConnectionPool.cacheKey(address, plainConnection.proxyAddr); + } + + @Override + long write(ByteBuffer[] buffers, int start, int number) throws IOException { + //debugPrint("Send", buffers, start, number); + ByteBuffer[] bufs = Utils.reduce(buffers, start, number); + long n = Utils.remaining(bufs); + sslDelegate.writeAsync(ByteBufferReference.toReferences(bufs)); + sslDelegate.flushAsync(); + return n; + } + + @Override + long write(ByteBuffer buffer) throws IOException { + //debugPrint("Send", buffer); + long n = buffer.remaining(); + sslDelegate.writeAsync(ByteBufferReference.toReferences(buffer)); + sslDelegate.flushAsync(); + return n; + } + + @Override + public void writeAsync(ByteBufferReference[] buffers) throws IOException { + sslDelegate.writeAsync(buffers); + } + + @Override + public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException { + sslDelegate.writeAsyncUnordered(buffers); + } + + @Override + public void flushAsync() throws IOException { + sslDelegate.flushAsync(); + } + + @Override + public void close() { + Utils.close(sslDelegate, plainConnection.channel()); + } + + @Override + void shutdownInput() throws IOException { + plainConnection.channel().shutdownInput(); + } + + @Override + void shutdownOutput() throws IOException { + plainConnection.channel().shutdownOutput(); + } + + @Override + SocketChannel channel() { + return plainConnection.channel(); + } + + @Override + boolean isProxied() { + return true; + } + + @Override + public void setAsyncCallbacks(Consumer asyncReceiver, + Consumer errorReceiver, + Supplier readBufferSupplier) { + sslDelegate.setAsyncCallbacks(asyncReceiver, errorReceiver, readBufferSupplier); + plainConnection.setAsyncCallbacks(sslDelegate::asyncReceive, errorReceiver, sslDelegate::getNetBuffer); + } + + @Override + public void startReading() { + plainConnection.startReading(); + sslDelegate.startReading(); + } + + @Override + public void stopAsyncReading() { + plainConnection.stopAsyncReading(); + } + + @Override + public void enableCallback() { + sslDelegate.enableCallback(); + } + + @Override + public void closeExceptionally(Throwable cause) throws IOException { + Utils.close(cause, sslDelegate, plainConnection.channel()); + } + + @Override + SSLEngine getEngine() { + return sslDelegate.getEngine(); + } + + @Override + SSLTunnelConnection downgrade() { + return new SSLTunnelConnection(this); + } +} diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java index 27b6c1964f4..3d41179d903 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java @@ -82,9 +82,9 @@ abstract class ExchangeImpl { c = c2.getConnectionFor(request); } catch (Http2Connection.ALPNException e) { // failed to negotiate "h2" - AsyncSSLConnection as = e.getConnection(); + AbstractAsyncSSLConnection as = e.getConnection(); as.stopAsyncReading(); - SSLConnection sslc = new SSLConnection(as); + HttpConnection sslc = as.downgrade(); ExchangeImpl ex = new Http1Exchange<>(exchange, sslc); return ex; } diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java index 275325f8b29..8e42022c286 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java @@ -211,12 +211,13 @@ class Http2Connection { this.hpackIn = new Decoder(clientSettings.getParameter(HEADER_TABLE_SIZE)); this.windowUpdater = new ConnectionWindowUpdateSender(this, client.getReceiveBufferSize()); } - /** - * Case 1) Create from upgraded HTTP/1.1 connection. - * Is ready to use. Will not be SSL. exchange is the Exchange - * that initiated the connection, whose response will be delivered - * on a Stream. - */ + + /** + * Case 1) Create from upgraded HTTP/1.1 connection. + * Is ready to use. Will not be SSL. exchange is the Exchange + * that initiated the connection, whose response will be delivered + * on a Stream. + */ Http2Connection(HttpConnection connection, Http2ClientImpl client2, Exchange exchange, @@ -280,7 +281,7 @@ class Http2Connection { * Throws an IOException if h2 was not negotiated */ private void checkSSLConfig() throws IOException { - AsyncSSLConnection aconn = (AsyncSSLConnection)connection; + AbstractAsyncSSLConnection aconn = (AbstractAsyncSSLConnection)connection; SSLEngine engine = aconn.getEngine(); String alpn = engine.getApplicationProtocol(); if (alpn == null || !alpn.equals("h2")) { @@ -906,14 +907,14 @@ class Http2Connection { */ static final class ALPNException extends IOException { private static final long serialVersionUID = 23138275393635783L; - final AsyncSSLConnection connection; + final AbstractAsyncSSLConnection connection; - ALPNException(String msg, AsyncSSLConnection connection) { + ALPNException(String msg, AbstractAsyncSSLConnection connection) { super(msg); this.connection = connection; } - AsyncSSLConnection getConnection() { + AbstractAsyncSSLConnection getConnection() { return connection; } } diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java index a520390ba2d..d81d3950374 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java @@ -34,7 +34,6 @@ import java.nio.channels.SocketChannel; import java.util.concurrent.CompletableFuture; import jdk.incubator.http.internal.common.ByteBufferReference; -import jdk.incubator.http.internal.common.Utils; /** * Wraps socket channel layer and takes care of SSL also. @@ -136,7 +135,11 @@ abstract class HttpConnection implements Closeable { String[] alpn, boolean isHttp2, HttpClientImpl client) { if (proxy != null) { - return new SSLTunnelConnection(addr, client, proxy); + if (!isHttp2) { + return new SSLTunnelConnection(addr, client, proxy); + } else { + return new AsyncSSLTunnelConnection(addr, client, alpn, proxy); + } } else if (!isHttp2) { return new SSLConnection(addr, client, alpn); } else { diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java index d133df1e250..c167c53f2b3 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java @@ -34,12 +34,15 @@ import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.Supplier; /** * A plain text socket tunnel through a proxy. Uses "CONNECT" but does not - * encrypt. Used by WebSocket. Subclassed in SSLTunnelConnection for encryption. + * encrypt. Used by WebSocket, as well as HTTP over SSL + Proxy. + * Wrapped in SSLTunnelConnection or AsyncSSLTunnelConnection for encryption. */ -class PlainTunnelingConnection extends HttpConnection { +class PlainTunnelingConnection extends HttpConnection implements AsyncConnection { final PlainHttpConnection delegate; protected final InetSocketAddress proxyAddr; @@ -116,17 +119,17 @@ class PlainTunnelingConnection extends HttpConnection { } @Override - void writeAsync(ByteBufferReference[] buffers) throws IOException { + public void writeAsync(ByteBufferReference[] buffers) throws IOException { delegate.writeAsync(buffers); } @Override - void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException { + public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException { delegate.writeAsyncUnordered(buffers); } @Override - void flushAsync() throws IOException { + public void flushAsync() throws IOException { delegate.flushAsync(); } @@ -165,4 +168,32 @@ class PlainTunnelingConnection extends HttpConnection { boolean isProxied() { return true; } + + @Override + public void setAsyncCallbacks(Consumer asyncReceiver, + Consumer errorReceiver, + Supplier readBufferSupplier) { + delegate.setAsyncCallbacks(asyncReceiver, errorReceiver, readBufferSupplier); + } + + @Override + public void startReading() { + delegate.startReading(); + } + + @Override + public void stopAsyncReading() { + delegate.stopAsyncReading(); + } + + @Override + public void enableCallback() { + delegate.enableCallback(); + } + + @Override + synchronized void configureMode(Mode mode) throws IOException { + super.configureMode(mode); + delegate.configureMode(mode); + } } diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java index 790d98b7fa0..9eb6a37e250 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java @@ -77,8 +77,8 @@ class SSLConnection extends HttpConnection { */ SSLConnection(AsyncSSLConnection c) { super(c.address, c.client); - this.delegate = c.plainConnection; - AsyncSSLDelegate adel = c.sslDelegate; + this.delegate = c.plainConnection(); + AsyncSSLDelegate adel = c.sslDelegate(); this.sslDelegate = new SSLDelegate(adel.engine, delegate.channel(), client, adel.serverName); this.alpn = adel.alpn; this.serverName = adel.serverName; diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java index fcd71728b5b..d5cade109b7 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java @@ -85,6 +85,19 @@ class SSLTunnelConnection extends HttpConnection { delegate = new PlainTunnelingConnection(addr, proxy, client); } + /** + * Create an SSLTunnelConnection from an existing connected AsyncSSLTunnelConnection. + * Used when downgrading from HTTP/2 to HTTP/1.1 + */ + SSLTunnelConnection(AsyncSSLTunnelConnection c) { + super(c.address, c.client); + this.delegate = c.plainConnection(); + AsyncSSLDelegate adel = c.sslDelegate(); + this.sslDelegate = new SSLDelegate(adel.engine, delegate.channel(), client, adel.serverName); + this.serverName = adel.serverName; + connected = c.connected(); + } + @Override SSLParameters sslParameters() { return sslDelegate.getSSLParameters(); diff --git a/jdk/test/java/net/httpclient/ProxyTest.java b/jdk/test/java/net/httpclient/ProxyTest.java index 8dc90dfb1a1..f6590d89f17 100644 --- a/jdk/test/java/net/httpclient/ProxyTest.java +++ b/jdk/test/java/net/httpclient/ProxyTest.java @@ -56,9 +56,12 @@ import jdk.testlibrary.SimpleSSLContext; /** * @test - * @bug 8185852 - * @summary verifies that passing a proxy with an unresolved address does - * not cause java.nio.channels.UnresolvedAddressException + * @bug 8185852 8181422 + * @summary Verifies that passing a proxy with an unresolved address does + * not cause java.nio.channels.UnresolvedAddressException. + * Verifies that downgrading from HTTP/2 to HTTP/1.1 works through + * an SSL Tunnel connection when the client is HTTP/2 and the server + * and proxy are HTTP/1.1 * @modules jdk.incubator.httpclient * @library /lib/testlibrary/ * @build jdk.testlibrary.SimpleSSLContext ProxyTest @@ -111,7 +114,7 @@ public class ProxyTest { server.start(); try { test(server, HttpClient.Version.HTTP_1_1); - // test(server, HttpClient.Version.HTTP_2); + test(server, HttpClient.Version.HTTP_2); } finally { server.stop(0); System.out.println("Server stopped"); diff --git a/jdk/test/java/net/httpclient/http2/ProxyTest2.java b/jdk/test/java/net/httpclient/http2/ProxyTest2.java new file mode 100644 index 00000000000..3a06bd304e1 --- /dev/null +++ b/jdk/test/java/net/httpclient/http2/ProxyTest2.java @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; +import com.sun.net.httpserver.HttpsServer; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Writer; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import jdk.incubator.http.HttpClient; +import jdk.incubator.http.HttpRequest; +import jdk.incubator.http.HttpResponse; +import jdk.testlibrary.SimpleSSLContext; +import java.util.concurrent.*; + +/** + * @test + * @bug 8181422 + * @summary Verifies that you can access an HTTP/2 server over HTTPS by + * tunnelling through an HTTP/1.1 proxy. + * @modules jdk.incubator.httpclient + * @library /lib/testlibrary server + * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common + * jdk.incubator.httpclient/jdk.incubator.http.internal.frame + * jdk.incubator.httpclient/jdk.incubator.http.internal.hpack + * @build jdk.testlibrary.SimpleSSLContext ProxyTest2 + * @run main/othervm ProxyTest2 + * @author danielfuchs + */ +public class ProxyTest2 { + + static { + try { + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + SSLContext.setDefault(new SimpleSSLContext().get()); + } catch (IOException ex) { + throw new ExceptionInInitializerError(ex); + } + } + + static final String RESPONSE = "

    Hello World!"; + static final String PATH = "/foo/"; + + static Http2TestServer createHttpsServer(ExecutorService exec) throws Exception { + Http2TestServer server = new Http2TestServer(true, 0, exec, SSLContext.getDefault()); + server.addHandler(new Http2Handler() { + @Override + public void handle(Http2TestExchange he) throws IOException { + he.getResponseHeaders().addHeader("encoding", "UTF-8"); + he.sendResponseHeaders(200, RESPONSE.length()); + he.getResponseBody().write(RESPONSE.getBytes(StandardCharsets.UTF_8)); + he.close(); + } + }, PATH); + + return server; + } + + public static void main(String[] args) + throws Exception + { + ExecutorService exec = Executors.newCachedThreadPool(); + Http2TestServer server = createHttpsServer(exec); + server.start(); + try { + // Http2TestServer over HTTPS does not support HTTP/1.1 + // => only test with a HTTP/2 client + test(server, HttpClient.Version.HTTP_2); + } finally { + server.stop(); + exec.shutdown(); + System.out.println("Server stopped"); + } + } + + public static void test(Http2TestServer server, HttpClient.Version version) + throws Exception + { + System.out.println("Server is: " + server.getAddress().toString()); + URI uri = new URI("https://localhost:" + server.getAddress().getPort() + PATH + "x"); + TunnelingProxy proxy = new TunnelingProxy(server); + proxy.start(); + try { + System.out.println("Proxy started"); + Proxy p = new Proxy(Proxy.Type.HTTP, + InetSocketAddress.createUnresolved("localhost", proxy.getAddress().getPort())); + System.out.println("Setting up request with HttpClient for version: " + + version.name() + "URI=" + uri); + ProxySelector ps = ProxySelector.of( + InetSocketAddress.createUnresolved("localhost", proxy.getAddress().getPort())); + HttpClient client = HttpClient.newBuilder() + .version(version) + .proxy(ps) + .build(); + HttpRequest request = HttpRequest.newBuilder() + .uri(uri) + .GET() + .build(); + + System.out.println("Sending request with HttpClient"); + HttpResponse response + = client.send(request, HttpResponse.BodyHandler.asString()); + System.out.println("Got response"); + String resp = response.body(); + System.out.println("Received: " + resp); + if (!RESPONSE.equals(resp)) { + throw new AssertionError("Unexpected response"); + } + } finally { + System.out.println("Stopping proxy"); + proxy.stop(); + System.out.println("Proxy stopped"); + } + } + + static class TunnelingProxy { + final Thread accept; + final ServerSocket ss; + final boolean DEBUG = false; + final Http2TestServer serverImpl; + TunnelingProxy(Http2TestServer serverImpl) throws IOException { + this.serverImpl = serverImpl; + ss = new ServerSocket(); + accept = new Thread(this::accept); + } + + void start() throws IOException { + ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + accept.start(); + } + + // Pipe the input stream to the output stream. + private synchronized Thread pipe(InputStream is, OutputStream os, char tag) { + return new Thread("TunnelPipe("+tag+")") { + @Override + public void run() { + try { + try { + int c; + while ((c = is.read()) != -1) { + os.write(c); + os.flush(); + // if DEBUG prints a + or a - for each transferred + // character. + if (DEBUG) System.out.print(tag); + } + is.close(); + } finally { + os.close(); + } + } catch (IOException ex) { + if (DEBUG) ex.printStackTrace(System.out); + } + } + }; + } + + public InetSocketAddress getAddress() { + return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort()); + } + + // This is a bit shaky. It doesn't handle continuation + // lines, but our client shouldn't send any. + // Read a line from the input stream, swallowing the final + // \r\n sequence. Stops at the first \n, doesn't complain + // if it wasn't preceded by '\r'. + // + String readLine(InputStream r) throws IOException { + StringBuilder b = new StringBuilder(); + int c; + while ((c = r.read()) != -1) { + if (c == '\n') break; + b.appendCodePoint(c); + } + if (b.codePointAt(b.length() -1) == '\r') { + b.delete(b.length() -1, b.length()); + } + return b.toString(); + } + + public void accept() { + Socket clientConnection = null; + try { + while (true) { + System.out.println("Tunnel: Waiting for client"); + Socket previous = clientConnection; + try { + clientConnection = ss.accept(); + } catch (IOException io) { + if (DEBUG) io.printStackTrace(System.out); + break; + } finally { + // we have only 1 client at a time, so it is safe + // to close the previous connection here + if (previous != null) previous.close(); + } + System.out.println("Tunnel: Client accepted"); + Socket targetConnection = null; + InputStream ccis = clientConnection.getInputStream(); + OutputStream ccos = clientConnection.getOutputStream(); + Writer w = new OutputStreamWriter(ccos, "UTF-8"); + PrintWriter pw = new PrintWriter(w); + System.out.println("Tunnel: Reading request line"); + String requestLine = readLine(ccis); + System.out.println("Tunnel: Request status line: " + requestLine); + if (requestLine.startsWith("CONNECT ")) { + // We should probably check that the next word following + // CONNECT is the host:port of our HTTPS serverImpl. + // Some improvement for a followup! + + // Read all headers until we find the empty line that + // signals the end of all headers. + while(!requestLine.equals("")) { + System.out.println("Tunnel: Reading header: " + + (requestLine = readLine(ccis))); + } + + // Open target connection + targetConnection = new Socket( + serverImpl.getAddress().getAddress(), + serverImpl.getAddress().getPort()); + + // Then send the 200 OK response to the client + System.out.println("Tunnel: Sending " + + "HTTP/1.1 200 OK\r\n\r\n"); + pw.print("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); + pw.flush(); + } else { + // This should not happen. + throw new IOException("Tunnel: Unexpected status line: " + + requestLine); + } + + // Pipe the input stream of the client connection to the + // output stream of the target connection and conversely. + // Now the client and target will just talk to each other. + System.out.println("Tunnel: Starting tunnel pipes"); + Thread t1 = pipe(ccis, targetConnection.getOutputStream(), '+'); + Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-'); + t1.start(); + t2.start(); + + // We have only 1 client... wait until it has finished before + // accepting a new connection request. + // System.out.println("Tunnel: Waiting for pipes to close"); + t1.join(); + t2.join(); + System.out.println("Tunnel: Done - waiting for next client"); + } + } catch (Throwable ex) { + try { + ss.close(); + } catch (IOException ex1) { + ex.addSuppressed(ex1); + } + ex.printStackTrace(System.err); + } + } + + void stop() throws IOException { + ss.close(); + } + + } + + static class Configurator extends HttpsConfigurator { + public Configurator(SSLContext ctx) { + super(ctx); + } + + @Override + public void configure (HttpsParameters params) { + params.setSSLParameters (getSSLContext().getSupportedSSLParameters()); + } + } + +} diff --git a/jdk/test/java/net/httpclient/http2/server/Http2TestServer.java b/jdk/test/java/net/httpclient/http2/server/Http2TestServer.java index 4a56e9beb4f..6889cf7aec8 100644 --- a/jdk/test/java/net/httpclient/http2/server/Http2TestServer.java +++ b/jdk/test/java/net/httpclient/http2/server/Http2TestServer.java @@ -201,7 +201,17 @@ public class Http2TestServer implements AutoCloseable { InetSocketAddress addr = (InetSocketAddress) socket.getRemoteSocketAddress(); Http2TestServerConnection c = new Http2TestServerConnection(this, socket); connections.put(addr, c); - c.run(); + try { + c.run(); + } catch(Throwable e) { + // we should not reach here, but if we do + // the connection might not have been closed + // and if so then the client might wait + // forever. + connections.remove(addr, c); + c.close(); + throw e; + } } } catch (Throwable e) { if (!stopping) { diff --git a/jdk/test/java/net/httpclient/http2/server/Http2TestServerConnection.java b/jdk/test/java/net/httpclient/http2/server/Http2TestServerConnection.java index 57698291ef1..5645c200692 100644 --- a/jdk/test/java/net/httpclient/http2/server/Http2TestServerConnection.java +++ b/jdk/test/java/net/httpclient/http2/server/Http2TestServerConnection.java @@ -133,10 +133,10 @@ public class Http2TestServerConnection { } void close() { + stopping = true; streams.forEach((i, q) -> { q.close(); }); - stopping = true; try { socket.close(); // TODO: put a reset on each stream @@ -557,7 +557,14 @@ public class Http2TestServerConnection { void writeLoop() { try { while (!stopping) { - Http2Frame frame = outputQ.take(); + Http2Frame frame; + try { + frame = outputQ.take(); + } catch(IOException x) { + if (stopping && x.getCause() instanceof InterruptedException) { + break; + } else throw x; + } if (frame instanceof ResponseHeaders) { ResponseHeaders rh = (ResponseHeaders)frame; HeadersFrame hf = new HeadersFrame(rh.streamid(), rh.getFlags(), encodeHeaders(rh.headers)); From b96bfedbdaa40fb7c42847f713d64c11d71569f1 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Wed, 16 Aug 2017 11:28:39 -0700 Subject: [PATCH 39/42] 8186208: closed/javax/xml/jaxp/transform/cr6657673/CR6657673Test.java: test result: Error. failed to clean up files after test Reviewed-by: dfuchs, lancea --- .../apache/bcel/internal/classfile/JavaClass.java | 2 +- .../xalan/internal/xsltc/compiler/XSLTC.java | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java index f9e1ac39eb2..fc35db70e25 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java @@ -279,7 +279,7 @@ public class JavaClass extends AccessFlags implements Cloneable, Node, Comparabl * @param file Output stream * @throws IOException */ - public void dump(final DataOutputStream file) throws IOException { + private void dump(final DataOutputStream file) throws IOException { file.writeInt(Const.JVM_CLASSFILE_MAGIC); file.writeShort(minor); file.writeShort(major); diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java index 25f5a495ff8..bc173a41861 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java @@ -102,7 +102,6 @@ public final class XSLTC { private ArrayList m_characterData; // These define the various methods for outputting the translet - public static final int FILE_OUTPUT = 0; public static final int JAR_OUTPUT = 1; public static final int BYTEARRAY_OUTPUT = 2; public static final int CLASSLOADER_OUTPUT = 3; @@ -116,7 +115,7 @@ public final class XSLTC { private String _className = null; // -o private String _packageName = "die.verwandlung"; // override with -p private File _destDir = null; // -d - private int _outputType = FILE_OUTPUT; // by default + private int _outputType = BYTEARRAY_OUTPUT; // by default private ArrayList _classes; private ArrayList _bcelClasses; @@ -897,8 +896,7 @@ public final class XSLTC { public void dumpClass(JavaClass clazz) { - if (_outputType == FILE_OUTPUT || - _outputType == BYTEARRAY_AND_FILE_OUTPUT) + if (_outputType == BYTEARRAY_AND_FILE_OUTPUT) { File outFile = getOutputFile(clazz.getClassName()); String parentDir = outFile.getParent(); @@ -911,12 +909,6 @@ public final class XSLTC { try { switch (_outputType) { - case FILE_OUTPUT: - clazz.dump( - new BufferedOutputStream( - new FileOutputStream( - getOutputFile(clazz.getClassName())))); - break; case JAR_OUTPUT: _bcelClasses.add(clazz); break; @@ -929,8 +921,7 @@ public final class XSLTC { _classes.add(out); if (_outputType == BYTEARRAY_AND_FILE_OUTPUT) - clazz.dump(new BufferedOutputStream( - new FileOutputStream(getOutputFile(clazz.getClassName())))); + clazz.dump(getOutputFile(clazz.getClassName())); else if (_outputType == BYTEARRAY_AND_JAR_OUTPUT) _bcelClasses.add(clazz); From ce6e379b4ed1df135613f6da8e41ed582d5c1fad Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 16 Aug 2017 11:29:58 -0700 Subject: [PATCH 40/42] 8186259: IOExceptionIfEncodedURLTest.sh versus IOExceptionIfEncodedURLTest.java Reviewed-by: tbell --- .../IOExceptionIfEncodedURLTest.java | 11 ----------- .../IOExceptionIfEncodedURLTest.sh | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.java b/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.java index 0db61d6db50..fc3945a7827 100644 --- a/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.java +++ b/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.java @@ -21,17 +21,6 @@ * questions. */ -/** - * @test - * @key headful - * @bug 6193279 - * @summary REGRESSION: AppletViewer throws IOException when path is encoded URL - * @author Dmitry Cherepanov: area=appletviewer - * @run compile IOExceptionIfEncodedURLTest.java - * @run main IOExceptionIfEncodedURLTest - * @run shell IOExceptionIfEncodedURLTest.sh - */ - import java.applet.Applet; import sun.net.www.ParseUtil; import java.io.File; diff --git a/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh b/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh index 619b57e0632..ddc86922a83 100644 --- a/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh +++ b/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh @@ -25,7 +25,7 @@ # # @test IOExceptionIfEncodedURLTest.sh # @key headful -# @bug 6193279 6619458 8137087 +# @bug 6193279 6619458 8137087 8186259 # @summary REGRESSION: AppletViewer throws IOException when path is encoded URL # @author Dmitry Cherepanov: area=appletviewer # @modules java.base/sun.net.www From fd1b70775855a45486639ba19179a7a927ac24b3 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Wed, 16 Aug 2017 13:15:45 -0700 Subject: [PATCH 41/42] 8186227: jdk/nio/zipfs/ZeroDate.java fails on Windows with "IllegalArgumentException: Illegal character in opaque part at index 13" Reviewed-by: rriggs --- jdk/test/jdk/nio/zipfs/ZeroDate.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/test/jdk/nio/zipfs/ZeroDate.java b/jdk/test/jdk/nio/zipfs/ZeroDate.java index 1a65c9b39b6..f8624064783 100644 --- a/jdk/test/jdk/nio/zipfs/ZeroDate.java +++ b/jdk/test/jdk/nio/zipfs/ZeroDate.java @@ -44,7 +44,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /* @test - * @bug 8184940 + * @bug 8184940 8186227 * @summary JDK 9 rejects zip files where the modified day or month is 0 * @author Liam Miller-Cushon */ @@ -85,7 +85,7 @@ public class ZeroDate { try (OutputStream os = Files.newOutputStream(path)) { os.write(data); } - URI uri = URI.create("jar:file://" + path.toAbsolutePath()); + URI uri = URI.create("jar:" + path.toUri()); try (FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) { Path entry = fs.getPath("x"); Instant actualInstant = From f1c5dd9a930391c18abc1e270a773e585b1c88a8 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Wed, 16 Aug 2017 16:46:51 -0400 Subject: [PATCH 42/42] 8185346: Relax RMI Registry Serial Filter to allow arrays of any type Registry filter should allow arrays of any type Reviewed-by: dfuchs, smarks, coffeys --- .../classes/java/io/ObjectInputFilter.java | 38 +++++++++++++++++-- .../misc/JavaObjectInputFilterAccess.java | 38 +++++++++++++++++++ .../jdk/internal/misc/SharedSecrets.java | 13 +++++++ .../share/conf/security/java.security | 28 +++++++++++++- .../sun/rmi/registry/RegistryImpl.java | 21 ++++------ .../serialFilter/RegistryFilterTest.java | 18 +++------ 6 files changed, 124 insertions(+), 32 deletions(-) create mode 100644 jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputFilterAccess.java diff --git a/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java b/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java index 534e1b2b8de..a45b655f8e7 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java @@ -34,6 +34,7 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Function; +import jdk.internal.misc.SharedSecrets; /** * Filter classes, array lengths, and graph metrics during deserialization. @@ -265,6 +266,9 @@ public interface ObjectInputFilter { return null; }); configLog = (configuredFilter != null) ? System.getLogger("java.io.serialization") : null; + + // Setup shared secrets for RegistryImpl to use. + SharedSecrets.setJavaObjectInputFilterAccess(Config::createFilter2); } /** @@ -370,7 +374,20 @@ public interface ObjectInputFilter { */ public static ObjectInputFilter createFilter(String pattern) { Objects.requireNonNull(pattern, "pattern"); - return Global.createFilter(pattern); + return Global.createFilter(pattern, true); + } + + /** + * Returns an ObjectInputFilter from a string of patterns that + * checks only the length for arrays, not the component type. + * + * @param pattern the pattern string to parse; not null + * @return a filter to check a class being deserialized; + * {@code null} if no patterns + */ + static ObjectInputFilter createFilter2(String pattern) { + Objects.requireNonNull(pattern, "pattern"); + return Global.createFilter(pattern, false); } /** @@ -404,20 +421,26 @@ public interface ObjectInputFilter { * Maximum length of any array. */ private long maxArrayLength; + /** + * True to check the component type for arrays. + */ + private final boolean checkComponentType; /** * Returns an ObjectInputFilter from a string of patterns. * * @param pattern the pattern string to parse + * @param checkComponentType true if the filter should check + * the component type of arrays * @return a filter to check a class being deserialized; * {@code null} if no patterns * @throws IllegalArgumentException if the parameter is malformed * if the pattern is missing the name, the long value * is not a number or is negative. */ - static ObjectInputFilter createFilter(String pattern) { + static ObjectInputFilter createFilter(String pattern, boolean checkComponentType) { try { - return new Global(pattern); + return new Global(pattern, checkComponentType); } catch (UnsupportedOperationException uoe) { // no non-empty patterns return null; @@ -428,12 +451,15 @@ public interface ObjectInputFilter { * Construct a new filter from the pattern String. * * @param pattern a pattern string of filters + * @param checkComponentType true if the filter should check + * the component type of arrays * @throws IllegalArgumentException if the pattern is malformed * @throws UnsupportedOperationException if there are no non-empty patterns */ - private Global(String pattern) { + private Global(String pattern, boolean checkComponentType) { boolean hasLimits = false; this.pattern = pattern; + this.checkComponentType = checkComponentType; maxArrayLength = Long.MAX_VALUE; // Default values are unlimited maxDepth = Long.MAX_VALUE; @@ -595,6 +621,10 @@ public interface ObjectInputFilter { // array length is too big return Status.REJECTED; } + if (!checkComponentType) { + // As revised; do not check the component type for arrays + return Status.UNDECIDED; + } do { // Arrays are decided based on the component type clazz = clazz.getComponentType(); diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputFilterAccess.java b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputFilterAccess.java new file mode 100644 index 00000000000..5edb4c778e4 --- /dev/null +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputFilterAccess.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 jdk.internal.misc; + +import java.io.ObjectInputFilter; + +/** + * Access to the alternative ObjectInputFilter.Config.createFilter2 for RMI. + */ +public interface JavaObjectInputFilterAccess { + /** + * Creates a filter from the pattern. + */ + ObjectInputFilter createFilter2(String pattern); +} diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java index cd54d422c21..0f60833ec78 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java @@ -25,6 +25,7 @@ package jdk.internal.misc; +import java.io.ObjectInputFilter; import java.lang.module.ModuleDescriptor; import java.util.ResourceBundle; import java.util.jar.JarFile; @@ -70,6 +71,7 @@ public class SharedSecrets { private static JavaAWTFontAccess javaAWTFontAccess; private static JavaBeansAccess javaBeansAccess; private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; + private static JavaObjectInputFilterAccess javaObjectInputFilterAccess; private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess; public static JavaUtilJarAccess javaUtilJarAccess() { @@ -315,6 +317,17 @@ public class SharedSecrets { javaObjectInputStreamAccess = access; } + public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() { + if (javaObjectInputFilterAccess == null) { + unsafe.ensureClassInitialized(ObjectInputFilter.Config.class); + } + return javaObjectInputFilterAccess; + } + + public static void setJavaObjectInputFilterAccess(JavaObjectInputFilterAccess access) { + javaObjectInputFilterAccess = access; + } + public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess jirafa) { javaIORandomAccessFileAccess = jirafa; } diff --git a/jdk/src/java.base/share/conf/security/java.security b/jdk/src/java.base/share/conf/security/java.security index 5ddf6198819..2ea7c3616d3 100644 --- a/jdk/src/java.base/share/conf/security/java.security +++ b/jdk/src/java.base/share/conf/security/java.security @@ -951,12 +951,36 @@ jdk.xml.dsig.secureValidationPolicy=\ # # The filter pattern uses the same format as jdk.serialFilter. # This filter can override the builtin filter if additional types need to be -# allowed or rejected from the RMI Registry. +# allowed or rejected from the RMI Registry or to decrease limits but not +# to increase limits. +# If the limits (maxdepth, maxrefs, or maxbytes) are exceeded, the object is rejected. +# +# Each non-array type is allowed or rejected if it matches one of the patterns, +# evaluated from left to right, and is otherwise allowed. Arrays of any +# component type, including subarrays and arrays of primitives, are allowed. +# +# Array construction of any component type, including subarrays and arrays of +# primitives, are allowed unless the length is greater than the maxarray limit. +# The filter is applied to each array element. # # Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # -#sun.rmi.registry.registryFilter=pattern;pattern +# The built-in filter allows subclasses of allowed classes and +# can approximately be represented as the pattern: +# +#sun.rmi.registry.registryFilter=\ +# maxarray=1000000;\ +# maxdepth=20;\ +# java.lang.String;\ +# java.lang.Number;\ +# java.lang.reflect.Proxy;\ +# java.rmi.Remote;\ +# sun.rmi.server.UnicastRef;\ +# sun.rmi.server.RMIClientSocketFactory;\ +# sun.rmi.server.RMIServerSocketFactory;\ +# java.rmi.activation.ActivationID;\ +# java.rmi.server.UID # # RMI Distributed Garbage Collector (DGC) Serial Filter # diff --git a/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java b/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java index af012faeb78..f6f486f80a5 100644 --- a/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java @@ -28,7 +28,6 @@ package sun.rmi.registry; import java.io.ObjectInputFilter; import java.nio.file.Path; import java.nio.file.Paths; -import java.rmi.server.LogStream; import java.security.PrivilegedAction; import java.security.Security; import java.util.ArrayList; @@ -58,6 +57,7 @@ import java.security.Permissions; import java.security.ProtectionDomain; import java.text.MessageFormat; +import jdk.internal.misc.SharedSecrets; import sun.rmi.runtime.Log; import sun.rmi.server.UnicastRef; import sun.rmi.server.UnicastServerRef; @@ -109,7 +109,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer private static final int REGISTRY_MAX_DEPTH = 20; /** Registry maximum array size in remote invocations. **/ - private static final int REGISTRY_MAX_ARRAY_SIZE = 10000; + private static final int REGISTRY_MAX_ARRAY_SIZE = 1_000_000; /** * The registryFilter created from the value of the {@code "sun.rmi.registry.registryFilter"} @@ -130,7 +130,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer props = Security.getProperty(REGISTRY_FILTER_PROPNAME); } if (props != null) { - filter = ObjectInputFilter.Config.createFilter(props); + filter = SharedSecrets.getJavaObjectInputFilterAccess().createFilter2(props); Log regLog = Log.getLog("sun.rmi.registry", "registry", -1); if (regLog.isLoggable(Log.BRIEF)) { regLog.log(Log.BRIEF, "registryFilter = " + filter); @@ -451,17 +451,10 @@ public class RegistryImpl extends java.rmi.server.RemoteServer Class clazz = filterInfo.serialClass(); if (clazz != null) { if (clazz.isArray()) { - if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE) { - return ObjectInputFilter.Status.REJECTED; - } - do { - // Arrays are allowed depending on the component type - clazz = clazz.getComponentType(); - } while (clazz.isArray()); - } - if (clazz.isPrimitive()) { - // Arrays of primitives are allowed - return ObjectInputFilter.Status.ALLOWED; + // Arrays are REJECTED only if they exceed the limit + return (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE) + ? ObjectInputFilter.Status.REJECTED + : ObjectInputFilter.Status.UNDECIDED; } if (String.class == clazz || java.lang.Number.class.isAssignableFrom(clazz) diff --git a/jdk/test/java/rmi/registry/serialFilter/RegistryFilterTest.java b/jdk/test/java/rmi/registry/serialFilter/RegistryFilterTest.java index 2d5562fed61..33f5f5aada3 100644 --- a/jdk/test/java/rmi/registry/serialFilter/RegistryFilterTest.java +++ b/jdk/test/java/rmi/registry/serialFilter/RegistryFilterTest.java @@ -35,7 +35,6 @@ import java.security.Security; import java.util.Objects; import org.testng.Assert; -import org.testng.TestNG; import org.testng.annotations.BeforeSuite; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -65,21 +64,14 @@ public class RegistryFilterTest { static final int REGISTRY_MAX_DEPTH = 20; - static final int REGISTRY_MAX_ARRAY = 10000; + static final int REGISTRY_MAX_ARRAY = 1_000_000; static final String registryFilter = System.getProperty("sun.rmi.registry.registryFilter", Security.getProperty("sun.rmi.registry.registryFilter")); - @DataProvider(name = "bindAllowed") - static Object[][] bindAllowedObjects() { - Object[][] objects = { - }; - return objects; - } - /** - * Data RMI Regiry bind test. + * Data RMI Registry bind test. * - name * - Object * - true/false if object is blacklisted by a filter (implicit or explicit) @@ -90,9 +82,11 @@ public class RegistryFilterTest { Object[][] data = { { "byte[max]", new XX(new byte[REGISTRY_MAX_ARRAY]), false }, { "String", new XX("now is the time"), false}, - { "String[]", new XX(new String[3]), false}, - { "Long[4]", new XX(new Long[4]), registryFilter != null }, + { "String[3]", new XX(new String[3]), false}, + { "Long[4]", new XX(new Long[4]), false }, + { "Object[REGISTRY_MAX_ARRAY]", new XX(new Object[REGISTRY_MAX_ARRAY]), false }, { "rej-byte[toobig]", new XX(new byte[REGISTRY_MAX_ARRAY + 1]), true }, + { "rej-Object[toobig]", new XX(new Object[REGISTRY_MAX_ARRAY + 1]), true }, { "rej-MarshalledObject", createMarshalledObject(), true }, { "rej-RejectableClass", new RejectableClass(), registryFilter != null}, };