diff --git a/archetypes/jersey-quickstart-ejb/pom.xml b/archetypes/jersey-quickstart-ejb/pom.xml
index 8fb7510cc..125af7137 100644
--- a/archetypes/jersey-quickstart-ejb/pom.xml
+++ b/archetypes/jersey-quickstart-ejb/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.archetypesjersey-archetypes
- 1.18.1
+ 1.18.4-SNAPSHOT4.0.0
diff --git a/archetypes/jersey-quickstart-ejb/src/main/resources/archetype-resources/pom.xml b/archetypes/jersey-quickstart-ejb/src/main/resources/archetype-resources/pom.xml
index a6c2a70c4..c16119170 100644
--- a/archetypes/jersey-quickstart-ejb/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/jersey-quickstart-ejb/src/main/resources/archetype-resources/pom.xml
@@ -42,7 +42,7 @@
- 1.18.1
+ 1.18.4-SNAPSHOTgfv3ee6
diff --git a/archetypes/jersey-quickstart-grizzly/pom.xml b/archetypes/jersey-quickstart-grizzly/pom.xml
index b56bdbce4..20f8d2aff 100644
--- a/archetypes/jersey-quickstart-grizzly/pom.xml
+++ b/archetypes/jersey-quickstart-grizzly/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.archetypesjersey-archetypes
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-quickstart-grizzly4.0.0
diff --git a/archetypes/jersey-quickstart-grizzly/src/main/resources/archetype-resources/pom.xml b/archetypes/jersey-quickstart-grizzly/src/main/resources/archetype-resources/pom.xml
index 923b6b4cc..4df8c295d 100644
--- a/archetypes/jersey-quickstart-grizzly/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/jersey-quickstart-grizzly/src/main/resources/archetype-resources/pom.xml
@@ -87,6 +87,6 @@
- 1.18.1
+ 1.18.4-SNAPSHOT
diff --git a/archetypes/jersey-quickstart-grizzly2/pom.xml b/archetypes/jersey-quickstart-grizzly2/pom.xml
index 9d9480123..9ae7e1e82 100644
--- a/archetypes/jersey-quickstart-grizzly2/pom.xml
+++ b/archetypes/jersey-quickstart-grizzly2/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.archetypesjersey-archetypes
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-quickstart-grizzly24.0.0
diff --git a/archetypes/jersey-quickstart-grizzly2/src/main/resources/archetype-resources/pom.xml b/archetypes/jersey-quickstart-grizzly2/src/main/resources/archetype-resources/pom.xml
index f4f015e94..ffe14b10e 100644
--- a/archetypes/jersey-quickstart-grizzly2/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/jersey-quickstart-grizzly2/src/main/resources/archetype-resources/pom.xml
@@ -82,6 +82,6 @@
- 1.18.1
+ 1.18.4-SNAPSHOT
diff --git a/archetypes/jersey-quickstart-webapp/pom.xml b/archetypes/jersey-quickstart-webapp/pom.xml
index 025d5ca09..23edccf5a 100644
--- a/archetypes/jersey-quickstart-webapp/pom.xml
+++ b/archetypes/jersey-quickstart-webapp/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.archetypesjersey-archetypes
- 1.18.1
+ 1.18.4-SNAPSHOT4.0.0
diff --git a/archetypes/jersey-quickstart-webapp/src/main/resources/archetype-resources/pom.xml b/archetypes/jersey-quickstart-webapp/src/main/resources/archetype-resources/pom.xml
index 6a266b4a1..a79f7afa7 100644
--- a/archetypes/jersey-quickstart-webapp/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/jersey-quickstart-webapp/src/main/resources/archetype-resources/pom.xml
@@ -75,7 +75,7 @@
- 1.18.1
+ 1.18.4-SNAPSHOT3.1.1UTF-8
diff --git a/archetypes/pom.xml b/archetypes/pom.xml
index b37a30b97..503a2097e 100644
--- a/archetypes/pom.xml
+++ b/archetypes/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,11 +47,11 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.archetypes
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-archetypespomAll Jersey Archetypes
diff --git a/archive/pom.xml b/archive/pom.xml
index ba2cc143e..e4ca0285a 100644
--- a/archive/pom.xml
+++ b/archive/pom.xml
@@ -48,7 +48,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-archiveJersey archive for non-maven users
diff --git a/contribs/ant-wadl-task/pom.xml b/contribs/ant-wadl-task/pom.xml
index 605606840..8e3dd37b1 100644
--- a/contribs/ant-wadl-task/pom.xml
+++ b/contribs/ant-wadl-task/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTant-wadl-taskjar
diff --git a/contribs/bill-burke-book/ex03_1/pom.xml b/contribs/bill-burke-book/ex03_1/pom.xml
index b928eb23a..03ef03496 100644
--- a/contribs/bill-burke-book/ex03_1/pom.xml
+++ b/contribs/bill-burke-book/ex03_1/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex03_1war
diff --git a/contribs/bill-burke-book/ex04_1/pom.xml b/contribs/bill-burke-book/ex04_1/pom.xml
index 03e9db679..a43a227c6 100644
--- a/contribs/bill-burke-book/ex04_1/pom.xml
+++ b/contribs/bill-burke-book/ex04_1/pom.xml
@@ -20,7 +20,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTwarex04_1
diff --git a/contribs/bill-burke-book/ex04_2/pom.xml b/contribs/bill-burke-book/ex04_2/pom.xml
index 9f1ae68ae..0e6d65cc1 100644
--- a/contribs/bill-burke-book/ex04_2/pom.xml
+++ b/contribs/bill-burke-book/ex04_2/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex04_2war
diff --git a/contribs/bill-burke-book/ex04_3/pom.xml b/contribs/bill-burke-book/ex04_3/pom.xml
index 5bfaf0a5d..47eae009a 100644
--- a/contribs/bill-burke-book/ex04_3/pom.xml
+++ b/contribs/bill-burke-book/ex04_3/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex04_3war
diff --git a/contribs/bill-burke-book/ex05_1/pom.xml b/contribs/bill-burke-book/ex05_1/pom.xml
index 0a20b7a3c..4af89cda4 100644
--- a/contribs/bill-burke-book/ex05_1/pom.xml
+++ b/contribs/bill-burke-book/ex05_1/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex05_1war
diff --git a/contribs/bill-burke-book/ex05_2/pom.xml b/contribs/bill-burke-book/ex05_2/pom.xml
index 31269b250..6a17443a6 100644
--- a/contribs/bill-burke-book/ex05_2/pom.xml
+++ b/contribs/bill-burke-book/ex05_2/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex05_2war
diff --git a/contribs/bill-burke-book/ex06_1/pom.xml b/contribs/bill-burke-book/ex06_1/pom.xml
index 6e50dc2d7..59ae98ed1 100644
--- a/contribs/bill-burke-book/ex06_1/pom.xml
+++ b/contribs/bill-burke-book/ex06_1/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex06_1war
diff --git a/contribs/bill-burke-book/ex06_2/pom.xml b/contribs/bill-burke-book/ex06_2/pom.xml
index c98fd3fe9..66c662b65 100644
--- a/contribs/bill-burke-book/ex06_2/pom.xml
+++ b/contribs/bill-burke-book/ex06_2/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex06_2war
diff --git a/contribs/bill-burke-book/ex07_1/pom.xml b/contribs/bill-burke-book/ex07_1/pom.xml
index 1ff0329fd..ec283869a 100644
--- a/contribs/bill-burke-book/ex07_1/pom.xml
+++ b/contribs/bill-burke-book/ex07_1/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex07_1war
diff --git a/contribs/bill-burke-book/ex08_1/pom.xml b/contribs/bill-burke-book/ex08_1/pom.xml
index b579860c1..c0c872147 100644
--- a/contribs/bill-burke-book/ex08_1/pom.xml
+++ b/contribs/bill-burke-book/ex08_1/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex08_1war
diff --git a/contribs/bill-burke-book/ex08_2/pom.xml b/contribs/bill-burke-book/ex08_2/pom.xml
index 73c4df697..7947cf4f3 100644
--- a/contribs/bill-burke-book/ex08_2/pom.xml
+++ b/contribs/bill-burke-book/ex08_2/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex08_2war
diff --git a/contribs/bill-burke-book/ex09_1/pom.xml b/contribs/bill-burke-book/ex09_1/pom.xml
index 3fdfd7932..985daf3b8 100644
--- a/contribs/bill-burke-book/ex09_1/pom.xml
+++ b/contribs/bill-burke-book/ex09_1/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex09_1war
diff --git a/contribs/bill-burke-book/ex09_2/pom.xml b/contribs/bill-burke-book/ex09_2/pom.xml
index 48bb7cda0..0329e09aa 100644
--- a/contribs/bill-burke-book/ex09_2/pom.xml
+++ b/contribs/bill-burke-book/ex09_2/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex09_2war
diff --git a/contribs/bill-burke-book/ex10_1/pom.xml b/contribs/bill-burke-book/ex10_1/pom.xml
index 147ac4082..d8ed053cb 100644
--- a/contribs/bill-burke-book/ex10_1/pom.xml
+++ b/contribs/bill-burke-book/ex10_1/pom.xml
@@ -19,7 +19,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex10_1war
diff --git a/contribs/bill-burke-book/ex11_1/ear/pom.xml b/contribs/bill-burke-book/ex11_1/ear/pom.xml
index d8736ed6a..a0fb18de1 100644
--- a/contribs/bill-burke-book/ex11_1/ear/pom.xml
+++ b/contribs/bill-burke-book/ex11_1/ear/pom.xml
@@ -16,7 +16,7 @@
com.sun.jersey.contribs.bill-burke-bookex11_1_pom
- 1.18.1
+ 1.18.4-SNAPSHOT4.0.0ex11_1-ear
diff --git a/contribs/bill-burke-book/ex11_1/ejb/pom.xml b/contribs/bill-burke-book/ex11_1/ejb/pom.xml
index 15e0c2476..73369f6f5 100644
--- a/contribs/bill-burke-book/ex11_1/ejb/pom.xml
+++ b/contribs/bill-burke-book/ex11_1/ejb/pom.xml
@@ -18,7 +18,7 @@
com.sun.jersey.contribs.bill-burke-bookex11_1_pom
- 1.18.1
+ 1.18.4-SNAPSHOT4.0.0ex11_1
diff --git a/contribs/bill-burke-book/ex11_1/pom.xml b/contribs/bill-burke-book/ex11_1/pom.xml
index cd2a9499f..3e9f3b618 100644
--- a/contribs/bill-burke-book/ex11_1/pom.xml
+++ b/contribs/bill-burke-book/ex11_1/pom.xml
@@ -18,7 +18,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex11_1_pompom
diff --git a/contribs/bill-burke-book/ex11_1/war/pom.xml b/contribs/bill-burke-book/ex11_1/war/pom.xml
index 37d7790da..5998a26b7 100644
--- a/contribs/bill-burke-book/ex11_1/war/pom.xml
+++ b/contribs/bill-burke-book/ex11_1/war/pom.xml
@@ -16,7 +16,7 @@
com.sun.jersey.contribs.bill-burke-bookex11_1_pom
- 1.18.1
+ 1.18.4-SNAPSHOT4.0.0ex11_1-war
diff --git a/contribs/bill-burke-book/ex11_2/pom.xml b/contribs/bill-burke-book/ex11_2/pom.xml
index e316dc22d..1322be357 100644
--- a/contribs/bill-burke-book/ex11_2/pom.xml
+++ b/contribs/bill-burke-book/ex11_2/pom.xml
@@ -17,7 +17,7 @@
com.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTex11_2war
diff --git a/contribs/bill-burke-book/pom.xml b/contribs/bill-burke-book/pom.xml
index 202d010f7..b577149b8 100644
--- a/contribs/bill-burke-book/pom.xml
+++ b/contribs/bill-burke-book/pom.xml
@@ -18,12 +18,12 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.contribs.bill-burke-bookbill-burke-book-examples
- 1.18.1
+ 1.18.4-SNAPSHOTpom
diff --git a/contribs/jersey-apache-client/pom.xml b/contribs/jersey-apache-client/pom.xml
index 183b26bc1..89b564417 100644
--- a/contribs/jersey-apache-client/pom.xml
+++ b/contribs/jersey-apache-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-apache-clientjar
diff --git a/contribs/jersey-apache-client4/pom.xml b/contribs/jersey-apache-client4/pom.xml
index 8d50e180d..7abc441fa 100644
--- a/contribs/jersey-apache-client4/pom.xml
+++ b/contribs/jersey-apache-client4/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-apache-client4jar
diff --git a/contribs/jersey-atom-abdera/pom.xml b/contribs/jersey-atom-abdera/pom.xml
index afe6618c9..1ff626597 100644
--- a/contribs/jersey-atom-abdera/pom.xml
+++ b/contribs/jersey-atom-abdera/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -49,7 +49,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-atom-abdera
diff --git a/contribs/jersey-aws-client/pom.xml b/contribs/jersey-aws-client/pom.xml
index d8ddc023a..919952966 100644
--- a/contribs/jersey-aws-client/pom.xml
+++ b/contribs/jersey-aws-client/pom.xml
@@ -47,7 +47,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-aws-client
diff --git a/contribs/jersey-freemarker/pom.xml b/contribs/jersey-freemarker/pom.xml
index c8d51504c..2e8e28b7c 100644
--- a/contribs/jersey-freemarker/pom.xml
+++ b/contribs/jersey-freemarker/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
jersey-contribscom.sun.jersey.contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-freemarkerjar
diff --git a/contribs/jersey-guice/pom.xml b/contribs/jersey-guice/pom.xml
index 1508da423..d8b75899c 100644
--- a/contribs/jersey-guice/pom.xml
+++ b/contribs/jersey-guice/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -49,7 +49,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-guice
diff --git a/contribs/jersey-moxy/pom.xml b/contribs/jersey-moxy/pom.xml
index 9838a1b3b..ae93654fc 100644
--- a/contribs/jersey-moxy/pom.xml
+++ b/contribs/jersey-moxy/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
jersey-contribscom.sun.jersey.contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-moxyjar
diff --git a/contribs/jersey-multipart/pom.xml b/contribs/jersey-multipart/pom.xml
index 6af22b1ac..d30338314 100644
--- a/contribs/jersey-multipart/pom.xml
+++ b/contribs/jersey-multipart/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -49,7 +49,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-multipart
diff --git a/contribs/jersey-non-blocking-client/pom.xml b/contribs/jersey-non-blocking-client/pom.xml
index dfe0e8eb8..5d415d305 100644
--- a/contribs/jersey-non-blocking-client/pom.xml
+++ b/contribs/jersey-non-blocking-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
jersey-contribscom.sun.jersey.contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-non-blocking-clientjar
diff --git a/contribs/jersey-oauth/oauth-client/pom.xml b/contribs/jersey-oauth/oauth-client/pom.xml
index 9d7e718e3..83bdd05c1 100644
--- a/contribs/jersey-oauth/oauth-client/pom.xml
+++ b/contribs/jersey-oauth/oauth-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribs.jersey-oauthjersey-oauth
- 1.18.1
+ 1.18.4-SNAPSHOToauth-clientjar
diff --git a/contribs/jersey-oauth/oauth-server/pom.xml b/contribs/jersey-oauth/oauth-server/pom.xml
index 44162bc26..c56561753 100644
--- a/contribs/jersey-oauth/oauth-server/pom.xml
+++ b/contribs/jersey-oauth/oauth-server/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribs.jersey-oauthjersey-oauth
- 1.18.1
+ 1.18.4-SNAPSHOToauth-serverjar
diff --git a/contribs/jersey-oauth/oauth-signature/pom.xml b/contribs/jersey-oauth/oauth-signature/pom.xml
index d229b027e..d07fb418b 100644
--- a/contribs/jersey-oauth/oauth-signature/pom.xml
+++ b/contribs/jersey-oauth/oauth-signature/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribs.jersey-oauthjersey-oauth
- 1.18.1
+ 1.18.4-SNAPSHOToauth-signaturejar
diff --git a/contribs/jersey-oauth/oauth-tests/pom.xml b/contribs/jersey-oauth/oauth-tests/pom.xml
index 6cb16e8f1..fce303b3a 100644
--- a/contribs/jersey-oauth/oauth-tests/pom.xml
+++ b/contribs/jersey-oauth/oauth-tests/pom.xml
@@ -47,7 +47,7 @@
com.sun.jersey.contribs.jersey-oauthjersey-oauth
- 1.18.1
+ 1.18.4-SNAPSHOToauth-testspom
diff --git a/contribs/jersey-oauth/pom.xml b/contribs/jersey-oauth/pom.xml
index 6f050f06e..9428e157e 100644
--- a/contribs/jersey-oauth/pom.xml
+++ b/contribs/jersey-oauth/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.contribs.jersey-oauthjersey-oauth
diff --git a/contribs/jersey-simple-server/pom.xml b/contribs/jersey-simple-server/pom.xml
index ed0d91f5f..9971b78c3 100644
--- a/contribs/jersey-simple-server/pom.xml
+++ b/contribs/jersey-simple-server/pom.xml
@@ -1,171 +1,172 @@
-
-
-
- 4.0.0
-
- com.sun.jersey.contribs
- jersey-contribs
- 1.18.1
-
- jersey-simple-server
- jar
- jersey-simple-server
-
-
- org.simpleframework
- simple
- 5.0.4
-
-
- com.sun.xml.bind
- jaxb-impl
- test
-
-
- junit
- junit
- test
-
-
-
-
-
- release
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
-
-
- http://jsr311.java.net/nonav/releases/1.1
- http://jersey.java.net/nonav/apidocs/${project.version}/jersey/
-
- true
- com.sun.jersey.simple.impl
-
-
-
-
-
-
- cobertura
-
-
- cobertura
-
-
-
-
- com.sun.jersey
- jersey-servlet
- ${project.version}
- cobertura
-
-
- com.sun.jersey
- jersey-client
- ${project.version}
- test
- cobertura
-
-
-
-
- default
-
- true
-
-
-
- com.sun.jersey
- jersey-servlet
- ${project.version}
-
-
- com.sun.jersey
- jersey-client
- ${project.version}
- test
-
-
-
-
-
-
-
-
- ${basedir}/src/main/java
-
- META-INF/**/*
-
-
-
- ${basedir}/src/main/resources
- true
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
-
-
- attach-sources
- package
-
- jar
-
-
-
-
-
-
-
-
+
+
+
+
+ 4.0.0
+
+ com.sun.jersey.contribs
+ jersey-contribs
+ 1.18.4-SNAPSHOT
+
+ jersey-simple-server
+ jar
+ jersey-simple-server
+
+
+ org.simpleframework
+ simple
+ 5.0.4
+
+
+ com.sun.xml.bind
+ jaxb-impl
+ test
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+ release
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ http://jsr311.java.net/nonav/releases/1.1
+ http://jersey.java.net/nonav/apidocs/${project.version}/jersey/
+
+ true
+ com.sun.jersey.simple.impl
+
+
+
+
+
+
+ cobertura
+
+
+ cobertura
+
+
+
+
+ com.sun.jersey
+ jersey-servlet
+ ${project.version}
+ cobertura
+
+
+ com.sun.jersey
+ jersey-client
+ ${project.version}
+ test
+ cobertura
+
+
+
+
+ default
+
+ true
+
+
+
+ com.sun.jersey
+ jersey-servlet
+ ${project.version}
+
+
+ com.sun.jersey
+ jersey-client
+ ${project.version}
+ test
+
+
+
+
+
+
+
+
+ ${basedir}/src/main/java
+
+ META-INF/**/*
+
+
+
+ ${basedir}/src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+ package
+
+ jar
+
+
+
+
+
+
+
+
diff --git a/contribs/jersey-wadl-json-schema/pom.xml b/contribs/jersey-wadl-json-schema/pom.xml
index 2421c24ae..d5712dcd4 100644
--- a/contribs/jersey-wadl-json-schema/pom.xml
+++ b/contribs/jersey-wadl-json-schema/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-wadl-json-schema
diff --git a/contribs/maven-wadl-plugin/pom.xml b/contribs/maven-wadl-plugin/pom.xml
index 202423605..6ab78c695 100644
--- a/contribs/maven-wadl-plugin/pom.xml
+++ b/contribs/maven-wadl-plugin/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -45,7 +45,7 @@
jersey-contribscom.sun.jersey.contribs
- 1.18.1
+ 1.18.4-SNAPSHOT../pom.xml4.0.0
diff --git a/contribs/pom.xml b/contribs/pom.xml
index ec1c8e551..68d5d6bf2 100644
--- a/contribs/pom.xml
+++ b/contribs/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOT../pom.xmlcom.sun.jersey.contribs
diff --git a/contribs/scala/jersey-lift-test/pom.xml b/contribs/scala/jersey-lift-test/pom.xml
index 669bbc46f..f5c7f2e8d 100644
--- a/contribs/scala/jersey-lift-test/pom.xml
+++ b/contribs/scala/jersey-lift-test/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribsscala
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-lift-test
diff --git a/contribs/scala/jersey-lift/pom.xml b/contribs/scala/jersey-lift/pom.xml
index f307e5eb9..67041526d 100644
--- a/contribs/scala/jersey-lift/pom.xml
+++ b/contribs/scala/jersey-lift/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribsscala
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-lift
diff --git a/contribs/scala/jersey-scala/pom.xml b/contribs/scala/jersey-scala/pom.xml
index b00e3c9c4..18dbf0dd0 100644
--- a/contribs/scala/jersey-scala/pom.xml
+++ b/contribs/scala/jersey-scala/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.contribsscala
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-scala
diff --git a/contribs/scala/pom.xml b/contribs/scala/pom.xml
index d03c726a7..9f998c7d3 100644
--- a/contribs/scala/pom.xml
+++ b/contribs/scala/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -49,7 +49,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOTscala
diff --git a/contribs/spring/pom.xml b/contribs/spring/pom.xml
index 6026dfe5f..0b4bcd899 100644
--- a/contribs/spring/pom.xml
+++ b/contribs/spring/pom.xml
@@ -2,7 +2,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.contribsjersey-contribs
- 1.18.1
+ 1.18.4-SNAPSHOT../pom.xmljersey-spring
diff --git a/contribs/wadl-resourcedoc-doclet/pom.xml b/contribs/wadl-resourcedoc-doclet/pom.xml
index cb0a9a8f8..268e2942c 100644
--- a/contribs/wadl-resourcedoc-doclet/pom.xml
+++ b/contribs/wadl-resourcedoc-doclet/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -45,7 +45,7 @@
jersey-contribscom.sun.jersey.contribs
- 1.18.1
+ 1.18.4-SNAPSHOT../pom.xml4.0.0
diff --git a/experimental/hypermedia-action/hypermedia-action-client/pom.xml b/experimental/hypermedia-action/hypermedia-action-client/pom.xml
index 8e4853a4c..583cb70d5 100644
--- a/experimental/hypermedia-action/hypermedia-action-client/pom.xml
+++ b/experimental/hypermedia-action/hypermedia-action-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.experimental.hypermedia-actionhypermedia-action
- 1.18.1
+ 1.18.4-SNAPSHOThypermedia-action-clientjar
diff --git a/experimental/hypermedia-action/hypermedia-action-core/pom.xml b/experimental/hypermedia-action/hypermedia-action-core/pom.xml
index a860125fb..f360fa76d 100644
--- a/experimental/hypermedia-action/hypermedia-action-core/pom.xml
+++ b/experimental/hypermedia-action/hypermedia-action-core/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.experimental.hypermedia-actionhypermedia-action
- 1.18.1
+ 1.18.4-SNAPSHOThypermedia-action-corejar
diff --git a/experimental/hypermedia-action/hypermedia-action-sample/pom.xml b/experimental/hypermedia-action/hypermedia-action-sample/pom.xml
index c14affc59..3627215b7 100644
--- a/experimental/hypermedia-action/hypermedia-action-sample/pom.xml
+++ b/experimental/hypermedia-action/hypermedia-action-sample/pom.xml
@@ -2,7 +2,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.experimental.hypermedia-actionhypermedia-action
- 1.18.1
+ 1.18.4-SNAPSHOThypermedia-action-samplejar
@@ -156,9 +156,9 @@
- 1.18.1
+ 1.18.4-SNAPSHOT
- 1.18.1
+ 1.18.4-SNAPSHOTSample that shows the use of hypermedia annotations like @Action
available in Jersey.
diff --git a/experimental/hypermedia-action/hypermedia-action-server/pom.xml b/experimental/hypermedia-action/hypermedia-action-server/pom.xml
index 0dfe2cbf7..735675ad0 100644
--- a/experimental/hypermedia-action/hypermedia-action-server/pom.xml
+++ b/experimental/hypermedia-action/hypermedia-action-server/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.experimental.hypermedia-actionhypermedia-action
- 1.18.1
+ 1.18.4-SNAPSHOThypermedia-action-serverjar
diff --git a/experimental/hypermedia-action/pom.xml b/experimental/hypermedia-action/pom.xml
index fc319888f..830a7cb03 100644
--- a/experimental/hypermedia-action/pom.xml
+++ b/experimental/hypermedia-action/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.experimentaljersey-experimental
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.experimental.hypermedia-actionhypermedia-action
diff --git a/experimental/jersey-monitoring/pom.xml b/experimental/jersey-monitoring/pom.xml
index 84e8658ee..d837cb30a 100644
--- a/experimental/jersey-monitoring/pom.xml
+++ b/experimental/jersey-monitoring/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
jersey-experimentalcom.sun.jersey.experimental
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-monitoringjar
diff --git a/experimental/pom.xml b/experimental/pom.xml
index 7e294493f..4346f3a08 100644
--- a/experimental/pom.xml
+++ b/experimental/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOT../pom.xmlcom.sun.jersey.experimental
diff --git a/experimental/proxy-client/jersey-proxy-client/pom.xml b/experimental/proxy-client/jersey-proxy-client/pom.xml
index 17b5e9663..dd4ef3a06 100644
--- a/experimental/proxy-client/jersey-proxy-client/pom.xml
+++ b/experimental/proxy-client/jersey-proxy-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.experimental.proxy-clientproject
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-proxy-client
@@ -72,12 +72,12 @@
com.sun.jerseyjersey-client
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jerseyjersey-core
- 1.18.1
+ 1.18.4-SNAPSHOT
diff --git a/experimental/proxy-client/pom.xml b/experimental/proxy-client/pom.xml
index be15f6e63..135a1a8cb 100644
--- a/experimental/proxy-client/pom.xml
+++ b/experimental/proxy-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.experimentaljersey-experimental
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.experimental.proxy-clientproject
diff --git a/experimental/proxy-client/system-properties-example/pom.xml b/experimental/proxy-client/system-properties-example/pom.xml
index 838e627be..ee46efbe0 100644
--- a/experimental/proxy-client/system-properties-example/pom.xml
+++ b/experimental/proxy-client/system-properties-example/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.experimental.proxy-clientproject
- 1.18.1
+ 1.18.4-SNAPSHOTsystem-properties-example
diff --git a/experimental/view-client/jersey-view-client-samples/atompub-simple-view-client-sample/pom.xml b/experimental/view-client/jersey-view-client-samples/atompub-simple-view-client-sample/pom.xml
index 4c487c4b4..f4928bd4d 100644
--- a/experimental/view-client/jersey-view-client-samples/atompub-simple-view-client-sample/pom.xml
+++ b/experimental/view-client/jersey-view-client-samples/atompub-simple-view-client-sample/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.experimental.view-client.jersey-view-client-samplesjersey-view-client-samples
- 1.18.1
+ 1.18.4-SNAPSHOTatompub-simple-view-client-sampleAtomPub Simple View-Client - Jersey sample
diff --git a/experimental/view-client/jersey-view-client-samples/hypermedia-action-sample/pom.xml b/experimental/view-client/jersey-view-client-samples/hypermedia-action-sample/pom.xml
index 30173a339..90e221287 100644
--- a/experimental/view-client/jersey-view-client-samples/hypermedia-action-sample/pom.xml
+++ b/experimental/view-client/jersey-view-client-samples/hypermedia-action-sample/pom.xml
@@ -2,7 +2,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.experimental.view-client.jersey-view-client-samplesjersey-view-client-samples
- 1.18.1
+ 1.18.4-SNAPSHOThypermedia-action-samplejar
@@ -148,9 +148,9 @@
- 1.18.1
+ 1.18.4-SNAPSHOT
- 1.18.1
+ 1.18.4-SNAPSHOTSample that shows the use of hypermedia annotations like @Action
available in Jersey.
diff --git a/experimental/view-client/jersey-view-client-samples/pom.xml b/experimental/view-client/jersey-view-client-samples/pom.xml
index 93f619b5b..cb1ad524a 100644
--- a/experimental/view-client/jersey-view-client-samples/pom.xml
+++ b/experimental/view-client/jersey-view-client-samples/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.experimental.view-clientview-client
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.experimental.view-client.jersey-view-client-samplesjersey-view-client-samples
diff --git a/experimental/view-client/jersey-view-client/pom.xml b/experimental/view-client/jersey-view-client/pom.xml
index 90f35bcaa..a1bb9c55b 100644
--- a/experimental/view-client/jersey-view-client/pom.xml
+++ b/experimental/view-client/jersey-view-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.experimental.view-clientview-client
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-view-clientjar
diff --git a/experimental/view-client/pom.xml b/experimental/view-client/pom.xml
index 7f6b83669..fe6004e7f 100644
--- a/experimental/view-client/pom.xml
+++ b/experimental/view-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.experimentaljersey-experimental
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.experimental.view-clientview-client
diff --git a/glassfish/pom.xml b/glassfish/pom.xml
index a097613f8..2b0c87d67 100644
--- a/glassfish/pom.xml
+++ b/glassfish/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTpom
diff --git a/glassfish/tests/jaxb22test/pom.xml b/glassfish/tests/jaxb22test/pom.xml
index 8d7e0c0f3..a27880eca 100644
--- a/glassfish/tests/jaxb22test/pom.xml
+++ b/glassfish/tests/jaxb22test/pom.xml
@@ -2,7 +2,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -113,7 +113,7 @@
- 1.18.1
+ 1.18.4-SNAPSHOT3.1.1
diff --git a/glassfish/v2-package/internal/pom.xml b/glassfish/v2-package/internal/pom.xml
index c80b76027..93a7c717a 100644
--- a/glassfish/v2-package/internal/pom.xml
+++ b/glassfish/v2-package/internal/pom.xml
@@ -48,7 +48,7 @@
com.sun.jersey.glassfish.v2glassfish-packages
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.glassfish.v2.internalmodule_jersey
diff --git a/glassfish/v2-package/main/pom.xml b/glassfish/v2-package/main/pom.xml
index 3d2f21095..c0eb91710 100644
--- a/glassfish/v2-package/main/pom.xml
+++ b/glassfish/v2-package/main/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.glassfish.v2glassfish-packages
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gfv2-packageJersey GFv2 UC Main Module
diff --git a/glassfish/v2-package/pom.xml b/glassfish/v2-package/pom.xml
index 9f4ebd109..a20a4fcc6 100644
--- a/glassfish/v2-package/pom.xml
+++ b/glassfish/v2-package/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jerseyglassfish
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.glassfish.v2glassfish-packages
diff --git a/glassfish/v3-packages/core/pom.xml b/glassfish/v3-packages/core/pom.xml
index a2be4c8b7..d1e4a0d9d 100644
--- a/glassfish/v3-packages/core/pom.xml
+++ b/glassfish/v3-packages/core/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
glassfish-packagescom.sun.jersey.glassfish.v3
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gfv3-coreJersey GFv3 UC Core Package Image
diff --git a/glassfish/v3-packages/core/src/main/resources/jersey-core_proto.py b/glassfish/v3-packages/core/src/main/resources/jersey-core_proto.py
index d5000f8cd..2e7adffb0 100644
--- a/glassfish/v3-packages/core/src/main/resources/jersey-core_proto.py
+++ b/glassfish/v3-packages/core/src/main/resources/jersey-core_proto.py
@@ -1,7 +1,6 @@
-#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#
-# Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
#
# The contents of this file are subject to the terms of either the GNU
# General Public License Version 2 only ("GPL") or the Common Development
@@ -38,9 +37,10 @@
# holder.
#
+
pkg = {
"name" : "jersey",
- "version" : "1.18,1-1.0",
+ "version" : "1.18,4-0.1",
"attributes" : { "pkg.summary" : "Jersey Core, RESTful Web services for GlassFish",
"pkg.description" :
"Jersey core runtime libraries including some 3rd party dependencies. \
diff --git a/glassfish/v3-packages/docs-and-samples/pom.xml b/glassfish/v3-packages/docs-and-samples/pom.xml
index b762a0b06..16ec51c7b 100644
--- a/glassfish/v3-packages/docs-and-samples/pom.xml
+++ b/glassfish/v3-packages/docs-and-samples/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
glassfish-packagescom.sun.jersey.glassfish.v3
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gfv3-docs-and-samplesJersey GFv3 UC Docs And Examples Package Image
diff --git a/glassfish/v3-packages/docs-and-samples/src/main/resources/jersey-docs-and-samples_proto.py b/glassfish/v3-packages/docs-and-samples/src/main/resources/jersey-docs-and-samples_proto.py
index d42542077..db9b8060d 100644
--- a/glassfish/v3-packages/docs-and-samples/src/main/resources/jersey-docs-and-samples_proto.py
+++ b/glassfish/v3-packages/docs-and-samples/src/main/resources/jersey-docs-and-samples_proto.py
@@ -1,7 +1,6 @@
-#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#
-# Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
#
# The contents of this file are subject to the terms of either the GNU
# General Public License Version 2 only ("GPL") or the Common Development
@@ -38,9 +37,10 @@
# holder.
#
+
pkg = {
"name" : "jersey-docs-and-examples",
- "version" : "1.18,1-1.0",
+ "version" : "1.18,4-0.1",
"attributes" : { "pkg.summary" : "Jersey Examples And Documentation, RESTful Web services for GlassFish",
"pkg.description" :
"This package contains Jersey API javadocs and examples. Once installed, \
@@ -53,7 +53,7 @@
"info.classification" : "Web Services" },
"dirtrees" : [ "glassfish" ],
"depends" : {
- "pkg:/jersey@1.18,1-1.0" : {"type" : "require" }
+ "pkg:/jersey@1.18,4-0.1" : {"type" : "require" }
},
"licenses" : { "glassfish/jersey/LICENSE.txt" : { "license" : "CDDL+GPL" }}
}
diff --git a/glassfish/v3-packages/osgi-modules/jersey-gf-server/pom.xml b/glassfish/v3-packages/osgi-modules/jersey-gf-server/pom.xml
index b11a15db3..f5607a504 100755
--- a/glassfish/v3-packages/osgi-modules/jersey-gf-server/pom.xml
+++ b/glassfish/v3-packages/osgi-modules/jersey-gf-server/pom.xml
@@ -48,7 +48,7 @@
com.sun.jersey.glassfish.v3.osgiosgi-modules
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gf-serverjar
diff --git a/glassfish/v3-packages/osgi-modules/jersey-gf-servlet/pom.xml b/glassfish/v3-packages/osgi-modules/jersey-gf-servlet/pom.xml
index 7a31eed33..fdaad82ac 100755
--- a/glassfish/v3-packages/osgi-modules/jersey-gf-servlet/pom.xml
+++ b/glassfish/v3-packages/osgi-modules/jersey-gf-servlet/pom.xml
@@ -48,7 +48,7 @@
com.sun.jersey.glassfish.v3.osgiosgi-modules
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gf-servletjar
diff --git a/glassfish/v3-packages/osgi-modules/jersey-gf-statsproviders/pom.xml b/glassfish/v3-packages/osgi-modules/jersey-gf-statsproviders/pom.xml
index 11ec3ba74..1f0f35447 100644
--- a/glassfish/v3-packages/osgi-modules/jersey-gf-statsproviders/pom.xml
+++ b/glassfish/v3-packages/osgi-modules/jersey-gf-statsproviders/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.glassfish.v3.osgiosgi-modules
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gf-statsprovidersjar
diff --git a/glassfish/v3-packages/osgi-modules/pom.xml b/glassfish/v3-packages/osgi-modules/pom.xml
index afa7d161b..d8a658906 100644
--- a/glassfish/v3-packages/osgi-modules/pom.xml
+++ b/glassfish/v3-packages/osgi-modules/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.glassfish.v3glassfish-packages
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.glassfish.v3.osgiosgi-modules
diff --git a/glassfish/v3-packages/pom.xml b/glassfish/v3-packages/pom.xml
index 7f28cf45d..91f41e781 100644
--- a/glassfish/v3-packages/pom.xml
+++ b/glassfish/v3-packages/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jerseyglassfish
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.glassfish.v3glassfish-packages
diff --git a/glassfish/v3.2-packages/core/pom.xml b/glassfish/v3.2-packages/core/pom.xml
index d3ad5094c..8ec4ab25c 100644
--- a/glassfish/v3.2-packages/core/pom.xml
+++ b/glassfish/v3.2-packages/core/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
glassfish-packagescom.sun.jersey.glassfish.v32
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gfv3-coreJersey GFv3.2 UC Core Package Image
diff --git a/glassfish/v3.2-packages/core/src/main/resources/jersey-core_proto.py b/glassfish/v3.2-packages/core/src/main/resources/jersey-core_proto.py
index d5000f8cd..2e7adffb0 100644
--- a/glassfish/v3.2-packages/core/src/main/resources/jersey-core_proto.py
+++ b/glassfish/v3.2-packages/core/src/main/resources/jersey-core_proto.py
@@ -1,7 +1,6 @@
-#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#
-# Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
#
# The contents of this file are subject to the terms of either the GNU
# General Public License Version 2 only ("GPL") or the Common Development
@@ -38,9 +37,10 @@
# holder.
#
+
pkg = {
"name" : "jersey",
- "version" : "1.18,1-1.0",
+ "version" : "1.18,4-0.1",
"attributes" : { "pkg.summary" : "Jersey Core, RESTful Web services for GlassFish",
"pkg.description" :
"Jersey core runtime libraries including some 3rd party dependencies. \
diff --git a/glassfish/v3.2-packages/docs-and-samples/pom.xml b/glassfish/v3.2-packages/docs-and-samples/pom.xml
index 8745e1739..615c6ce93 100644
--- a/glassfish/v3.2-packages/docs-and-samples/pom.xml
+++ b/glassfish/v3.2-packages/docs-and-samples/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
glassfish-packagescom.sun.jersey.glassfish.v32
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gfv3-docs-and-samplesJersey GFv3.2 UC Docs And Examples Package Image
diff --git a/glassfish/v3.2-packages/docs-and-samples/src/main/resources/jersey-docs-and-samples_proto.py b/glassfish/v3.2-packages/docs-and-samples/src/main/resources/jersey-docs-and-samples_proto.py
index d42542077..db9b8060d 100644
--- a/glassfish/v3.2-packages/docs-and-samples/src/main/resources/jersey-docs-and-samples_proto.py
+++ b/glassfish/v3.2-packages/docs-and-samples/src/main/resources/jersey-docs-and-samples_proto.py
@@ -1,7 +1,6 @@
-#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#
-# Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
#
# The contents of this file are subject to the terms of either the GNU
# General Public License Version 2 only ("GPL") or the Common Development
@@ -38,9 +37,10 @@
# holder.
#
+
pkg = {
"name" : "jersey-docs-and-examples",
- "version" : "1.18,1-1.0",
+ "version" : "1.18,4-0.1",
"attributes" : { "pkg.summary" : "Jersey Examples And Documentation, RESTful Web services for GlassFish",
"pkg.description" :
"This package contains Jersey API javadocs and examples. Once installed, \
@@ -53,7 +53,7 @@
"info.classification" : "Web Services" },
"dirtrees" : [ "glassfish" ],
"depends" : {
- "pkg:/jersey@1.18,1-1.0" : {"type" : "require" }
+ "pkg:/jersey@1.18,4-0.1" : {"type" : "require" }
},
"licenses" : { "glassfish/jersey/LICENSE.txt" : { "license" : "CDDL+GPL" }}
}
diff --git a/glassfish/v3.2-packages/osgi-modules/jersey-gf-server/pom.xml b/glassfish/v3.2-packages/osgi-modules/jersey-gf-server/pom.xml
index aa7e938bd..2b0f9c635 100755
--- a/glassfish/v3.2-packages/osgi-modules/jersey-gf-server/pom.xml
+++ b/glassfish/v3.2-packages/osgi-modules/jersey-gf-server/pom.xml
@@ -48,7 +48,7 @@
com.sun.jersey.glassfish.v32.osgiosgi-modules
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gf-serverjar
diff --git a/glassfish/v3.2-packages/osgi-modules/jersey-gf-servlet/pom.xml b/glassfish/v3.2-packages/osgi-modules/jersey-gf-servlet/pom.xml
index d2dcde0fd..a13d1a9f2 100755
--- a/glassfish/v3.2-packages/osgi-modules/jersey-gf-servlet/pom.xml
+++ b/glassfish/v3.2-packages/osgi-modules/jersey-gf-servlet/pom.xml
@@ -47,7 +47,7 @@
com.sun.jersey.glassfish.v3.osgiosgi-modules
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gf-servletjar
diff --git a/glassfish/v3.2-packages/osgi-modules/jersey-gf-statsproviders/pom.xml b/glassfish/v3.2-packages/osgi-modules/jersey-gf-statsproviders/pom.xml
index 64cbd4cd8..263b660ae 100644
--- a/glassfish/v3.2-packages/osgi-modules/jersey-gf-statsproviders/pom.xml
+++ b/glassfish/v3.2-packages/osgi-modules/jersey-gf-statsproviders/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.glassfish.v32.osgiosgi-modules
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-gf-statsprovidersjar
diff --git a/glassfish/v3.2-packages/osgi-modules/pom.xml b/glassfish/v3.2-packages/osgi-modules/pom.xml
index 7ca8f9092..7f72df19d 100644
--- a/glassfish/v3.2-packages/osgi-modules/pom.xml
+++ b/glassfish/v3.2-packages/osgi-modules/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.glassfish.v32glassfish-packages
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.glassfish.v32.osgiosgi-modules
diff --git a/glassfish/v3.2-packages/pom.xml b/glassfish/v3.2-packages/pom.xml
index 12eaacf20..32dedf7d5 100644
--- a/glassfish/v3.2-packages/pom.xml
+++ b/glassfish/v3.2-packages/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jerseyglassfish
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.glassfish.v32glassfish-packages
diff --git a/jersey-atom/pom.xml b/jersey-atom/pom.xml
index a852e1f79..7914e9f6d 100644
--- a/jersey-atom/pom.xml
+++ b/jersey-atom/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-atomjar
diff --git a/jersey-bundle/pom.xml b/jersey-bundle/pom.xml
index 5e4828a9d..4afb755e3 100644
--- a/jersey-bundle/pom.xml
+++ b/jersey-bundle/pom.xml
@@ -47,7 +47,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-bundle
diff --git a/jersey-client/pom.xml b/jersey-client/pom.xml
index 067645cd2..b1bb9a619 100644
--- a/jersey-client/pom.xml
+++ b/jersey-client/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-clientjar
diff --git a/jersey-core/pom.xml b/jersey-core/pom.xml
index f5424abe8..2264a0c51 100644
--- a/jersey-core/pom.xml
+++ b/jersey-core/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-corejar
diff --git a/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCComponentProviderFactory.java b/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCComponentProviderFactory.java
index 321570dbd..4638450f8 100644
--- a/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCComponentProviderFactory.java
+++ b/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCComponentProviderFactory.java
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
@@ -58,7 +58,7 @@
* If the component is not supported then a null value may be returned and the
* runtime will manage the component.
*
- * Specializations of {@link IoCComponentProvider} must be returned by the
+ * Specializations of {@link IoCComponentProvider} must be returned by the
* getComponentProvider methods that declare the boundary of
* responsibility, between the runtime and the underlying IoC framework,
* for management of a component.
@@ -77,7 +77,7 @@
* component is fully managed by the runtime but when an instance is created
* the underlying IoC framework is deferred to for creating a proxy of the
* component instance.
- *
+ *
* @author Paul.Sandoz@Sun.Com
*/
public interface IoCComponentProviderFactory extends ComponentProviderFactory {
diff --git a/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCProviderFactory.java b/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCProviderFactory.java
index 4f648cccf..2e3336c5e 100644
--- a/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCProviderFactory.java
+++ b/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCProviderFactory.java
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
@@ -44,8 +44,12 @@
import com.sun.jersey.core.spi.component.ComponentProvider;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.core.spi.component.ProviderFactory;
+import com.sun.jersey.core.util.PriorityUtil;
import com.sun.jersey.spi.inject.InjectableProviderContext;
+
import java.lang.reflect.InvocationTargetException;
+
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
@@ -53,13 +57,29 @@
/**
* An extension of {@link ProviderFactory} that defers to an
* {@link IoCComponentProviderFactory}.
- *
- * @author Paul.Sandoz@Sun.Com
+ *
+ * All registered provider factory implementations are being polled
+ * so that a single {@link IoCComponentProvider} instance could be selected
+ * for each component.
+ *
+ * @author Paul Sandoz (paul.sandoz at oracle.com)
*/
public class IoCProviderFactory extends ProviderFactory {
+
+ /*
+ The following would be added to the class javadoc if the priority annotation
+ was part of public API:
+
+ Polling order is specified by priority value
+ set on individual provider factories. The factory that has the highest
+ priority value is polled first. Priority value is set using
+ {@link Priority} annotation.
+ */
private final List factories;
/**
+ * Create a new provider factory based
+ * on given context and factory.
*
* @param ipc the injectable provider context.
* @param icpf the IoC component provider factory.
@@ -71,6 +91,7 @@ public IoCProviderFactory(
}
/**
+ * Create a new provider factory based on given context and factories.
*
* @param ipc the injectable provider context.
* @param factories the list of IoC component provider factory.
@@ -79,7 +100,9 @@ public IoCProviderFactory(
InjectableProviderContext ipc,
List factories) {
super(ipc);
- this.factories = factories;
+ List myFactories = new ArrayList(factories);
+ Collections.sort(myFactories, PriorityUtil.INSTANCE_COMPARATOR);
+ this.factories = Collections.unmodifiableList(myFactories);
}
@Override
@@ -123,7 +146,7 @@ private static class InstantiatedSingleton implements ComponentProvider, Destroy
private final Object o;
private final IoCDestroyable destroyable;
-
+
private final ComponentDestructor cd;
InstantiatedSingleton(InjectableProviderContext ipc,
@@ -131,7 +154,7 @@ private static class InstantiatedSingleton implements ComponentProvider, Destroy
Class c) {
this.destroyable = (iicp instanceof IoCDestroyable)
? (IoCDestroyable) iicp : null;
-
+
o = iicp.getInstance();
this.cd = (destroyable == null) ? new ComponentDestructor(c) : null;
@@ -210,7 +233,7 @@ private static class ProxiedSingletonWrapper implements ComponentProvider, Destr
this.destroyable = (cp instanceof Destroyable)
? (Destroyable) cp : null;
-
+
Object o = cp.getInstance();
this.proxy = ipcp.proxy(o);
if (!this.proxy.getClass().isAssignableFrom(o.getClass()))
diff --git a/jersey-core/src/main/java/com/sun/jersey/core/util/Priority.java b/jersey-core/src/main/java/com/sun/jersey/core/util/Priority.java
new file mode 100644
index 000000000..49a0aa265
--- /dev/null
+++ b/jersey-core/src/main/java/com/sun/jersey/core/util/Priority.java
@@ -0,0 +1,68 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * http://glassfish.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package com.sun.jersey.core.util;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.TYPE;
+
+
+/**
+ * Priority annotation can be applied to provider classes
+ * to indicate in what order the providers should be polled.
+ * Concrete usage must be defined by individual provider specification.
+ *
+ * Introduced to help control component factory ordering.
+ *
+ * @author Jakub Podlesak (jakub.podlesak at oracle.com)
+ */
+@Target(value=TYPE)
+@Retention(value=RUNTIME)
+public @interface Priority {
+
+ /**
+ * The priority value.
+ *
+ * @return priority value to be used for annotated element.
+ */
+ public int value();
+}
\ No newline at end of file
diff --git a/jersey-core/src/main/java/com/sun/jersey/core/util/PriorityUtil.java b/jersey-core/src/main/java/com/sun/jersey/core/util/PriorityUtil.java
new file mode 100644
index 000000000..c29a9dd1f
--- /dev/null
+++ b/jersey-core/src/main/java/com/sun/jersey/core/util/PriorityUtil.java
@@ -0,0 +1,96 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * http://glassfish.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.jersey.core.util;
+
+import java.util.Comparator;
+
+/**
+ * Utility code for work with {@link Priority} annotated types.
+ *
+ * @author Jakub Podlesak (jakub.podlesak at oracle.com)
+ */
+public class PriorityUtil {
+
+ /**
+ * Default priority value for factory types that do not have
+ * their priority set explicitly using {@link Priority} annotation.
+ */
+ public static final int DEFAULT_PRIORITY = 100;
+
+ /**
+ * Convenience comparator instance.
+ */
+ public static final InstanceComparator INSTANCE_COMPARATOR = new InstanceComparator();
+
+ /**
+ * Comparator for instances of types annotated with Priority
+ * annotation.
+ */
+ public static final class InstanceComparator implements Comparator {
+
+ @Override
+ public int compare(Object o1, Object o2) {
+ return priorityOf(o2) - priorityOf(o1);
+ }
+
+ private int priorityOf(Object o) {
+ final Priority priorityAnnotation = o.getClass().getAnnotation(Priority.class);
+ return priorityAnnotation == null ? DEFAULT_PRIORITY : priorityAnnotation.value();
+ }
+ }
+
+ /**
+ * Comparator for types annotated with Priority
+ * annotation.
+ */
+ public static class TypeComparator implements Comparator> {
+
+ @Override
+ public int compare(Class> o1, Class> o2) {
+ return priorityOf(o2) - priorityOf(o1);
+ }
+
+ private int priorityOf(Class> o) {
+ final Priority priorityAnnotation = o.getAnnotation(Priority.class);
+ return priorityAnnotation == null ? DEFAULT_PRIORITY : priorityAnnotation.value();
+ }
+ }
+}
\ No newline at end of file
diff --git a/jersey-core/src/test/java/com/sun/jersey/core/util/PriorityTest.java b/jersey-core/src/test/java/com/sun/jersey/core/util/PriorityTest.java
new file mode 100644
index 000000000..8c81069a9
--- /dev/null
+++ b/jersey-core/src/test/java/com/sun/jersey/core/util/PriorityTest.java
@@ -0,0 +1,133 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * http://glassfish.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.jersey.core.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+/**
+ * Test priority annotation usage on types and instances.
+ *
+ * @author Jakub Podlesak (jakub.podlesak at oracle.com)
+ */
+public class PriorityTest {
+
+ public static final int D_MINUS_200 = PriorityUtil.DEFAULT_PRIORITY - 200;
+ public static final int D_PLUS_300 = PriorityUtil.DEFAULT_PRIORITY + 300;
+ public static final int D_PLUS_400 = PriorityUtil.DEFAULT_PRIORITY + 400;
+
+ public PriorityTest() {
+ }
+
+ public static interface Base {
+ int getPriority();
+ }
+
+ @Priority(D_MINUS_200)
+ public static class A implements Base {
+
+ @Override
+ public int getPriority() {
+ return D_MINUS_200;
+ }
+ }
+
+ public static class B implements Base {
+
+ @Override
+ public int getPriority() {
+ return PriorityUtil.DEFAULT_PRIORITY;
+ }
+ }
+
+ @Priority(D_PLUS_300)
+ public static class C implements Base {
+
+ @Override
+ public int getPriority() {
+ return D_PLUS_300;
+ }
+ }
+
+ @Priority(D_PLUS_400)
+ public static class D implements Base {
+
+ @Override
+ public int getPriority() {
+ return D_PLUS_400;
+ }
+ }
+
+ /**
+ * Test the priority comparator.
+ */
+ @Test
+ public void testOrdering() {
+
+ Base a = new A();
+ Base b = new B();
+ Base c = new C();
+ Base d = new D();
+
+ List l1 = new ArrayList();
+
+ l1.add(d);
+ l1.add(c);
+ l1.add(b);
+ l1.add(a);
+
+ for (int i=0; i<20; i++) {
+ Collections.shuffle(l1);
+ Collections.sort(l1, PriorityUtil.INSTANCE_COMPARATOR);
+ int p = Integer.MAX_VALUE;
+ for (Base e : l1) {
+ if (e.getPriority() > p) {
+ Assert.fail("Wrong order of list " + l1);
+ }
+ p = e.getPriority();
+ }
+ }
+ }
+}
diff --git a/jersey-documentation/pom.xml b/jersey-documentation/pom.xml
index 5925681e4..fe667b4fa 100644
--- a/jersey-documentation/pom.xml
+++ b/jersey-documentation/pom.xml
@@ -46,7 +46,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-documentationpom
diff --git a/jersey-fastinfoset/pom.xml b/jersey-fastinfoset/pom.xml
index d8e8590de..d3571258b 100644
--- a/jersey-fastinfoset/pom.xml
+++ b/jersey-fastinfoset/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-fastinfosetjar
diff --git a/jersey-grizzly/pom.xml b/jersey-grizzly/pom.xml
index 36c04f4c8..e003b0114 100644
--- a/jersey-grizzly/pom.xml
+++ b/jersey-grizzly/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-grizzlyjar
diff --git a/jersey-grizzly2-servlet/pom.xml b/jersey-grizzly2-servlet/pom.xml
index 0a37bece2..a3fad5aad 100644
--- a/jersey-grizzly2-servlet/pom.xml
+++ b/jersey-grizzly2-servlet/pom.xml
@@ -2,7 +2,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-grizzly2-servletjar
diff --git a/jersey-grizzly2/pom.xml b/jersey-grizzly2/pom.xml
index bdc91b8bc..770b101b6 100644
--- a/jersey-grizzly2/pom.xml
+++ b/jersey-grizzly2/pom.xml
@@ -2,7 +2,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-grizzly2jar
diff --git a/jersey-json/pom.xml b/jersey-json/pom.xml
index a46842a4c..fad21b0d0 100644
--- a/jersey-json/pom.xml
+++ b/jersey-json/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-jsonjar
diff --git a/jersey-server-linking/pom.xml b/jersey-server-linking/pom.xml
index 7865d18e9..15e109298 100644
--- a/jersey-server-linking/pom.xml
+++ b/jersey-server-linking/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-server-linkingjar
diff --git a/jersey-server/pom.xml b/jersey-server/pom.xml
index e8e9e8332..7a6fb7c59 100644
--- a/jersey-server/pom.xml
+++ b/jersey-server/pom.xml
@@ -47,7 +47,7 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-serverjar
diff --git a/jersey-server/src/main/java/com/sun/jersey/server/impl/component/IoCResourceFactory.java b/jersey-server/src/main/java/com/sun/jersey/server/impl/component/IoCResourceFactory.java
index ae82972cf..a52dcd8bb 100644
--- a/jersey-server/src/main/java/com/sun/jersey/server/impl/component/IoCResourceFactory.java
+++ b/jersey-server/src/main/java/com/sun/jersey/server/impl/component/IoCResourceFactory.java
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
@@ -48,25 +48,33 @@
import com.sun.jersey.core.spi.component.ioc.IoCManagedComponentProvider;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.core.spi.component.ioc.IoCFullyManagedComponentProvider;
+import com.sun.jersey.core.util.PriorityUtil;
import com.sun.jersey.server.impl.inject.ServerInjectableProviderContext;
import com.sun.jersey.server.spi.component.ResourceComponentInjector;
import com.sun.jersey.server.spi.component.ResourceComponentProvider;
import com.sun.jersey.server.spi.component.ResourceComponentProviderFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
+ * Factory for individual JAX-RS resources.
*
- * @author Paul.Sandoz@Sun.Com
+ * @author Paul Sandoz (paul.sandoz at oracle.com)
*/
public class IoCResourceFactory extends ResourceFactory {
+
private final List factories;
-
+
public IoCResourceFactory(
ResourceConfig config,
ServerInjectableProviderContext ipc,
List factories) {
super(config, ipc);
- this.factories = factories;
+ List myFactories = new ArrayList(factories);
+ Collections.sort(myFactories, PriorityUtil.INSTANCE_COMPARATOR);
+ this.factories = Collections.unmodifiableList(myFactories);
}
@Override
@@ -124,12 +132,12 @@ public Object getInstance() {
public void destroy() {
}
}
-
+
private static class PerRequestWrapper implements ResourceComponentProvider {
private final ServerInjectableProviderContext ipc;
private final IoCManagedComponentProvider imcp;
private ResourceComponentInjector rci;
-
+
PerRequestWrapper(ServerInjectableProviderContext ipc, IoCManagedComponentProvider imcp) {
this.ipc = ipc;
this.imcp = imcp;
diff --git a/jersey-server/src/main/java/com/sun/jersey/spi/scanning/AnnotationScannerListener.java b/jersey-server/src/main/java/com/sun/jersey/spi/scanning/AnnotationScannerListener.java
index 1488dc6fa..4025bb0a0 100644
--- a/jersey-server/src/main/java/com/sun/jersey/spi/scanning/AnnotationScannerListener.java
+++ b/jersey-server/src/main/java/com/sun/jersey/spi/scanning/AnnotationScannerListener.java
@@ -140,7 +140,7 @@ public void onProcess(String name, InputStream in) throws IOException {
//
- private final class AnnotatedClassVisitor implements ClassVisitor {
+ private final class AnnotatedClassVisitor extends ClassVisitor {
/**
* The name of the visited class.
@@ -155,6 +155,10 @@ private final class AnnotatedClassVisitor implements ClassVisitor {
*/
private boolean isAnnotated;
+ private AnnotatedClassVisitor() {
+ super(Opcodes.ASM5);
+ }
+
public void visit(int version, int access, String name,
String signature, String superName, String[] interfaces) {
className = name;
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationVisitor.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationVisitor.java
index f5aba82a2..30f9fe24b 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationVisitor.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationVisitor.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,68 +30,140 @@
package jersey.repackaged.org.objectweb.asm;
/**
- * A visitor to visit a Java annotation. The methods of this interface must be
- * called in the following order: (visit | visitEnum |
- * visitAnnotation | visitArray)* visitEnd.
- *
+ * A visitor to visit a Java annotation. The methods of this class must be
+ * called in the following order: ( visit | visitEnum |
+ * visitAnnotation | visitArray )* visitEnd.
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
-public interface AnnotationVisitor {
+public abstract class AnnotationVisitor {
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ protected final int api;
+
+ /**
+ * The annotation visitor to which this visitor must delegate method calls.
+ * May be null.
+ */
+ protected AnnotationVisitor av;
+
+ /**
+ * Constructs a new {@link AnnotationVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ public AnnotationVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link AnnotationVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * @param av
+ * the annotation visitor to which this visitor must delegate
+ * method calls. May be null.
+ */
+ public AnnotationVisitor(final int api, final AnnotationVisitor av) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ throw new IllegalArgumentException();
+ }
+ this.api = api;
+ this.av = av;
+ }
/**
* Visits a primitive value of the annotation.
- *
- * @param name the value name.
- * @param value the actual value, whose type must be {@link Byte},
- * {@link Boolean}, {@link Character}, {@link Short},
- * {@link Integer}, {@link Long}, {@link Float}, {@link Double},
- * {@link String} or {@link Type}. This value can also be an array
- * of byte, boolean, short, char, int, long, float or double values
- * (this is equivalent to using {@link #visitArray visitArray} and
- * visiting each array element in turn, but is more convenient).
+ *
+ * @param name
+ * the value name.
+ * @param value
+ * the actual value, whose type must be {@link Byte},
+ * {@link Boolean}, {@link Character}, {@link Short},
+ * {@link Integer} , {@link Long}, {@link Float}, {@link Double},
+ * {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+ * value can also be an array of byte, boolean, short, char, int,
+ * long, float or double values (this is equivalent to using
+ * {@link #visitArray visitArray} and visiting each array element
+ * in turn, but is more convenient).
*/
- void visit(String name, Object value);
+ public void visit(String name, Object value) {
+ if (av != null) {
+ av.visit(name, value);
+ }
+ }
/**
* Visits an enumeration value of the annotation.
- *
- * @param name the value name.
- * @param desc the class descriptor of the enumeration class.
- * @param value the actual enumeration value.
+ *
+ * @param name
+ * the value name.
+ * @param desc
+ * the class descriptor of the enumeration class.
+ * @param value
+ * the actual enumeration value.
*/
- void visitEnum(String name, String desc, String value);
+ public void visitEnum(String name, String desc, String value) {
+ if (av != null) {
+ av.visitEnum(name, desc, value);
+ }
+ }
/**
* Visits a nested annotation value of the annotation.
- *
- * @param name the value name.
- * @param desc the class descriptor of the nested annotation class.
+ *
+ * @param name
+ * the value name.
+ * @param desc
+ * the class descriptor of the nested annotation class.
* @return a visitor to visit the actual nested annotation value, or
- * null if this visitor is not interested in visiting
- * this nested annotation. The nested annotation value must be
- * fully visited before calling other methods on this annotation
+ * null if this visitor is not interested in visiting this
+ * nested annotation. The nested annotation value must be fully
+ * visited before calling other methods on this annotation
* visitor.
*/
- AnnotationVisitor visitAnnotation(String name, String desc);
+ public AnnotationVisitor visitAnnotation(String name, String desc) {
+ if (av != null) {
+ return av.visitAnnotation(name, desc);
+ }
+ return null;
+ }
/**
* Visits an array value of the annotation. Note that arrays of primitive
* types (such as byte, boolean, short, char, int, long, float or double)
* can be passed as value to {@link #visit visit}. This is what
* {@link ClassReader} does.
- *
- * @param name the value name.
+ *
+ * @param name
+ * the value name.
* @return a visitor to visit the actual array value elements, or
- * null if this visitor is not interested in visiting
- * these values. The 'name' parameters passed to the methods of this
+ * null if this visitor is not interested in visiting these
+ * values. The 'name' parameters passed to the methods of this
* visitor are ignored. All the array values must be visited
* before calling other methods on this annotation visitor.
*/
- AnnotationVisitor visitArray(String name);
+ public AnnotationVisitor visitArray(String name) {
+ if (av != null) {
+ return av.visitArray(name);
+ }
+ return null;
+ }
/**
* Visits the end of the annotation.
*/
- void visitEnd();
+ public void visitEnd() {
+ if (av != null) {
+ av.visitEnd();
+ }
+ }
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationWriter.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationWriter.java
index 56001dd32..f317837bd 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationWriter.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationWriter.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,11 +31,11 @@
/**
* An {@link AnnotationVisitor} that generates annotations in bytecode form.
- *
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
-final class AnnotationWriter implements AnnotationVisitor {
+final class AnnotationWriter extends AnnotationVisitor {
/**
* The class writer to which this annotation must be added.
@@ -89,21 +89,22 @@ final class AnnotationWriter implements AnnotationVisitor {
/**
* Constructs a new {@link AnnotationWriter}.
- *
- * @param cw the class writer to which this annotation must be added.
- * @param named true if values are named, false otherwise.
- * @param bv where the annotation values must be stored.
- * @param parent where the number of annotation values must be stored.
- * @param offset where in parent the number of annotation values must
- * be stored.
+ *
+ * @param cw
+ * the class writer to which this annotation must be added.
+ * @param named
+ * true if values are named, false otherwise.
+ * @param bv
+ * where the annotation values must be stored.
+ * @param parent
+ * where the number of annotation values must be stored.
+ * @param offset
+ * where in parent the number of annotation values must
+ * be stored.
*/
- AnnotationWriter(
- final ClassWriter cw,
- final boolean named,
- final ByteVector bv,
- final ByteVector parent,
- final int offset)
- {
+ AnnotationWriter(final ClassWriter cw, final boolean named,
+ final ByteVector bv, final ByteVector parent, final int offset) {
+ super(Opcodes.ASM5);
this.cw = cw;
this.named = named;
this.bv = bv;
@@ -112,9 +113,10 @@ final class AnnotationWriter implements AnnotationVisitor {
}
// ------------------------------------------------------------------------
- // Implementation of the AnnotationVisitor interface
+ // Implementation of the AnnotationVisitor abstract class
// ------------------------------------------------------------------------
+ @Override
public void visit(final String name, final Object value) {
++size;
if (named) {
@@ -187,11 +189,9 @@ public void visit(final String name, final Object value) {
}
}
- public void visitEnum(
- final String name,
- final String desc,
- final String value)
- {
+ @Override
+ public void visitEnum(final String name, final String desc,
+ final String value) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
@@ -199,10 +199,9 @@ public void visitEnum(
bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
}
- public AnnotationVisitor visitAnnotation(
- final String name,
- final String desc)
- {
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name,
+ final String desc) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
@@ -212,6 +211,7 @@ public AnnotationVisitor visitAnnotation(
return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
}
+ @Override
public AnnotationVisitor visitArray(final String name) {
++size;
if (named) {
@@ -222,6 +222,7 @@ public AnnotationVisitor visitArray(final String name) {
return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
}
+ @Override
public void visitEnd() {
if (parent != null) {
byte[] data = parent.data;
@@ -236,7 +237,7 @@ public void visitEnd() {
/**
* Returns the size of this annotation writer list.
- *
+ *
* @return the size of this annotation writer list.
*/
int getSize() {
@@ -252,8 +253,9 @@ int getSize() {
/**
* Puts the annotations of this annotation writer list into the given byte
* vector.
- *
- * @param out where the annotations must be put.
+ *
+ * @param out
+ * where the annotations must be put.
*/
void put(final ByteVector out) {
int n = 0;
@@ -279,16 +281,16 @@ void put(final ByteVector out) {
/**
* Puts the given annotation lists into the given byte vector.
- *
- * @param panns an array of annotation writer lists.
- * @param off index of the first annotation to be written.
- * @param out where the annotations must be put.
+ *
+ * @param panns
+ * an array of annotation writer lists.
+ * @param off
+ * index of the first annotation to be written.
+ * @param out
+ * where the annotations must be put.
*/
- static void put(
- final AnnotationWriter[] panns,
- final int off,
- final ByteVector out)
- {
+ static void put(final AnnotationWriter[] panns, final int off,
+ final ByteVector out) {
int size = 1 + 2 * (panns.length - off);
for (int i = off; i < panns.length; ++i) {
size += panns[i] == null ? 0 : panns[i].getSize();
@@ -313,4 +315,57 @@ static void put(
}
}
}
+
+ /**
+ * Puts the given type reference and type path into the given bytevector.
+ * LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported.
+ *
+ * @param typeRef
+ * a reference to the annotated type. See {@link TypeReference}.
+ * @param typePath
+ * the path to the annotated type argument, wildcard bound, array
+ * element type, or static inner type within 'typeRef'. May be
+ * null if the annotation targets 'typeRef' as a whole.
+ * @param out
+ * where the type reference and type path must be put.
+ */
+ static void putTarget(int typeRef, TypePath typePath, ByteVector out) {
+ switch (typeRef >>> 24) {
+ case 0x00: // CLASS_TYPE_PARAMETER
+ case 0x01: // METHOD_TYPE_PARAMETER
+ case 0x16: // METHOD_FORMAL_PARAMETER
+ out.putShort(typeRef >>> 16);
+ break;
+ case 0x13: // FIELD
+ case 0x14: // METHOD_RETURN
+ case 0x15: // METHOD_RECEIVER
+ out.putByte(typeRef >>> 24);
+ break;
+ case 0x47: // CAST
+ case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+ case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+ out.putInt(typeRef);
+ break;
+ // case 0x10: // CLASS_EXTENDS
+ // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+ // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+ // case 0x17: // THROWS
+ // case 0x42: // EXCEPTION_PARAMETER
+ // case 0x43: // INSTANCEOF
+ // case 0x44: // NEW
+ // case 0x45: // CONSTRUCTOR_REFERENCE
+ // case 0x46: // METHOD_REFERENCE
+ default:
+ out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8);
+ break;
+ }
+ if (typePath == null) {
+ out.putByte(0);
+ } else {
+ int length = typePath.b[typePath.offset] * 2 + 1;
+ out.putByteArray(typePath.b, typePath.offset, length);
+ }
+ }
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Attribute.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Attribute.java
index 930c925d0..be8851512 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Attribute.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Attribute.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
/**
* A non standard class, field, method or code attribute.
- *
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
@@ -54,8 +54,9 @@ public class Attribute {
/**
* Constructs a new empty attribute.
- *
- * @param type the type of the attribute.
+ *
+ * @param type
+ * the type of the attribute.
*/
protected Attribute(final String type) {
this.type = type;
@@ -64,7 +65,7 @@ protected Attribute(final String type) {
/**
* Returns true if this type of attribute is unknown. The default
* implementation of this method always returns true.
- *
+ *
* @return true if this type of attribute is unknown.
*/
public boolean isUnknown() {
@@ -73,7 +74,7 @@ public boolean isUnknown() {
/**
* Returns true if this type of attribute is a code attribute.
- *
+ *
* @return true if this type of attribute is a code attribute.
*/
public boolean isCodeAttribute() {
@@ -82,7 +83,7 @@ public boolean isCodeAttribute() {
/**
* Returns the labels corresponding to this attribute.
- *
+ *
* @return the labels corresponding to this attribute, or null if
* this attribute is not a code attribute that contains labels.
*/
@@ -91,39 +92,39 @@ protected Label[] getLabels() {
}
/**
- * Reads a {@link #type type} attribute. This method must return a new
- * {@link Attribute} object, of type {@link #type type}, corresponding to
- * the len bytes starting at the given offset, in the given class
- * reader.
- *
- * @param cr the class that contains the attribute to be read.
- * @param off index of the first byte of the attribute's content in {@link
- * ClassReader#b cr.b}. The 6 attribute header bytes, containing the
- * type and the length of the attribute, are not taken into account
- * here.
- * @param len the length of the attribute's content.
- * @param buf buffer to be used to call
- * {@link ClassReader#readUTF8 readUTF8},
- * {@link ClassReader#readClass(int,char[]) readClass} or
- * {@link ClassReader#readConst readConst}.
- * @param codeOff index of the first byte of code's attribute content in
- * {@link ClassReader#b cr.b}, or -1 if the attribute to be read is
- * not a code attribute. The 6 attribute header bytes, containing the
- * type and the length of the attribute, are not taken into account
- * here.
- * @param labels the labels of the method's code, or null if the
- * attribute to be read is not a code attribute.
+ * Reads a {@link #type type} attribute. This method must return a
+ * new {@link Attribute} object, of type {@link #type type},
+ * corresponding to the len bytes starting at the given offset, in
+ * the given class reader.
+ *
+ * @param cr
+ * the class that contains the attribute to be read.
+ * @param off
+ * index of the first byte of the attribute's content in
+ * {@link ClassReader#b cr.b}. The 6 attribute header bytes,
+ * containing the type and the length of the attribute, are not
+ * taken into account here.
+ * @param len
+ * the length of the attribute's content.
+ * @param buf
+ * buffer to be used to call {@link ClassReader#readUTF8
+ * readUTF8}, {@link ClassReader#readClass(int,char[]) readClass}
+ * or {@link ClassReader#readConst readConst}.
+ * @param codeOff
+ * index of the first byte of code's attribute content in
+ * {@link ClassReader#b cr.b}, or -1 if the attribute to be read
+ * is not a code attribute. The 6 attribute header bytes,
+ * containing the type and the length of the attribute, are not
+ * taken into account here.
+ * @param labels
+ * the labels of the method's code, or null if the
+ * attribute to be read is not a code attribute.
* @return a new {@link Attribute} object corresponding to the given
* bytes.
*/
- protected Attribute read(
- final ClassReader cr,
- final int off,
- final int len,
- final char[] buf,
- final int codeOff,
- final Label[] labels)
- {
+ protected Attribute read(final ClassReader cr, final int off,
+ final int len, final char[] buf, final int codeOff,
+ final Label[] labels) {
Attribute attr = new Attribute(type);
attr.value = new byte[len];
System.arraycopy(cr.b, off, attr.value, 0, len);
@@ -132,31 +133,31 @@ protected Attribute read(
/**
* Returns the byte array form of this attribute.
- *
- * @param cw the class to which this attribute must be added. This parameter
- * can be used to add to the constant pool of this class the items
- * that corresponds to this attribute.
- * @param code the bytecode of the method corresponding to this code
- * attribute, or null if this attribute is not a code
- * attributes.
- * @param len the length of the bytecode of the method corresponding to this
- * code attribute, or null if this attribute is not a code
- * attribute.
- * @param maxStack the maximum stack size of the method corresponding to
- * this code attribute, or -1 if this attribute is not a code
- * attribute.
- * @param maxLocals the maximum number of local variables of the method
- * corresponding to this code attribute, or -1 if this attribute is
- * not a code attribute.
+ *
+ * @param cw
+ * the class to which this attribute must be added. This
+ * parameter can be used to add to the constant pool of this
+ * class the items that corresponds to this attribute.
+ * @param code
+ * the bytecode of the method corresponding to this code
+ * attribute, or null if this attribute is not a code
+ * attributes.
+ * @param len
+ * the length of the bytecode of the method corresponding to this
+ * code attribute, or null if this attribute is not a
+ * code attribute.
+ * @param maxStack
+ * the maximum stack size of the method corresponding to this
+ * code attribute, or -1 if this attribute is not a code
+ * attribute.
+ * @param maxLocals
+ * the maximum number of local variables of the method
+ * corresponding to this code attribute, or -1 if this attribute
+ * is not a code attribute.
* @return the byte array form of this attribute.
*/
- protected ByteVector write(
- final ClassWriter cw,
- final byte[] code,
- final int len,
- final int maxStack,
- final int maxLocals)
- {
+ protected ByteVector write(final ClassWriter cw, final byte[] code,
+ final int len, final int maxStack, final int maxLocals) {
ByteVector v = new ByteVector();
v.data = value;
v.length = value.length;
@@ -165,7 +166,7 @@ protected ByteVector write(
/**
* Returns the length of the attribute list that begins with this attribute.
- *
+ *
* @return the length of the attribute list that begins with this attribute.
*/
final int getCount() {
@@ -180,31 +181,31 @@ final int getCount() {
/**
* Returns the size of all the attributes in this attribute list.
- *
- * @param cw the class writer to be used to convert the attributes into byte
- * arrays, with the {@link #write write} method.
- * @param code the bytecode of the method corresponding to these code
- * attributes, or null if these attributes are not code
- * attributes.
- * @param len the length of the bytecode of the method corresponding to
- * these code attributes, or null if these attributes are
- * not code attributes.
- * @param maxStack the maximum stack size of the method corresponding to
- * these code attributes, or -1 if these attributes are not code
- * attributes.
- * @param maxLocals the maximum number of local variables of the method
- * corresponding to these code attributes, or -1 if these attributes
- * are not code attributes.
+ *
+ * @param cw
+ * the class writer to be used to convert the attributes into
+ * byte arrays, with the {@link #write write} method.
+ * @param code
+ * the bytecode of the method corresponding to these code
+ * attributes, or null if these attributes are not code
+ * attributes.
+ * @param len
+ * the length of the bytecode of the method corresponding to
+ * these code attributes, or null if these attributes
+ * are not code attributes.
+ * @param maxStack
+ * the maximum stack size of the method corresponding to these
+ * code attributes, or -1 if these attributes are not code
+ * attributes.
+ * @param maxLocals
+ * the maximum number of local variables of the method
+ * corresponding to these code attributes, or -1 if these
+ * attributes are not code attributes.
* @return the size of all the attributes in this attribute list. This size
* includes the size of the attribute headers.
*/
- final int getSize(
- final ClassWriter cw,
- final byte[] code,
- final int len,
- final int maxStack,
- final int maxLocals)
- {
+ final int getSize(final ClassWriter cw, final byte[] code, final int len,
+ final int maxStack, final int maxLocals) {
Attribute attr = this;
int size = 0;
while (attr != null) {
@@ -218,31 +219,31 @@ final int getSize(
/**
* Writes all the attributes of this attribute list in the given byte
* vector.
- *
- * @param cw the class writer to be used to convert the attributes into byte
- * arrays, with the {@link #write write} method.
- * @param code the bytecode of the method corresponding to these code
- * attributes, or null if these attributes are not code
- * attributes.
- * @param len the length of the bytecode of the method corresponding to
- * these code attributes, or null if these attributes are
- * not code attributes.
- * @param maxStack the maximum stack size of the method corresponding to
- * these code attributes, or -1 if these attributes are not code
- * attributes.
- * @param maxLocals the maximum number of local variables of the method
- * corresponding to these code attributes, or -1 if these attributes
- * are not code attributes.
- * @param out where the attributes must be written.
+ *
+ * @param cw
+ * the class writer to be used to convert the attributes into
+ * byte arrays, with the {@link #write write} method.
+ * @param code
+ * the bytecode of the method corresponding to these code
+ * attributes, or null if these attributes are not code
+ * attributes.
+ * @param len
+ * the length of the bytecode of the method corresponding to
+ * these code attributes, or null if these attributes
+ * are not code attributes.
+ * @param maxStack
+ * the maximum stack size of the method corresponding to these
+ * code attributes, or -1 if these attributes are not code
+ * attributes.
+ * @param maxLocals
+ * the maximum number of local variables of the method
+ * corresponding to these code attributes, or -1 if these
+ * attributes are not code attributes.
+ * @param out
+ * where the attributes must be written.
*/
- final void put(
- final ClassWriter cw,
- final byte[] code,
- final int len,
- final int maxStack,
- final int maxLocals,
- final ByteVector out)
- {
+ final void put(final ClassWriter cw, final byte[] code, final int len,
+ final int maxStack, final int maxLocals, final ByteVector out) {
Attribute attr = this;
while (attr != null) {
ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ByteVector.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ByteVector.java
index 1c19e0273..e89a9404e 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ByteVector.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ByteVector.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
/**
* A dynamically extensible vector of bytes. This class is roughly equivalent to
* a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
- *
+ *
* @author Eric Bruneton
*/
public class ByteVector {
@@ -58,8 +58,9 @@ public ByteVector() {
/**
* Constructs a new {@link ByteVector ByteVector} with the given initial
* size.
- *
- * @param initialSize the initial size of the byte vector to be constructed.
+ *
+ * @param initialSize
+ * the initial size of the byte vector to be constructed.
*/
public ByteVector(final int initialSize) {
data = new byte[initialSize];
@@ -68,8 +69,9 @@ public ByteVector(final int initialSize) {
/**
* Puts a byte into this byte vector. The byte vector is automatically
* enlarged if necessary.
- *
- * @param b a byte.
+ *
+ * @param b
+ * a byte.
* @return this byte vector.
*/
public ByteVector putByte(final int b) {
@@ -85,9 +87,11 @@ public ByteVector putByte(final int b) {
/**
* Puts two bytes into this byte vector. The byte vector is automatically
* enlarged if necessary.
- *
- * @param b1 a byte.
- * @param b2 another byte.
+ *
+ * @param b1
+ * a byte.
+ * @param b2
+ * another byte.
* @return this byte vector.
*/
ByteVector put11(final int b1, final int b2) {
@@ -105,8 +109,9 @@ ByteVector put11(final int b1, final int b2) {
/**
* Puts a short into this byte vector. The byte vector is automatically
* enlarged if necessary.
- *
- * @param s a short.
+ *
+ * @param s
+ * a short.
* @return this byte vector.
*/
public ByteVector putShort(final int s) {
@@ -124,9 +129,11 @@ public ByteVector putShort(final int s) {
/**
* Puts a byte and a short into this byte vector. The byte vector is
* automatically enlarged if necessary.
- *
- * @param b a byte.
- * @param s a short.
+ *
+ * @param b
+ * a byte.
+ * @param s
+ * a short.
* @return this byte vector.
*/
ByteVector put12(final int b, final int s) {
@@ -145,8 +152,9 @@ ByteVector put12(final int b, final int s) {
/**
* Puts an int into this byte vector. The byte vector is automatically
* enlarged if necessary.
- *
- * @param i an int.
+ *
+ * @param i
+ * an int.
* @return this byte vector.
*/
public ByteVector putInt(final int i) {
@@ -166,8 +174,9 @@ public ByteVector putInt(final int i) {
/**
* Puts a long into this byte vector. The byte vector is automatically
* enlarged if necessary.
- *
- * @param l a long.
+ *
+ * @param l
+ * a long.
* @return this byte vector.
*/
public ByteVector putLong(final long l) {
@@ -193,16 +202,20 @@ public ByteVector putLong(final long l) {
/**
* Puts an UTF8 string into this byte vector. The byte vector is
* automatically enlarged if necessary.
- *
- * @param s a String.
+ *
+ * @param s
+ * a String whose UTF8 encoded length must be less than 65536.
* @return this byte vector.
*/
public ByteVector putUTF8(final String s) {
int charLength = s.length();
- if (length + 2 + charLength > data.length) {
- enlarge(2 + charLength);
+ if (charLength > 65535) {
+ throw new IllegalArgumentException();
}
int len = length;
+ if (len + 2 + charLength > data.length) {
+ enlarge(2 + charLength);
+ }
byte[] data = this.data;
// optimistic algorithm: instead of computing the byte length and then
// serializing the string (which requires two loops), we assume the byte
@@ -228,6 +241,9 @@ public ByteVector putUTF8(final String s) {
byteLength += 2;
}
}
+ if (byteLength > 65535) {
+ throw new IllegalArgumentException();
+ }
data[length] = (byte) (byteLength >>> 8);
data[length + 1] = (byte) byteLength;
if (length + 2 + byteLength > data.length) {
@@ -258,15 +274,17 @@ public ByteVector putUTF8(final String s) {
/**
* Puts an array of bytes into this byte vector. The byte vector is
* automatically enlarged if necessary.
- *
- * @param b an array of bytes. May be null to put len
- * null bytes into this byte vector.
- * @param off index of the fist byte of b that must be copied.
- * @param len number of bytes of b that must be copied.
+ *
+ * @param b
+ * an array of bytes. May be null to put len
+ * null bytes into this byte vector.
+ * @param off
+ * index of the fist byte of b that must be copied.
+ * @param len
+ * number of bytes of b that must be copied.
* @return this byte vector.
*/
- public ByteVector putByteArray(final byte[] b, final int off, final int len)
- {
+ public ByteVector putByteArray(final byte[] b, final int off, final int len) {
if (length + len > data.length) {
enlarge(len);
}
@@ -279,9 +297,10 @@ public ByteVector putByteArray(final byte[] b, final int off, final int len)
/**
* Enlarge this byte vector so that it can receive n more bytes.
- *
- * @param size number of additional bytes that this byte vector should be
- * able to receive.
+ *
+ * @param size
+ * number of additional bytes that this byte vector should be
+ * able to receive.
*/
private void enlarge(final int size) {
int length1 = 2 * data.length;
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
index 876876df6..6441fc3f0 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,15 +29,15 @@
*/
package jersey.repackaged.org.objectweb.asm;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
/**
* A Java class parser to make a {@link ClassVisitor} visit an existing class.
* This class parses a byte array conforming to the Java class file format and
* calls the appropriate visit methods of a given class visitor for each field,
* method and bytecode instruction encountered.
- *
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
@@ -112,9 +112,8 @@ public class ClassReader {
public final byte[] b;
/**
- * The start index of each constant pool item in {@link #b b}, plus one.
- * The one byte offset skips the constant pool item tag that indicates its
- * type.
+ * The start index of each constant pool item in {@link #b b}, plus one. The
+ * one byte offset skips the constant pool item tag that indicates its type.
*/
private final int[] items;
@@ -146,8 +145,9 @@ public class ClassReader {
/**
* Constructs a new {@link ClassReader} object.
- *
- * @param b the bytecode of the class to be read.
+ *
+ * @param b
+ * the bytecode of the class to be read.
*/
public ClassReader(final byte[] b) {
this(b, 0, b.length);
@@ -155,13 +155,20 @@ public ClassReader(final byte[] b) {
/**
* Constructs a new {@link ClassReader} object.
- *
- * @param b the bytecode of the class to be read.
- * @param off the start offset of the class data.
- * @param len the length of the class data.
+ *
+ * @param b
+ * the bytecode of the class to be read.
+ * @param off
+ * the start offset of the class data.
+ * @param len
+ * the length of the class data.
*/
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
+ // checks the class version
+ if (readShort(off + 6) > Opcodes.V1_8) {
+ throw new IllegalArgumentException();
+ }
// parses the constant pool
items = new int[readUnsignedShort(off + 8)];
int n = items.length;
@@ -172,30 +179,35 @@ public ClassReader(final byte[] b, final int off, final int len) {
items[i] = index + 1;
int size;
switch (b[index]) {
- case ClassWriter.FIELD:
- case ClassWriter.METH:
- case ClassWriter.IMETH:
- case ClassWriter.INT:
- case ClassWriter.FLOAT:
- case ClassWriter.NAME_TYPE:
- size = 5;
- break;
- case ClassWriter.LONG:
- case ClassWriter.DOUBLE:
- size = 9;
- ++i;
- break;
- case ClassWriter.UTF8:
- size = 3 + readUnsignedShort(index + 1);
- if (size > max) {
- max = size;
- }
- break;
- // case ClassWriter.CLASS:
- // case ClassWriter.STR:
- default:
- size = 3;
- break;
+ case ClassWriter.FIELD:
+ case ClassWriter.METH:
+ case ClassWriter.IMETH:
+ case ClassWriter.INT:
+ case ClassWriter.FLOAT:
+ case ClassWriter.NAME_TYPE:
+ case ClassWriter.INDY:
+ size = 5;
+ break;
+ case ClassWriter.LONG:
+ case ClassWriter.DOUBLE:
+ size = 9;
+ ++i;
+ break;
+ case ClassWriter.UTF8:
+ size = 3 + readUnsignedShort(index + 1);
+ if (size > max) {
+ max = size;
+ }
+ break;
+ case ClassWriter.HANDLE:
+ size = 4;
+ break;
+ // case ClassWriter.CLASS:
+ // case ClassWriter.STR:
+ // case ClassWriter.MTYPE
+ default:
+ size = 3;
+ break;
}
index += size;
}
@@ -208,9 +220,9 @@ public ClassReader(final byte[] b, final int off, final int len) {
* Returns the class's access flags (see {@link Opcodes}). This value may
* not reflect Deprecated and Synthetic flags when bytecode is before 1.5
* and those flags are represented by attributes.
- *
+ *
* @return the class access flags
- *
+ *
* @see ClassVisitor#visit(int, int, String, String, String, String[])
*/
public int getAccess() {
@@ -220,9 +232,9 @@ public int getAccess() {
/**
* Returns the internal name of the class (see
* {@link Type#getInternalName() getInternalName}).
- *
+ *
* @return the internal class name
- *
+ *
* @see ClassVisitor#visit(int, int, String, String, String, String[])
*/
public String getClassName() {
@@ -233,24 +245,23 @@ public String getClassName() {
* Returns the internal of name of the super class (see
* {@link Type#getInternalName() getInternalName}). For interfaces, the
* super class is {@link Object}.
- *
+ *
* @return the internal name of super class, or null for
* {@link Object} class.
- *
+ *
* @see ClassVisitor#visit(int, int, String, String, String, String[])
*/
public String getSuperName() {
- int n = items[readUnsignedShort(header + 4)];
- return n == 0 ? null : readUTF8(n, new char[maxStringLength]);
+ return readClass(header + 4, new char[maxStringLength]);
}
/**
* Returns the internal names of the class's interfaces (see
* {@link Type#getInternalName() getInternalName}).
- *
+ *
* @return the array of internal names for all implemented interfaces or
* null.
- *
+ *
* @see ClassVisitor#visit(int, int, String, String, String, String[])
*/
public String[] getInterfaces() {
@@ -270,8 +281,9 @@ public String[] getInterfaces() {
/**
* Copies the constant pool data into the given {@link ClassWriter}. Should
* be called before the {@link #accept(ClassVisitor,int)} method.
- *
- * @param classWriter the {@link ClassWriter} to copy constant pool into.
+ *
+ * @param classWriter
+ * the {@link ClassWriter} to copy constant pool into.
*/
void copyPool(final ClassWriter classWriter) {
char[] buf = new char[maxStringLength];
@@ -283,58 +295,63 @@ void copyPool(final ClassWriter classWriter) {
Item item = new Item(i);
int nameType;
switch (tag) {
- case ClassWriter.FIELD:
- case ClassWriter.METH:
- case ClassWriter.IMETH:
- nameType = items[readUnsignedShort(index + 2)];
- item.set(tag,
- readClass(index, buf),
- readUTF8(nameType, buf),
- readUTF8(nameType + 2, buf));
- break;
-
- case ClassWriter.INT:
- item.set(readInt(index));
- break;
-
- case ClassWriter.FLOAT:
- item.set(Float.intBitsToFloat(readInt(index)));
- break;
-
- case ClassWriter.NAME_TYPE:
- item.set(tag,
- readUTF8(index, buf),
- readUTF8(index + 2, buf),
- null);
- break;
-
- case ClassWriter.LONG:
- item.set(readLong(index));
- ++i;
- break;
-
- case ClassWriter.DOUBLE:
- item.set(Double.longBitsToDouble(readLong(index)));
- ++i;
- break;
-
- case ClassWriter.UTF8: {
- String s = strings[i];
- if (s == null) {
- index = items[i];
- s = strings[i] = readUTF(index + 2,
- readUnsignedShort(index),
- buf);
- }
- item.set(tag, s, null, null);
+ case ClassWriter.FIELD:
+ case ClassWriter.METH:
+ case ClassWriter.IMETH:
+ nameType = items[readUnsignedShort(index + 2)];
+ item.set(tag, readClass(index, buf), readUTF8(nameType, buf),
+ readUTF8(nameType + 2, buf));
+ break;
+ case ClassWriter.INT:
+ item.set(readInt(index));
+ break;
+ case ClassWriter.FLOAT:
+ item.set(Float.intBitsToFloat(readInt(index)));
+ break;
+ case ClassWriter.NAME_TYPE:
+ item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf),
+ null);
+ break;
+ case ClassWriter.LONG:
+ item.set(readLong(index));
+ ++i;
+ break;
+ case ClassWriter.DOUBLE:
+ item.set(Double.longBitsToDouble(readLong(index)));
+ ++i;
+ break;
+ case ClassWriter.UTF8: {
+ String s = strings[i];
+ if (s == null) {
+ index = items[i];
+ s = strings[i] = readUTF(index + 2,
+ readUnsignedShort(index), buf);
}
- break;
-
- // case ClassWriter.STR:
- // case ClassWriter.CLASS:
- default:
- item.set(tag, readUTF8(index, buf), null, null);
- break;
+ item.set(tag, s, null, null);
+ break;
+ }
+ case ClassWriter.HANDLE: {
+ int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
+ nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
+ item.set(ClassWriter.HANDLE_BASE + readByte(index),
+ readClass(fieldOrMethodRef, buf),
+ readUTF8(nameType, buf), readUTF8(nameType + 2, buf));
+ break;
+ }
+ case ClassWriter.INDY:
+ if (classWriter.bootstrapMethods == null) {
+ copyBootstrapMethods(classWriter, items2, buf);
+ }
+ nameType = items[readUnsignedShort(index + 2)];
+ item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf),
+ readUnsignedShort(index));
+ break;
+ // case ClassWriter.STR:
+ // case ClassWriter.CLASS:
+ // case ClassWriter.MTYPE
+ default:
+ item.set(tag, readUTF8(index, buf), null, null);
+ break;
}
int index2 = item.hashCode % items2.length;
@@ -349,55 +366,122 @@ void copyPool(final ClassWriter classWriter) {
classWriter.index = ll;
}
+ /**
+ * Copies the bootstrap method data into the given {@link ClassWriter}.
+ * Should be called before the {@link #accept(ClassVisitor,int)} method.
+ *
+ * @param classWriter
+ * the {@link ClassWriter} to copy bootstrap methods into.
+ */
+ private void copyBootstrapMethods(final ClassWriter classWriter,
+ final Item[] items, final char[] c) {
+ // finds the "BootstrapMethods" attribute
+ int u = getAttributes();
+ boolean found = false;
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
+ if ("BootstrapMethods".equals(attrName)) {
+ found = true;
+ break;
+ }
+ u += 6 + readInt(u + 4);
+ }
+ if (!found) {
+ return;
+ }
+ // copies the bootstrap methods in the class writer
+ int boostrapMethodCount = readUnsignedShort(u + 8);
+ for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) {
+ int position = v - u - 10;
+ int hashCode = readConst(readUnsignedShort(v), c).hashCode();
+ for (int k = readUnsignedShort(v + 2); k > 0; --k) {
+ hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode();
+ v += 2;
+ }
+ v += 4;
+ Item item = new Item(j);
+ item.set(position, hashCode & 0x7FFFFFFF);
+ int index = item.hashCode % items.length;
+ item.next = items[index];
+ items[index] = item;
+ }
+ int attrSize = readInt(u + 4);
+ ByteVector bootstrapMethods = new ByteVector(attrSize + 62);
+ bootstrapMethods.putByteArray(b, u + 10, attrSize - 2);
+ classWriter.bootstrapMethodsCount = boostrapMethodCount;
+ classWriter.bootstrapMethods = bootstrapMethods;
+ }
+
/**
* Constructs a new {@link ClassReader} object.
- *
- * @param is an input stream from which to read the class.
- * @throws IOException if a problem occurs during reading.
+ *
+ * @param is
+ * an input stream from which to read the class.
+ * @throws IOException
+ * if a problem occurs during reading.
*/
public ClassReader(final InputStream is) throws IOException {
- this(readClass(is));
+ this(readClass(is, false));
}
/**
* Constructs a new {@link ClassReader} object.
- *
- * @param name the fully qualified name of the class to be read.
- * @throws IOException if an exception occurs during reading.
+ *
+ * @param name
+ * the binary qualified name of the class to be read.
+ * @throws IOException
+ * if an exception occurs during reading.
*/
public ClassReader(final String name) throws IOException {
- this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
- + ".class"));
+ this(readClass(
+ ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
+ + ".class"), true));
}
/**
* Reads the bytecode of a class.
- *
- * @param is an input stream from which to read the class.
+ *
+ * @param is
+ * an input stream from which to read the class.
+ * @param close
+ * true to close the input stream after reading.
* @return the bytecode read from the given input stream.
- * @throws IOException if a problem occurs during reading.
+ * @throws IOException
+ * if a problem occurs during reading.
*/
- private static byte[] readClass(final InputStream is) throws IOException {
+ private static byte[] readClass(final InputStream is, boolean close)
+ throws IOException {
if (is == null) {
throw new IOException("Class not found");
}
- byte[] b = new byte[is.available()];
- int len = 0;
- while (true) {
- int n = is.read(b, len, b.length - len);
- if (n == -1) {
- if (len < b.length) {
- byte[] c = new byte[len];
+ try {
+ byte[] b = new byte[is.available()];
+ int len = 0;
+ while (true) {
+ int n = is.read(b, len, b.length - len);
+ if (n == -1) {
+ if (len < b.length) {
+ byte[] c = new byte[len];
+ System.arraycopy(b, 0, c, 0, len);
+ b = c;
+ }
+ return b;
+ }
+ len += n;
+ if (len == b.length) {
+ int last = is.read();
+ if (last < 0) {
+ return b;
+ }
+ byte[] c = new byte[b.length + 1000];
System.arraycopy(b, 0, c, 0, len);
+ c[len++] = (byte) last;
b = c;
}
- return b;
}
- len += n;
- if (len == b.length) {
- byte[] c = new byte[b.length + 1000];
- System.arraycopy(b, 0, c, 0, len);
- b = c;
+ } finally {
+ if (close) {
+ is.close();
}
}
}
@@ -407,14 +491,16 @@ private static byte[] readClass(final InputStream is) throws IOException {
// ------------------------------------------------------------------------
/**
- * Makes the given visitor visit the Java class of this {@link ClassReader}.
- * This class is the one specified in the constructor (see
+ * Makes the given visitor visit the Java class of this {@link ClassReader}
+ * . This class is the one specified in the constructor (see
* {@link #ClassReader(byte[]) ClassReader}).
- *
- * @param classVisitor the visitor that must visit this class.
- * @param flags option flags that can be used to modify the default behavior
- * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
- * {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
+ *
+ * @param classVisitor
+ * the visitor that must visit this class.
+ * @param flags
+ * option flags that can be used to modify the default behavior
+ * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
+ * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
*/
public void accept(final ClassVisitor classVisitor, final int flags) {
accept(classVisitor, new Attribute[0], flags);
@@ -424,1057 +510,1219 @@ public void accept(final ClassVisitor classVisitor, final int flags) {
* Makes the given visitor visit the Java class of this {@link ClassReader}.
* This class is the one specified in the constructor (see
* {@link #ClassReader(byte[]) ClassReader}).
- *
- * @param classVisitor the visitor that must visit this class.
- * @param attrs prototypes of the attributes that must be parsed during the
- * visit of the class. Any attribute whose type is not equal to the
- * type of one the prototypes will not be parsed: its byte array
- * value will be passed unchanged to the ClassWriter. This may
- * corrupt it if this value contains references to the constant pool,
- * or has syntactic or semantic links with a class element that has
- * been transformed by a class adapter between the reader and the
- * writer.
- * @param flags option flags that can be used to modify the default behavior
- * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
- * {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
+ *
+ * @param classVisitor
+ * the visitor that must visit this class.
+ * @param attrs
+ * prototypes of the attributes that must be parsed during the
+ * visit of the class. Any attribute whose type is not equal to
+ * the type of one the prototypes will not be parsed: its byte
+ * array value will be passed unchanged to the ClassWriter.
+ * This may corrupt it if this value contains references to
+ * the constant pool, or has syntactic or semantic links with a
+ * class element that has been transformed by a class adapter
+ * between the reader and the writer.
+ * @param flags
+ * option flags that can be used to modify the default behavior
+ * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
+ * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
*/
- public void accept(
- final ClassVisitor classVisitor,
- final Attribute[] attrs,
- final int flags)
- {
- byte[] b = this.b; // the bytecode array
+ public void accept(final ClassVisitor classVisitor,
+ final Attribute[] attrs, final int flags) {
+ int u = header; // current offset in the class file
char[] c = new char[maxStringLength]; // buffer used to read strings
- int i, j, k; // loop variables
- int u, v, w; // indexes in b
- Attribute attr;
-
- int access;
- String name;
- String desc;
- String attrName;
- String signature;
- int anns = 0;
- int ianns = 0;
- Attribute cattrs = null;
-
- // visits the header
- u = header;
- access = readUnsignedShort(u);
- name = readClass(u + 2, c);
- v = items[readUnsignedShort(u + 4)];
- String superClassName = v == 0 ? null : readUTF8(v, c);
- String[] implementedItfs = new String[readUnsignedShort(u + 6)];
- w = 0;
+
+ Context context = new Context();
+ context.attrs = attrs;
+ context.flags = flags;
+ context.buffer = c;
+
+ // reads the class declaration
+ int access = readUnsignedShort(u);
+ String name = readClass(u + 2, c);
+ String superClass = readClass(u + 4, c);
+ String[] interfaces = new String[readUnsignedShort(u + 6)];
u += 8;
- for (i = 0; i < implementedItfs.length; ++i) {
- implementedItfs[i] = readClass(u, c);
+ for (int i = 0; i < interfaces.length; ++i) {
+ interfaces[i] = readClass(u, c);
u += 2;
}
- boolean skipCode = (flags & SKIP_CODE) != 0;
- boolean skipDebug = (flags & SKIP_DEBUG) != 0;
- boolean unzip = (flags & EXPAND_FRAMES) != 0;
-
- // skips fields and methods
- v = u;
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- j = readUnsignedShort(v + 6);
- v += 8;
- for (; j > 0; --j) {
- v += 6 + readInt(v + 2);
- }
- }
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- j = readUnsignedShort(v + 6);
- v += 8;
- for (; j > 0; --j) {
- v += 6 + readInt(v + 2);
- }
- }
- // reads the class's attributes
- signature = null;
+ // reads the class attributes
+ String signature = null;
String sourceFile = null;
String sourceDebug = null;
String enclosingOwner = null;
String enclosingName = null;
String enclosingDesc = null;
-
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- attrName = readUTF8(v, c);
+ int anns = 0;
+ int ianns = 0;
+ int tanns = 0;
+ int itanns = 0;
+ int innerClasses = 0;
+ Attribute attributes = null;
+
+ u = getAttributes();
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
// tests are sorted in decreasing frequency order
// (based on frequencies observed on typical classes)
if ("SourceFile".equals(attrName)) {
- sourceFile = readUTF8(v + 6, c);
+ sourceFile = readUTF8(u + 8, c);
} else if ("InnerClasses".equals(attrName)) {
- w = v + 6;
+ innerClasses = u + 8;
} else if ("EnclosingMethod".equals(attrName)) {
- enclosingOwner = readClass(v + 6, c);
- int item = readUnsignedShort(v + 8);
+ enclosingOwner = readClass(u + 8, c);
+ int item = readUnsignedShort(u + 10);
if (item != 0) {
enclosingName = readUTF8(items[item], c);
enclosingDesc = readUTF8(items[item] + 2, c);
}
} else if (SIGNATURES && "Signature".equals(attrName)) {
- signature = readUTF8(v + 6, c);
- } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
- anns = v + 6;
+ signature = readUTF8(u + 8, c);
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleAnnotations".equals(attrName)) {
+ anns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ tanns = u + 8;
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
} else if ("Synthetic".equals(attrName)) {
- access |= Opcodes.ACC_SYNTHETIC;
+ access |= Opcodes.ACC_SYNTHETIC
+ | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
} else if ("SourceDebugExtension".equals(attrName)) {
- int len = readInt(v + 2);
- sourceDebug = readUTF(v + 6, len, new char[len]);
- } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
- ianns = v + 6;
+ int len = readInt(u + 4);
+ sourceDebug = readUTF(u + 8, len, new char[len]);
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ ianns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ itanns = u + 8;
+ } else if ("BootstrapMethods".equals(attrName)) {
+ int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
+ for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
+ bootstrapMethods[j] = v;
+ v += 2 + readUnsignedShort(v + 2) << 1;
+ }
+ context.bootstrapMethods = bootstrapMethods;
} else {
- attr = readAttribute(attrs,
- attrName,
- v + 6,
- readInt(v + 2),
- c,
- -1,
- null);
+ Attribute attr = readAttribute(attrs, attrName, u + 8,
+ readInt(u + 4), c, -1, null);
if (attr != null) {
- attr.next = cattrs;
- cattrs = attr;
+ attr.next = attributes;
+ attributes = attr;
}
}
- v += 6 + readInt(v + 2);
- }
- // calls the visit method
- classVisitor.visit(readInt(4),
- access,
- name,
- signature,
- superClassName,
- implementedItfs);
-
- // calls the visitSource method
- if (!skipDebug && (sourceFile != null || sourceDebug != null)) {
+ u += 6 + readInt(u + 4);
+ }
+
+ // visits the class declaration
+ classVisitor.visit(readInt(items[1] - 7), access, name, signature,
+ superClass, interfaces);
+
+ // visits the source and debug info
+ if ((flags & SKIP_DEBUG) == 0
+ && (sourceFile != null || sourceDebug != null)) {
classVisitor.visitSource(sourceFile, sourceDebug);
}
- // calls the visitOuterClass method
+ // visits the outer class
if (enclosingOwner != null) {
- classVisitor.visitOuterClass(enclosingOwner,
- enclosingName,
+ classVisitor.visitOuterClass(enclosingOwner, enclosingName,
enclosingDesc);
}
- // visits the class annotations
- if (ANNOTATIONS) {
- for (i = 1; i >= 0; --i) {
- v = i == 0 ? ianns : anns;
- if (v != 0) {
- j = readUnsignedShort(v);
- v += 2;
- for (; j > 0; --j) {
- v = readAnnotationValues(v + 2,
- c,
- true,
- classVisitor.visitAnnotation(readUTF8(v, c), i != 0));
- }
- }
+ // visits the class annotations and type annotations
+ if (ANNOTATIONS && anns != 0) {
+ for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ classVisitor.visitAnnotation(readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && ianns != 0) {
+ for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ classVisitor.visitAnnotation(readUTF8(v, c), false));
+ }
+ }
+ if (ANNOTATIONS && tanns != 0) {
+ for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ classVisitor.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && itanns != 0) {
+ for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ classVisitor.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), false));
}
}
- // visits the class attributes
- while (cattrs != null) {
- attr = cattrs.next;
- cattrs.next = null;
- classVisitor.visitAttribute(cattrs);
- cattrs = attr;
+ // visits the attributes
+ while (attributes != null) {
+ Attribute attr = attributes.next;
+ attributes.next = null;
+ classVisitor.visitAttribute(attributes);
+ attributes = attr;
}
- // calls the visitInnerClass method
- if (w != 0) {
- i = readUnsignedShort(w);
- w += 2;
- for (; i > 0; --i) {
- classVisitor.visitInnerClass(readUnsignedShort(w) == 0
- ? null
- : readClass(w, c), readUnsignedShort(w + 2) == 0
- ? null
- : readClass(w + 2, c), readUnsignedShort(w + 4) == 0
- ? null
- : readUTF8(w + 4, c), readUnsignedShort(w + 6));
- w += 8;
+ // visits the inner classes
+ if (innerClasses != 0) {
+ int v = innerClasses + 2;
+ for (int i = readUnsignedShort(innerClasses); i > 0; --i) {
+ classVisitor.visitInnerClass(readClass(v, c),
+ readClass(v + 2, c), readUTF8(v + 4, c),
+ readUnsignedShort(v + 6));
+ v += 8;
}
}
- // visits the fields
- i = readUnsignedShort(u);
+ // visits the fields and methods
+ u = header + 10 + 2 * interfaces.length;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ u = readField(classVisitor, context, u);
+ }
u += 2;
- for (; i > 0; --i) {
- access = readUnsignedShort(u);
- name = readUTF8(u + 2, c);
- desc = readUTF8(u + 4, c);
- // visits the field's attributes and looks for a ConstantValue
- // attribute
- int fieldValueItem = 0;
- signature = null;
- anns = 0;
- ianns = 0;
- cattrs = null;
-
- j = readUnsignedShort(u + 6);
- u += 8;
- for (; j > 0; --j) {
- attrName = readUTF8(u, c);
- // tests are sorted in decreasing frequency order
- // (based on frequencies observed on typical classes)
- if ("ConstantValue".equals(attrName)) {
- fieldValueItem = readUnsignedShort(u + 6);
- } else if (SIGNATURES && "Signature".equals(attrName)) {
- signature = readUTF8(u + 6, c);
- } else if ("Deprecated".equals(attrName)) {
- access |= Opcodes.ACC_DEPRECATED;
- } else if ("Synthetic".equals(attrName)) {
- access |= Opcodes.ACC_SYNTHETIC;
- } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
- anns = u + 6;
- } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
- ianns = u + 6;
- } else {
- attr = readAttribute(attrs,
- attrName,
- u + 6,
- readInt(u + 2),
- c,
- -1,
- null);
- if (attr != null) {
- attr.next = cattrs;
- cattrs = attr;
- }
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ u = readMethod(classVisitor, context, u);
+ }
+
+ // visits the end of the class
+ classVisitor.visitEnd();
+ }
+
+ /**
+ * Reads a field and makes the given visitor visit it.
+ *
+ * @param classVisitor
+ * the visitor that must visit the field.
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * the start offset of the field in the class file.
+ * @return the offset of the first byte following the field in the class.
+ */
+ private int readField(final ClassVisitor classVisitor,
+ final Context context, int u) {
+ // reads the field declaration
+ char[] c = context.buffer;
+ int access = readUnsignedShort(u);
+ String name = readUTF8(u + 2, c);
+ String desc = readUTF8(u + 4, c);
+ u += 6;
+
+ // reads the field attributes
+ String signature = null;
+ int anns = 0;
+ int ianns = 0;
+ int tanns = 0;
+ int itanns = 0;
+ Object value = null;
+ Attribute attributes = null;
+
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
+ // tests are sorted in decreasing frequency order
+ // (based on frequencies observed on typical classes)
+ if ("ConstantValue".equals(attrName)) {
+ int item = readUnsignedShort(u + 8);
+ value = item == 0 ? null : readConst(item, c);
+ } else if (SIGNATURES && "Signature".equals(attrName)) {
+ signature = readUTF8(u + 8, c);
+ } else if ("Deprecated".equals(attrName)) {
+ access |= Opcodes.ACC_DEPRECATED;
+ } else if ("Synthetic".equals(attrName)) {
+ access |= Opcodes.ACC_SYNTHETIC
+ | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleAnnotations".equals(attrName)) {
+ anns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ tanns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ ianns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ itanns = u + 8;
+ } else {
+ Attribute attr = readAttribute(context.attrs, attrName, u + 8,
+ readInt(u + 4), c, -1, null);
+ if (attr != null) {
+ attr.next = attributes;
+ attributes = attr;
}
- u += 6 + readInt(u + 2);
}
- // visits the field
- FieldVisitor fv = classVisitor.visitField(access,
- name,
- desc,
- signature,
- fieldValueItem == 0 ? null : readConst(fieldValueItem, c));
- // visits the field annotations and attributes
- if (fv != null) {
- if (ANNOTATIONS) {
- for (j = 1; j >= 0; --j) {
- v = j == 0 ? ianns : anns;
- if (v != 0) {
- k = readUnsignedShort(v);
- v += 2;
- for (; k > 0; --k) {
- v = readAnnotationValues(v + 2,
- c,
- true,
- fv.visitAnnotation(readUTF8(v, c), j != 0));
- }
- }
- }
- }
- while (cattrs != null) {
- attr = cattrs.next;
- cattrs.next = null;
- fv.visitAttribute(cattrs);
- cattrs = attr;
- }
- fv.visitEnd();
+ u += 6 + readInt(u + 4);
+ }
+ u += 2;
+
+ // visits the field declaration
+ FieldVisitor fv = classVisitor.visitField(access, name, desc,
+ signature, value);
+ if (fv == null) {
+ return u;
+ }
+
+ // visits the field annotations and type annotations
+ if (ANNOTATIONS && anns != 0) {
+ for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ fv.visitAnnotation(readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && ianns != 0) {
+ for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ fv.visitAnnotation(readUTF8(v, c), false));
+ }
+ }
+ if (ANNOTATIONS && tanns != 0) {
+ for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ fv.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && itanns != 0) {
+ for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ fv.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), false));
}
}
- // visits the methods
- i = readUnsignedShort(u);
- u += 2;
- for (; i > 0; --i) {
- int u0 = u + 6;
- access = readUnsignedShort(u);
- name = readUTF8(u + 2, c);
- desc = readUTF8(u + 4, c);
- signature = null;
- anns = 0;
- ianns = 0;
- int dann = 0;
- int mpanns = 0;
- int impanns = 0;
- cattrs = null;
- v = 0;
- w = 0;
-
- // looks for Code and Exceptions attributes
- j = readUnsignedShort(u + 6);
- u += 8;
- for (; j > 0; --j) {
- attrName = readUTF8(u, c);
- int attrSize = readInt(u + 2);
- u += 6;
- // tests are sorted in decreasing frequency order
- // (based on frequencies observed on typical classes)
- if ("Code".equals(attrName)) {
- if (!skipCode) {
- v = u;
- }
- } else if ("Exceptions".equals(attrName)) {
- w = u;
- } else if (SIGNATURES && "Signature".equals(attrName)) {
- signature = readUTF8(u, c);
- } else if ("Deprecated".equals(attrName)) {
- access |= Opcodes.ACC_DEPRECATED;
- } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
- anns = u;
- } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
- dann = u;
- } else if ("Synthetic".equals(attrName)) {
- access |= Opcodes.ACC_SYNTHETIC;
- } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
- ianns = u;
- } else if (ANNOTATIONS && "RuntimeVisibleParameterAnnotations".equals(attrName))
- {
- mpanns = u;
- } else if (ANNOTATIONS && "RuntimeInvisibleParameterAnnotations".equals(attrName))
- {
- impanns = u;
- } else {
- attr = readAttribute(attrs,
- attrName,
- u,
- attrSize,
- c,
- -1,
- null);
- if (attr != null) {
- attr.next = cattrs;
- cattrs = attr;
- }
+ // visits the field attributes
+ while (attributes != null) {
+ Attribute attr = attributes.next;
+ attributes.next = null;
+ fv.visitAttribute(attributes);
+ attributes = attr;
+ }
+
+ // visits the end of the field
+ fv.visitEnd();
+
+ return u;
+ }
+
+ /**
+ * Reads a method and makes the given visitor visit it.
+ *
+ * @param classVisitor
+ * the visitor that must visit the method.
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * the start offset of the method in the class file.
+ * @return the offset of the first byte following the method in the class.
+ */
+ private int readMethod(final ClassVisitor classVisitor,
+ final Context context, int u) {
+ // reads the method declaration
+ char[] c = context.buffer;
+ context.access = readUnsignedShort(u);
+ context.name = readUTF8(u + 2, c);
+ context.desc = readUTF8(u + 4, c);
+ u += 6;
+
+ // reads the method attributes
+ int code = 0;
+ int exception = 0;
+ String[] exceptions = null;
+ String signature = null;
+ int methodParameters = 0;
+ int anns = 0;
+ int ianns = 0;
+ int tanns = 0;
+ int itanns = 0;
+ int dann = 0;
+ int mpanns = 0;
+ int impanns = 0;
+ int firstAttribute = u;
+ Attribute attributes = null;
+
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
+ // tests are sorted in decreasing frequency order
+ // (based on frequencies observed on typical classes)
+ if ("Code".equals(attrName)) {
+ if ((context.flags & SKIP_CODE) == 0) {
+ code = u + 8;
}
- u += attrSize;
- }
- // reads declared exceptions
- String[] exceptions;
- if (w == 0) {
- exceptions = null;
+ } else if ("Exceptions".equals(attrName)) {
+ exceptions = new String[readUnsignedShort(u + 8)];
+ exception = u + 10;
+ for (int j = 0; j < exceptions.length; ++j) {
+ exceptions[j] = readClass(exception, c);
+ exception += 2;
+ }
+ } else if (SIGNATURES && "Signature".equals(attrName)) {
+ signature = readUTF8(u + 8, c);
+ } else if ("Deprecated".equals(attrName)) {
+ context.access |= Opcodes.ACC_DEPRECATED;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleAnnotations".equals(attrName)) {
+ anns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ tanns = u + 8;
+ } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+ dann = u + 8;
+ } else if ("Synthetic".equals(attrName)) {
+ context.access |= Opcodes.ACC_SYNTHETIC
+ | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ ianns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ itanns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+ mpanns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+ impanns = u + 8;
+ } else if ("MethodParameters".equals(attrName)) {
+ methodParameters = u + 8;
} else {
- exceptions = new String[readUnsignedShort(w)];
- w += 2;
- for (j = 0; j < exceptions.length; ++j) {
- exceptions[j] = readClass(w, c);
- w += 2;
+ Attribute attr = readAttribute(context.attrs, attrName, u + 8,
+ readInt(u + 4), c, -1, null);
+ if (attr != null) {
+ attr.next = attributes;
+ attributes = attr;
}
}
+ u += 6 + readInt(u + 4);
+ }
+ u += 2;
- // visits the method's code, if any
- MethodVisitor mv = classVisitor.visitMethod(access,
- name,
- desc,
- signature,
- exceptions);
+ // visits the method declaration
+ MethodVisitor mv = classVisitor.visitMethod(context.access,
+ context.name, context.desc, signature, exceptions);
+ if (mv == null) {
+ return u;
+ }
- if (mv != null) {
- /*
- * if the returned MethodVisitor is in fact a MethodWriter, it
- * means there is no method adapter between the reader and the
- * writer. If, in addition, the writer's constant pool was
- * copied from this reader (mw.cw.cr == this), and the signature
- * and exceptions of the method have not been changed, then it
- * is possible to skip all visit events and just copy the
- * original code of the method to the writer (the access, name
- * and descriptor can have been changed, this is not important
- * since they are not copied as is from the reader).
- */
- if (WRITER && mv instanceof MethodWriter) {
- MethodWriter mw = (MethodWriter) mv;
- if (mw.cw.cr == this) {
- if (signature == mw.signature) {
- boolean sameExceptions = false;
- if (exceptions == null) {
- sameExceptions = mw.exceptionCount == 0;
- } else {
- if (exceptions.length == mw.exceptionCount) {
- sameExceptions = true;
- for (j = exceptions.length - 1; j >= 0; --j)
- {
- w -= 2;
- if (mw.exceptions[j] != readUnsignedShort(w))
- {
- sameExceptions = false;
- break;
- }
- }
- }
- }
- if (sameExceptions) {
- /*
- * we do not copy directly the code into
- * MethodWriter to save a byte array copy
- * operation. The real copy will be done in
- * ClassWriter.toByteArray().
- */
- mw.classReaderOffset = u0;
- mw.classReaderLength = u - u0;
- continue;
- }
+ /*
+ * if the returned MethodVisitor is in fact a MethodWriter, it means
+ * there is no method adapter between the reader and the writer. If, in
+ * addition, the writer's constant pool was copied from this reader
+ * (mw.cw.cr == this), and the signature and exceptions of the method
+ * have not been changed, then it is possible to skip all visit events
+ * and just copy the original code of the method to the writer (the
+ * access, name and descriptor can have been changed, this is not
+ * important since they are not copied as is from the reader).
+ */
+ if (WRITER && mv instanceof MethodWriter) {
+ MethodWriter mw = (MethodWriter) mv;
+ if (mw.cw.cr == this && signature == mw.signature) {
+ boolean sameExceptions = false;
+ if (exceptions == null) {
+ sameExceptions = mw.exceptionCount == 0;
+ } else if (exceptions.length == mw.exceptionCount) {
+ sameExceptions = true;
+ for (int j = exceptions.length - 1; j >= 0; --j) {
+ exception -= 2;
+ if (mw.exceptions[j] != readUnsignedShort(exception)) {
+ sameExceptions = false;
+ break;
}
}
}
-
- if (ANNOTATIONS && dann != 0) {
- AnnotationVisitor dv = mv.visitAnnotationDefault();
- readAnnotationValue(dann, c, null, dv);
- if (dv != null) {
- dv.visitEnd();
- }
- }
- if (ANNOTATIONS) {
- for (j = 1; j >= 0; --j) {
- w = j == 0 ? ianns : anns;
- if (w != 0) {
- k = readUnsignedShort(w);
- w += 2;
- for (; k > 0; --k) {
- w = readAnnotationValues(w + 2,
- c,
- true,
- mv.visitAnnotation(readUTF8(w, c), j != 0));
- }
- }
- }
+ if (sameExceptions) {
+ /*
+ * we do not copy directly the code into MethodWriter to
+ * save a byte array copy operation. The real copy will be
+ * done in ClassWriter.toByteArray().
+ */
+ mw.classReaderOffset = firstAttribute;
+ mw.classReaderLength = u - firstAttribute;
+ return u;
}
- if (ANNOTATIONS && mpanns != 0) {
- readParameterAnnotations(mpanns, desc, c, true, mv);
+ }
+ }
+
+ // visit the method parameters
+ if (methodParameters != 0) {
+ for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) {
+ mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2));
+ }
+ }
+
+ // visits the method annotations
+ if (ANNOTATIONS && dann != 0) {
+ AnnotationVisitor dv = mv.visitAnnotationDefault();
+ readAnnotationValue(dann, c, null, dv);
+ if (dv != null) {
+ dv.visitEnd();
+ }
+ }
+ if (ANNOTATIONS && anns != 0) {
+ for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitAnnotation(readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && ianns != 0) {
+ for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitAnnotation(readUTF8(v, c), false));
+ }
+ }
+ if (ANNOTATIONS && tanns != 0) {
+ for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && itanns != 0) {
+ for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), false));
+ }
+ }
+ if (ANNOTATIONS && mpanns != 0) {
+ readParameterAnnotations(mv, context, mpanns, true);
+ }
+ if (ANNOTATIONS && impanns != 0) {
+ readParameterAnnotations(mv, context, impanns, false);
+ }
+
+ // visits the method attributes
+ while (attributes != null) {
+ Attribute attr = attributes.next;
+ attributes.next = null;
+ mv.visitAttribute(attributes);
+ attributes = attr;
+ }
+
+ // visits the method code
+ if (code != 0) {
+ mv.visitCode();
+ readCode(mv, context, code);
+ }
+
+ // visits the end of the method
+ mv.visitEnd();
+
+ return u;
+ }
+
+ /**
+ * Reads the bytecode of a method and makes the given visitor visit it.
+ *
+ * @param mv
+ * the visitor that must visit the method's code.
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * the start offset of the code attribute in the class file.
+ */
+ private void readCode(final MethodVisitor mv, final Context context, int u) {
+ // reads the header
+ byte[] b = this.b;
+ char[] c = context.buffer;
+ int maxStack = readUnsignedShort(u);
+ int maxLocals = readUnsignedShort(u + 2);
+ int codeLength = readInt(u + 4);
+ u += 8;
+
+ // reads the bytecode to find the labels
+ int codeStart = u;
+ int codeEnd = u + codeLength;
+ Label[] labels = context.labels = new Label[codeLength + 2];
+ readLabel(codeLength + 1, labels);
+ while (u < codeEnd) {
+ int offset = u - codeStart;
+ int opcode = b[u] & 0xFF;
+ switch (ClassWriter.TYPE[opcode]) {
+ case ClassWriter.NOARG_INSN:
+ case ClassWriter.IMPLVAR_INSN:
+ u += 1;
+ break;
+ case ClassWriter.LABEL_INSN:
+ readLabel(offset + readShort(u + 1), labels);
+ u += 3;
+ break;
+ case ClassWriter.LABELW_INSN:
+ readLabel(offset + readInt(u + 1), labels);
+ u += 5;
+ break;
+ case ClassWriter.WIDE_INSN:
+ opcode = b[u + 1] & 0xFF;
+ if (opcode == Opcodes.IINC) {
+ u += 6;
+ } else {
+ u += 4;
}
- if (ANNOTATIONS && impanns != 0) {
- readParameterAnnotations(impanns, desc, c, false, mv);
+ break;
+ case ClassWriter.TABL_INSN:
+ // skips 0 to 3 padding bytes
+ u = u + 4 - (offset & 3);
+ // reads instruction
+ readLabel(offset + readInt(u), labels);
+ for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
+ readLabel(offset + readInt(u + 12), labels);
+ u += 4;
}
- while (cattrs != null) {
- attr = cattrs.next;
- cattrs.next = null;
- mv.visitAttribute(cattrs);
- cattrs = attr;
+ u += 12;
+ break;
+ case ClassWriter.LOOK_INSN:
+ // skips 0 to 3 padding bytes
+ u = u + 4 - (offset & 3);
+ // reads instruction
+ readLabel(offset + readInt(u), labels);
+ for (int i = readInt(u + 4); i > 0; --i) {
+ readLabel(offset + readInt(u + 12), labels);
+ u += 8;
}
+ u += 8;
+ break;
+ case ClassWriter.VAR_INSN:
+ case ClassWriter.SBYTE_INSN:
+ case ClassWriter.LDC_INSN:
+ u += 2;
+ break;
+ case ClassWriter.SHORT_INSN:
+ case ClassWriter.LDCW_INSN:
+ case ClassWriter.FIELDORMETH_INSN:
+ case ClassWriter.TYPE_INSN:
+ case ClassWriter.IINC_INSN:
+ u += 3;
+ break;
+ case ClassWriter.ITFMETH_INSN:
+ case ClassWriter.INDYMETH_INSN:
+ u += 5;
+ break;
+ // case MANA_INSN:
+ default:
+ u += 4;
+ break;
}
+ }
- if (mv != null && v != 0) {
- int maxStack = readUnsignedShort(v);
- int maxLocals = readUnsignedShort(v + 2);
- int codeLength = readInt(v + 4);
- v += 8;
+ // reads the try catch entries to find the labels, and also visits them
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ Label start = readLabel(readUnsignedShort(u + 2), labels);
+ Label end = readLabel(readUnsignedShort(u + 4), labels);
+ Label handler = readLabel(readUnsignedShort(u + 6), labels);
+ String type = readUTF8(items[readUnsignedShort(u + 8)], c);
+ mv.visitTryCatchBlock(start, end, handler, type);
+ u += 8;
+ }
+ u += 2;
- int codeStart = v;
- int codeEnd = v + codeLength;
-
- mv.visitCode();
-
- // 1st phase: finds the labels
- int label;
- Label[] labels = new Label[codeLength + 2];
- readLabel(codeLength + 1, labels);
- while (v < codeEnd) {
- w = v - codeStart;
- int opcode = b[v] & 0xFF;
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- v += 1;
- break;
- case ClassWriter.LABEL_INSN:
- readLabel(w + readShort(v + 1), labels);
- v += 3;
- break;
- case ClassWriter.LABELW_INSN:
- readLabel(w + readInt(v + 1), labels);
- v += 5;
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[v + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- v += 6;
- } else {
- v += 4;
- }
- break;
- case ClassWriter.TABL_INSN:
- // skips 0 to 3 padding bytes*
- v = v + 4 - (w & 3);
- // reads instruction
- readLabel(w + readInt(v), labels);
- j = readInt(v + 8) - readInt(v + 4) + 1;
- v += 12;
- for (; j > 0; --j) {
- readLabel(w + readInt(v), labels);
- v += 4;
- }
- break;
- case ClassWriter.LOOK_INSN:
- // skips 0 to 3 padding bytes*
- v = v + 4 - (w & 3);
- // reads instruction
- readLabel(w + readInt(v), labels);
- j = readInt(v + 4);
- v += 8;
- for (; j > 0; --j) {
- readLabel(w + readInt(v + 4), labels);
- v += 8;
- }
- break;
- case ClassWriter.VAR_INSN:
- case ClassWriter.SBYTE_INSN:
- case ClassWriter.LDC_INSN:
- v += 2;
- break;
- case ClassWriter.SHORT_INSN:
- case ClassWriter.LDCW_INSN:
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.TYPE_INSN:
- case ClassWriter.IINC_INSN:
- v += 3;
- break;
- case ClassWriter.ITFMETH_INSN:
- v += 5;
- break;
- // case MANA_INSN:
- default:
- v += 4;
- break;
+ // reads the code attributes
+ int[] tanns = null; // start index of each visible type annotation
+ int[] itanns = null; // start index of each invisible type annotation
+ int tann = 0; // current index in tanns array
+ int itann = 0; // current index in itanns array
+ int ntoff = -1; // next visible type annotation code offset
+ int nitoff = -1; // next invisible type annotation code offset
+ int varTable = 0;
+ int varTypeTable = 0;
+ boolean zip = true;
+ boolean unzip = (context.flags & EXPAND_FRAMES) != 0;
+ int stackMap = 0;
+ int stackMapSize = 0;
+ int frameCount = 0;
+ Context frame = null;
+ Attribute attributes = null;
+
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
+ if ("LocalVariableTable".equals(attrName)) {
+ if ((context.flags & SKIP_DEBUG) == 0) {
+ varTable = u + 8;
+ for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
+ int label = readUnsignedShort(v + 10);
+ if (labels[label] == null) {
+ readLabel(label, labels).status |= Label.DEBUG;
+ }
+ label += readUnsignedShort(v + 12);
+ if (labels[label] == null) {
+ readLabel(label, labels).status |= Label.DEBUG;
+ }
+ v += 10;
}
}
- // parses the try catch entries
- j = readUnsignedShort(v);
- v += 2;
- for (; j > 0; --j) {
- Label start = readLabel(readUnsignedShort(v), labels);
- Label end = readLabel(readUnsignedShort(v + 2), labels);
- Label handler = readLabel(readUnsignedShort(v + 4), labels);
- int type = readUnsignedShort(v + 6);
- if (type == 0) {
- mv.visitTryCatchBlock(start, end, handler, null);
- } else {
- mv.visitTryCatchBlock(start,
- end,
- handler,
- readUTF8(items[type], c));
+ } else if ("LocalVariableTypeTable".equals(attrName)) {
+ varTypeTable = u + 8;
+ } else if ("LineNumberTable".equals(attrName)) {
+ if ((context.flags & SKIP_DEBUG) == 0) {
+ for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
+ int label = readUnsignedShort(v + 10);
+ if (labels[label] == null) {
+ readLabel(label, labels).status |= Label.DEBUG;
+ }
+ labels[label].line = readUnsignedShort(v + 12);
+ v += 4;
}
- v += 8;
}
- // parses the local variable, line number tables, and code
- // attributes
- int varTable = 0;
- int varTypeTable = 0;
- int stackMap = 0;
- int frameCount = 0;
- int frameMode = 0;
- int frameOffset = 0;
- int frameLocalCount = 0;
- int frameLocalDiff = 0;
- int frameStackCount = 0;
- Object[] frameLocal = null;
- Object[] frameStack = null;
- boolean zip = true;
- cattrs = null;
- j = readUnsignedShort(v);
- v += 2;
- for (; j > 0; --j) {
- attrName = readUTF8(v, c);
- if ("LocalVariableTable".equals(attrName)) {
- if (!skipDebug) {
- varTable = v + 6;
- k = readUnsignedShort(v + 6);
- w = v + 8;
- for (; k > 0; --k) {
- label = readUnsignedShort(w);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
- label += readUnsignedShort(w + 2);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
- w += 10;
- }
- }
- } else if ("LocalVariableTypeTable".equals(attrName)) {
- varTypeTable = v + 6;
- } else if ("LineNumberTable".equals(attrName)) {
- if (!skipDebug) {
- k = readUnsignedShort(v + 6);
- w = v + 8;
- for (; k > 0; --k) {
- label = readUnsignedShort(w);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
- labels[label].line = readUnsignedShort(w + 2);
- w += 4;
- }
- }
- } else if (FRAMES && "StackMapTable".equals(attrName)) {
- if ((flags & SKIP_FRAMES) == 0) {
- stackMap = v + 8;
- frameCount = readUnsignedShort(v + 6);
- }
- /*
- * here we do not extract the labels corresponding to
- * the attribute content. This would require a full
- * parsing of the attribute, which would need to be
- * repeated in the second phase (see below). Instead the
- * content of the attribute is read one frame at a time
- * (i.e. after a frame has been visited, the next frame
- * is read), and the labels it contains are also
- * extracted one frame at a time. Thanks to the ordering
- * of frames, having only a "one frame lookahead" is not
- * a problem, i.e. it is not possible to see an offset
- * smaller than the offset of the current insn and for
- * which no Label exist.
- */
- // TODO true for frame offsets,
- // but for UNINITIALIZED type offsets?
- } else if (FRAMES && "StackMap".equals(attrName)) {
- if ((flags & SKIP_FRAMES) == 0) {
- stackMap = v + 8;
- frameCount = readUnsignedShort(v + 6);
- zip = false;
- }
- /*
- * IMPORTANT! here we assume that the frames are
- * ordered, as in the StackMapTable attribute, although
- * this is not guaranteed by the attribute format.
- */
- } else {
- for (k = 0; k < attrs.length; ++k) {
- if (attrs[k].type.equals(attrName)) {
- attr = attrs[k].read(this,
- v + 6,
- readInt(v + 2),
- c,
- codeStart - 8,
- labels);
- if (attr != null) {
- attr.next = cattrs;
- cattrs = attr;
- }
- }
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ tanns = readTypeAnnotations(mv, context, u + 8, true);
+ ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
+ : readUnsignedShort(tanns[0] + 1);
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ itanns = readTypeAnnotations(mv, context, u + 8, false);
+ nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
+ : readUnsignedShort(itanns[0] + 1);
+ } else if (FRAMES && "StackMapTable".equals(attrName)) {
+ if ((context.flags & SKIP_FRAMES) == 0) {
+ stackMap = u + 10;
+ stackMapSize = readInt(u + 4);
+ frameCount = readUnsignedShort(u + 8);
+ }
+ /*
+ * here we do not extract the labels corresponding to the
+ * attribute content. This would require a full parsing of the
+ * attribute, which would need to be repeated in the second
+ * phase (see below). Instead the content of the attribute is
+ * read one frame at a time (i.e. after a frame has been
+ * visited, the next frame is read), and the labels it contains
+ * are also extracted one frame at a time. Thanks to the
+ * ordering of frames, having only a "one frame lookahead" is
+ * not a problem, i.e. it is not possible to see an offset
+ * smaller than the offset of the current insn and for which no
+ * Label exist.
+ */
+ /*
+ * This is not true for UNINITIALIZED type offsets. We solve
+ * this by parsing the stack map table without a full decoding
+ * (see below).
+ */
+ } else if (FRAMES && "StackMap".equals(attrName)) {
+ if ((context.flags & SKIP_FRAMES) == 0) {
+ zip = false;
+ stackMap = u + 10;
+ stackMapSize = readInt(u + 4);
+ frameCount = readUnsignedShort(u + 8);
+ }
+ /*
+ * IMPORTANT! here we assume that the frames are ordered, as in
+ * the StackMapTable attribute, although this is not guaranteed
+ * by the attribute format.
+ */
+ } else {
+ for (int j = 0; j < context.attrs.length; ++j) {
+ if (context.attrs[j].type.equals(attrName)) {
+ Attribute attr = context.attrs[j].read(this, u + 8,
+ readInt(u + 4), c, codeStart - 8, labels);
+ if (attr != null) {
+ attr.next = attributes;
+ attributes = attr;
}
}
- v += 6 + readInt(v + 2);
}
+ }
+ u += 6 + readInt(u + 4);
+ }
+ u += 2;
- // 2nd phase: visits each instruction
- if (FRAMES && stackMap != 0) {
- // creates the very first (implicit) frame from the method
- // descriptor
- frameLocal = new Object[maxLocals];
- frameStack = new Object[maxStack];
- if (unzip) {
- int local = 0;
- if ((access & Opcodes.ACC_STATIC) == 0) {
- if ("".equals(name)) {
- frameLocal[local++] = Opcodes.UNINITIALIZED_THIS;
- } else {
- frameLocal[local++] = readClass(header + 2, c);
- }
- }
- j = 1;
- loop: while (true) {
- k = j;
- switch (desc.charAt(j++)) {
- case 'Z':
- case 'C':
- case 'B':
- case 'S':
- case 'I':
- frameLocal[local++] = Opcodes.INTEGER;
- break;
- case 'F':
- frameLocal[local++] = Opcodes.FLOAT;
- break;
- case 'J':
- frameLocal[local++] = Opcodes.LONG;
- break;
- case 'D':
- frameLocal[local++] = Opcodes.DOUBLE;
- break;
- case '[':
- while (desc.charAt(j) == '[') {
- ++j;
- }
- if (desc.charAt(j) == 'L') {
- ++j;
- while (desc.charAt(j) != ';') {
- ++j;
- }
- }
- frameLocal[local++] = desc.substring(k, ++j);
- break;
- case 'L':
- while (desc.charAt(j) != ';') {
- ++j;
- }
- frameLocal[local++] = desc.substring(k + 1,
- j++);
- break;
- default:
- break loop;
- }
+ // generates the first (implicit) stack map frame
+ if (FRAMES && stackMap != 0) {
+ /*
+ * for the first explicit frame the offset is not offset_delta + 1
+ * but only offset_delta; setting the implicit frame offset to -1
+ * allow the use of the "offset_delta + 1" rule in all cases
+ */
+ frame = context;
+ frame.offset = -1;
+ frame.mode = 0;
+ frame.localCount = 0;
+ frame.localDiff = 0;
+ frame.stackCount = 0;
+ frame.local = new Object[maxLocals];
+ frame.stack = new Object[maxStack];
+ if (unzip) {
+ getImplicitFrame(context);
+ }
+ /*
+ * Finds labels for UNINITIALIZED frame types. Instead of decoding
+ * each element of the stack map table, we look for 3 consecutive
+ * bytes that "look like" an UNINITIALIZED type (tag 8, offset
+ * within code bounds, NEW instruction at this offset). We may find
+ * false positives (i.e. not real UNINITIALIZED types), but this
+ * should be rare, and the only consequence will be the creation of
+ * an unneeded label. This is better than creating a label for each
+ * NEW instruction, and faster than fully decoding the whole stack
+ * map table.
+ */
+ for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) {
+ if (b[i] == 8) { // UNINITIALIZED FRAME TYPE
+ int v = readUnsignedShort(i + 1);
+ if (v >= 0 && v < codeLength) {
+ if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
+ readLabel(v, labels);
}
- frameLocalCount = local;
}
- /*
- * for the first explicit frame the offset is not
- * offset_delta + 1 but only offset_delta; setting the
- * implicit frame offset to -1 allow the use of the
- * "offset_delta + 1" rule in all cases
- */
- frameOffset = -1;
}
- v = codeStart;
- Label l;
- while (v < codeEnd) {
- w = v - codeStart;
-
- l = labels[w];
- if (l != null) {
- mv.visitLabel(l);
- if (!skipDebug && l.line > 0) {
- mv.visitLineNumber(l.line, l);
- }
- }
+ }
+ }
- while (FRAMES && frameLocal != null
- && (frameOffset == w || frameOffset == -1))
- {
- // if there is a frame for this offset,
- // makes the visitor visit it,
- // and reads the next frame if there is one.
- if (!zip || unzip) {
- mv.visitFrame(Opcodes.F_NEW,
- frameLocalCount,
- frameLocal,
- frameStackCount,
- frameStack);
- } else if (frameOffset != -1) {
- mv.visitFrame(frameMode,
- frameLocalDiff,
- frameLocal,
- frameStackCount,
- frameStack);
- }
+ // visits the instructions
+ u = codeStart;
+ while (u < codeEnd) {
+ int offset = u - codeStart;
+
+ // visits the label and line number for this offset, if any
+ Label l = labels[offset];
+ if (l != null) {
+ mv.visitLabel(l);
+ if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
+ mv.visitLineNumber(l.line, l);
+ }
+ }
- if (frameCount > 0) {
- int tag, delta, n;
- if (zip) {
- tag = b[stackMap++] & 0xFF;
- } else {
- tag = MethodWriter.FULL_FRAME;
- frameOffset = -1;
- }
- frameLocalDiff = 0;
- if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME)
- {
- delta = tag;
- frameMode = Opcodes.F_SAME;
- frameStackCount = 0;
- } else if (tag < MethodWriter.RESERVED) {
- delta = tag
- - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
- stackMap = readFrameType(frameStack,
- 0,
- stackMap,
- c,
- labels);
- frameMode = Opcodes.F_SAME1;
- frameStackCount = 1;
- } else {
- delta = readUnsignedShort(stackMap);
- stackMap += 2;
- if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
- {
- stackMap = readFrameType(frameStack,
- 0,
- stackMap,
- c,
- labels);
- frameMode = Opcodes.F_SAME1;
- frameStackCount = 1;
- } else if (tag >= MethodWriter.CHOP_FRAME
- && tag < MethodWriter.SAME_FRAME_EXTENDED)
- {
- frameMode = Opcodes.F_CHOP;
- frameLocalDiff = MethodWriter.SAME_FRAME_EXTENDED
- - tag;
- frameLocalCount -= frameLocalDiff;
- frameStackCount = 0;
- } else if (tag == MethodWriter.SAME_FRAME_EXTENDED)
- {
- frameMode = Opcodes.F_SAME;
- frameStackCount = 0;
- } else if (tag < MethodWriter.FULL_FRAME) {
- j = unzip ? frameLocalCount : 0;
- for (k = tag
- - MethodWriter.SAME_FRAME_EXTENDED; k > 0; k--)
- {
- stackMap = readFrameType(frameLocal,
- j++,
- stackMap,
- c,
- labels);
- }
- frameMode = Opcodes.F_APPEND;
- frameLocalDiff = tag
- - MethodWriter.SAME_FRAME_EXTENDED;
- frameLocalCount += frameLocalDiff;
- frameStackCount = 0;
- } else { // if (tag == FULL_FRAME) {
- frameMode = Opcodes.F_FULL;
- n = frameLocalDiff = frameLocalCount = readUnsignedShort(stackMap);
- stackMap += 2;
- for (j = 0; n > 0; n--) {
- stackMap = readFrameType(frameLocal,
- j++,
- stackMap,
- c,
- labels);
- }
- n = frameStackCount = readUnsignedShort(stackMap);
- stackMap += 2;
- for (j = 0; n > 0; n--) {
- stackMap = readFrameType(frameStack,
- j++,
- stackMap,
- c,
- labels);
- }
- }
- }
- frameOffset += delta + 1;
- readLabel(frameOffset, labels);
-
- --frameCount;
- } else {
- frameLocal = null;
- }
+ // visits the frame for this offset, if any
+ while (FRAMES && frame != null
+ && (frame.offset == offset || frame.offset == -1)) {
+ // if there is a frame for this offset, makes the visitor visit
+ // it, and reads the next frame if there is one.
+ if (frame.offset != -1) {
+ if (!zip || unzip) {
+ mv.visitFrame(Opcodes.F_NEW, frame.localCount,
+ frame.local, frame.stackCount, frame.stack);
+ } else {
+ mv.visitFrame(frame.mode, frame.localDiff, frame.local,
+ frame.stackCount, frame.stack);
}
+ }
+ if (frameCount > 0) {
+ stackMap = readFrame(stackMap, zip, unzip, frame);
+ --frameCount;
+ } else {
+ frame = null;
+ }
+ }
- int opcode = b[v] & 0xFF;
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- mv.visitInsn(opcode);
- v += 1;
- break;
- case ClassWriter.IMPLVAR_INSN:
- if (opcode > Opcodes.ISTORE) {
- opcode -= 59; // ISTORE_0
- mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
- opcode & 0x3);
- } else {
- opcode -= 26; // ILOAD_0
- mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2),
- opcode & 0x3);
- }
- v += 1;
- break;
- case ClassWriter.LABEL_INSN:
- mv.visitJumpInsn(opcode, labels[w
- + readShort(v + 1)]);
- v += 3;
- break;
- case ClassWriter.LABELW_INSN:
- mv.visitJumpInsn(opcode - 33, labels[w
- + readInt(v + 1)]);
- v += 5;
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[v + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- mv.visitIincInsn(readUnsignedShort(v + 2),
- readShort(v + 4));
- v += 6;
- } else {
- mv.visitVarInsn(opcode,
- readUnsignedShort(v + 2));
- v += 4;
- }
- break;
- case ClassWriter.TABL_INSN:
- // skips 0 to 3 padding bytes
- v = v + 4 - (w & 3);
- // reads instruction
- label = w + readInt(v);
- int min = readInt(v + 4);
- int max = readInt(v + 8);
- v += 12;
- Label[] table = new Label[max - min + 1];
- for (j = 0; j < table.length; ++j) {
- table[j] = labels[w + readInt(v)];
- v += 4;
- }
- mv.visitTableSwitchInsn(min,
- max,
- labels[label],
- table);
- break;
- case ClassWriter.LOOK_INSN:
- // skips 0 to 3 padding bytes
- v = v + 4 - (w & 3);
- // reads instruction
- label = w + readInt(v);
- j = readInt(v + 4);
- v += 8;
- int[] keys = new int[j];
- Label[] values = new Label[j];
- for (j = 0; j < keys.length; ++j) {
- keys[j] = readInt(v);
- values[j] = labels[w + readInt(v + 4)];
- v += 8;
- }
- mv.visitLookupSwitchInsn(labels[label],
- keys,
- values);
- break;
- case ClassWriter.VAR_INSN:
- mv.visitVarInsn(opcode, b[v + 1] & 0xFF);
- v += 2;
- break;
- case ClassWriter.SBYTE_INSN:
- mv.visitIntInsn(opcode, b[v + 1]);
- v += 2;
- break;
- case ClassWriter.SHORT_INSN:
- mv.visitIntInsn(opcode, readShort(v + 1));
- v += 3;
- break;
- case ClassWriter.LDC_INSN:
- mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c));
- v += 2;
- break;
- case ClassWriter.LDCW_INSN:
- mv.visitLdcInsn(readConst(readUnsignedShort(v + 1),
- c));
- v += 3;
- break;
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.ITFMETH_INSN:
- int cpIndex = items[readUnsignedShort(v + 1)];
- String iowner = readClass(cpIndex, c);
- cpIndex = items[readUnsignedShort(cpIndex + 2)];
- String iname = readUTF8(cpIndex, c);
- String idesc = readUTF8(cpIndex + 2, c);
- if (opcode < Opcodes.INVOKEVIRTUAL) {
- mv.visitFieldInsn(opcode, iowner, iname, idesc);
- } else {
- mv.visitMethodInsn(opcode, iowner, iname, idesc);
- }
- if (opcode == Opcodes.INVOKEINTERFACE) {
- v += 5;
- } else {
- v += 3;
- }
- break;
- case ClassWriter.TYPE_INSN:
- mv.visitTypeInsn(opcode, readClass(v + 1, c));
- v += 3;
- break;
- case ClassWriter.IINC_INSN:
- mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]);
- v += 3;
- break;
- // case MANA_INSN:
- default:
- mv.visitMultiANewArrayInsn(readClass(v + 1, c),
- b[v + 3] & 0xFF);
- v += 4;
- break;
- }
+ // visits the instruction at this offset
+ int opcode = b[u] & 0xFF;
+ switch (ClassWriter.TYPE[opcode]) {
+ case ClassWriter.NOARG_INSN:
+ mv.visitInsn(opcode);
+ u += 1;
+ break;
+ case ClassWriter.IMPLVAR_INSN:
+ if (opcode > Opcodes.ISTORE) {
+ opcode -= 59; // ISTORE_0
+ mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
+ opcode & 0x3);
+ } else {
+ opcode -= 26; // ILOAD_0
+ mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
}
- l = labels[codeEnd - codeStart];
- if (l != null) {
- mv.visitLabel(l);
+ u += 1;
+ break;
+ case ClassWriter.LABEL_INSN:
+ mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
+ u += 3;
+ break;
+ case ClassWriter.LABELW_INSN:
+ mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+ u += 5;
+ break;
+ case ClassWriter.WIDE_INSN:
+ opcode = b[u + 1] & 0xFF;
+ if (opcode == Opcodes.IINC) {
+ mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
+ u += 6;
+ } else {
+ mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
+ u += 4;
}
- // visits the local variable tables
- if (!skipDebug && varTable != 0) {
- int[] typeTable = null;
- if (varTypeTable != 0) {
- k = readUnsignedShort(varTypeTable) * 3;
- w = varTypeTable + 2;
- typeTable = new int[k];
- while (k > 0) {
- typeTable[--k] = w + 6; // signature
- typeTable[--k] = readUnsignedShort(w + 8); // index
- typeTable[--k] = readUnsignedShort(w); // start
- w += 10;
- }
- }
- k = readUnsignedShort(varTable);
- w = varTable + 2;
- for (; k > 0; --k) {
- int start = readUnsignedShort(w);
- int length = readUnsignedShort(w + 2);
- int index = readUnsignedShort(w + 8);
- String vsignature = null;
- if (typeTable != null) {
- for (int a = 0; a < typeTable.length; a += 3) {
- if (typeTable[a] == start
- && typeTable[a + 1] == index)
- {
- vsignature = readUTF8(typeTable[a + 2], c);
- break;
- }
- }
+ break;
+ case ClassWriter.TABL_INSN: {
+ // skips 0 to 3 padding bytes
+ u = u + 4 - (offset & 3);
+ // reads instruction
+ int label = offset + readInt(u);
+ int min = readInt(u + 4);
+ int max = readInt(u + 8);
+ Label[] table = new Label[max - min + 1];
+ u += 12;
+ for (int i = 0; i < table.length; ++i) {
+ table[i] = labels[offset + readInt(u)];
+ u += 4;
+ }
+ mv.visitTableSwitchInsn(min, max, labels[label], table);
+ break;
+ }
+ case ClassWriter.LOOK_INSN: {
+ // skips 0 to 3 padding bytes
+ u = u + 4 - (offset & 3);
+ // reads instruction
+ int label = offset + readInt(u);
+ int len = readInt(u + 4);
+ int[] keys = new int[len];
+ Label[] values = new Label[len];
+ u += 8;
+ for (int i = 0; i < len; ++i) {
+ keys[i] = readInt(u);
+ values[i] = labels[offset + readInt(u + 4)];
+ u += 8;
+ }
+ mv.visitLookupSwitchInsn(labels[label], keys, values);
+ break;
+ }
+ case ClassWriter.VAR_INSN:
+ mv.visitVarInsn(opcode, b[u + 1] & 0xFF);
+ u += 2;
+ break;
+ case ClassWriter.SBYTE_INSN:
+ mv.visitIntInsn(opcode, b[u + 1]);
+ u += 2;
+ break;
+ case ClassWriter.SHORT_INSN:
+ mv.visitIntInsn(opcode, readShort(u + 1));
+ u += 3;
+ break;
+ case ClassWriter.LDC_INSN:
+ mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c));
+ u += 2;
+ break;
+ case ClassWriter.LDCW_INSN:
+ mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
+ u += 3;
+ break;
+ case ClassWriter.FIELDORMETH_INSN:
+ case ClassWriter.ITFMETH_INSN: {
+ int cpIndex = items[readUnsignedShort(u + 1)];
+ String iowner = readClass(cpIndex, c);
+ cpIndex = items[readUnsignedShort(cpIndex + 2)];
+ String iname = readUTF8(cpIndex, c);
+ String idesc = readUTF8(cpIndex + 2, c);
+ if (opcode < Opcodes.INVOKEVIRTUAL) {
+ mv.visitFieldInsn(opcode, iowner, iname, idesc);
+ } else {
+ mv.visitMethodInsn(opcode, iowner, iname, idesc);
+ }
+ if (opcode == Opcodes.INVOKEINTERFACE) {
+ u += 5;
+ } else {
+ u += 3;
+ }
+ break;
+ }
+ case ClassWriter.INDYMETH_INSN: {
+ int cpIndex = items[readUnsignedShort(u + 1)];
+ int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
+ Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);
+ int bsmArgCount = readUnsignedShort(bsmIndex + 2);
+ Object[] bsmArgs = new Object[bsmArgCount];
+ bsmIndex += 4;
+ for (int i = 0; i < bsmArgCount; i++) {
+ bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);
+ bsmIndex += 2;
+ }
+ cpIndex = items[readUnsignedShort(cpIndex + 2)];
+ String iname = readUTF8(cpIndex, c);
+ String idesc = readUTF8(cpIndex + 2, c);
+ mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
+ u += 5;
+ break;
+ }
+ case ClassWriter.TYPE_INSN:
+ mv.visitTypeInsn(opcode, readClass(u + 1, c));
+ u += 3;
+ break;
+ case ClassWriter.IINC_INSN:
+ mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]);
+ u += 3;
+ break;
+ // case MANA_INSN:
+ default:
+ mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF);
+ u += 4;
+ break;
+ }
+
+ // visit the instruction annotations, if any
+ while (tanns != null && tann < tanns.length && ntoff <= offset) {
+ if (ntoff == offset) {
+ int v = readAnnotationTarget(context, tanns[tann]);
+ readAnnotationValues(v + 2, c, true,
+ mv.visitInsnAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), true));
+ }
+ ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1
+ : readUnsignedShort(tanns[tann] + 1);
+ }
+ while (itanns != null && itann < itanns.length && nitoff <= offset) {
+ if (nitoff == offset) {
+ int v = readAnnotationTarget(context, itanns[itann]);
+ readAnnotationValues(v + 2, c, true,
+ mv.visitInsnAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), false));
+ }
+ nitoff = ++itann >= itanns.length
+ || readByte(itanns[itann]) < 0x43 ? -1
+ : readUnsignedShort(itanns[itann] + 1);
+ }
+ }
+ if (labels[codeLength] != null) {
+ mv.visitLabel(labels[codeLength]);
+ }
+
+ // visits the local variable tables
+ if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) {
+ int[] typeTable = null;
+ if (varTypeTable != 0) {
+ u = varTypeTable + 2;
+ typeTable = new int[readUnsignedShort(varTypeTable) * 3];
+ for (int i = typeTable.length; i > 0;) {
+ typeTable[--i] = u + 6; // signature
+ typeTable[--i] = readUnsignedShort(u + 8); // index
+ typeTable[--i] = readUnsignedShort(u); // start
+ u += 10;
+ }
+ }
+ u = varTable + 2;
+ for (int i = readUnsignedShort(varTable); i > 0; --i) {
+ int start = readUnsignedShort(u);
+ int length = readUnsignedShort(u + 2);
+ int index = readUnsignedShort(u + 8);
+ String vsignature = null;
+ if (typeTable != null) {
+ for (int j = 0; j < typeTable.length; j += 3) {
+ if (typeTable[j] == start && typeTable[j + 1] == index) {
+ vsignature = readUTF8(typeTable[j + 2], c);
+ break;
}
- mv.visitLocalVariable(readUTF8(w + 4, c),
- readUTF8(w + 6, c),
- vsignature,
- labels[start],
- labels[start + length],
- index);
- w += 10;
}
}
- // visits the other attributes
- while (cattrs != null) {
- attr = cattrs.next;
- cattrs.next = null;
- mv.visitAttribute(cattrs);
- cattrs = attr;
+ mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c),
+ vsignature, labels[start], labels[start + length],
+ index);
+ u += 10;
+ }
+ }
+
+ // visits the local variables type annotations
+ if (tanns != null) {
+ for (int i = 0; i < tanns.length; ++i) {
+ if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) {
+ int v = readAnnotationTarget(context, tanns[i]);
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitLocalVariableAnnotation(context.typeRef,
+ context.typePath, context.start,
+ context.end, context.index, readUTF8(v, c),
+ true));
+ }
+ }
+ }
+ if (itanns != null) {
+ for (int i = 0; i < itanns.length; ++i) {
+ if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) {
+ int v = readAnnotationTarget(context, itanns[i]);
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitLocalVariableAnnotation(context.typeRef,
+ context.typePath, context.start,
+ context.end, context.index, readUTF8(v, c),
+ false));
}
- // visits the max stack and max locals values
- mv.visitMaxs(maxStack, maxLocals);
}
+ }
+
+ // visits the code attributes
+ while (attributes != null) {
+ Attribute attr = attributes.next;
+ attributes.next = null;
+ mv.visitAttribute(attributes);
+ attributes = attr;
+ }
- if (mv != null) {
- mv.visitEnd();
+ // visits the max stack and max locals values
+ mv.visitMaxs(maxStack, maxLocals);
+ }
+
+ /**
+ * Parses a type annotation table to find the labels, and to visit the try
+ * catch block annotations.
+ *
+ * @param u
+ * the start offset of a type annotation table.
+ * @param mv
+ * the method visitor to be used to visit the try catch block
+ * annotations.
+ * @param context
+ * information about the class being parsed.
+ * @param visible
+ * if the type annotation table to parse contains runtime visible
+ * annotations.
+ * @return the start offset of each type annotation in the parsed table.
+ */
+ private int[] readTypeAnnotations(final MethodVisitor mv,
+ final Context context, int u, boolean visible) {
+ char[] c = context.buffer;
+ int[] offsets = new int[readUnsignedShort(u)];
+ u += 2;
+ for (int i = 0; i < offsets.length; ++i) {
+ offsets[i] = u;
+ int target = readInt(u);
+ switch (target >>> 24) {
+ case 0x00: // CLASS_TYPE_PARAMETER
+ case 0x01: // METHOD_TYPE_PARAMETER
+ case 0x16: // METHOD_FORMAL_PARAMETER
+ u += 2;
+ break;
+ case 0x13: // FIELD
+ case 0x14: // METHOD_RETURN
+ case 0x15: // METHOD_RECEIVER
+ u += 1;
+ break;
+ case 0x40: // LOCAL_VARIABLE
+ case 0x41: // RESOURCE_VARIABLE
+ for (int j = readUnsignedShort(u + 1); j > 0; --j) {
+ int start = readUnsignedShort(u + 3);
+ int length = readUnsignedShort(u + 5);
+ readLabel(start, context.labels);
+ readLabel(start + length, context.labels);
+ u += 6;
+ }
+ u += 3;
+ break;
+ case 0x47: // CAST
+ case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+ case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+ u += 4;
+ break;
+ // case 0x10: // CLASS_EXTENDS
+ // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+ // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+ // case 0x17: // THROWS
+ // case 0x42: // EXCEPTION_PARAMETER
+ // case 0x43: // INSTANCEOF
+ // case 0x44: // NEW
+ // case 0x45: // CONSTRUCTOR_REFERENCE
+ // case 0x46: // METHOD_REFERENCE
+ default:
+ u += 3;
+ break;
+ }
+ int pathLength = readByte(u);
+ if ((target >>> 24) == 0x42) {
+ TypePath path = pathLength == 0 ? null : new TypePath(b, u);
+ u += 1 + 2 * pathLength;
+ u = readAnnotationValues(u + 2, c, true,
+ mv.visitTryCatchAnnotation(target, path,
+ readUTF8(u, c), visible));
+ } else {
+ u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null);
}
}
+ return offsets;
+ }
- // visits the end of the class
- classVisitor.visitEnd();
+ /**
+ * Parses the header of a type annotation to extract its target_type and
+ * target_path (the result is stored in the given context), and returns the
+ * start offset of the rest of the type_annotation structure (i.e. the
+ * offset to the type_index field, which is followed by
+ * num_element_value_pairs and then the name,value pairs).
+ *
+ * @param context
+ * information about the class being parsed. This is where the
+ * extracted target_type and target_path must be stored.
+ * @param u
+ * the start offset of a type_annotation structure.
+ * @return the start offset of the rest of the type_annotation structure.
+ */
+ private int readAnnotationTarget(final Context context, int u) {
+ int target = readInt(u);
+ switch (target >>> 24) {
+ case 0x00: // CLASS_TYPE_PARAMETER
+ case 0x01: // METHOD_TYPE_PARAMETER
+ case 0x16: // METHOD_FORMAL_PARAMETER
+ target &= 0xFFFF0000;
+ u += 2;
+ break;
+ case 0x13: // FIELD
+ case 0x14: // METHOD_RETURN
+ case 0x15: // METHOD_RECEIVER
+ target &= 0xFF000000;
+ u += 1;
+ break;
+ case 0x40: // LOCAL_VARIABLE
+ case 0x41: { // RESOURCE_VARIABLE
+ target &= 0xFF000000;
+ int n = readUnsignedShort(u + 1);
+ context.start = new Label[n];
+ context.end = new Label[n];
+ context.index = new int[n];
+ u += 3;
+ for (int i = 0; i < n; ++i) {
+ int start = readUnsignedShort(u);
+ int length = readUnsignedShort(u + 2);
+ context.start[i] = readLabel(start, context.labels);
+ context.end[i] = readLabel(start + length, context.labels);
+ context.index[i] = readUnsignedShort(u + 4);
+ u += 6;
+ }
+ break;
+ }
+ case 0x47: // CAST
+ case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+ case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+ target &= 0xFF0000FF;
+ u += 4;
+ break;
+ // case 0x10: // CLASS_EXTENDS
+ // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+ // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+ // case 0x17: // THROWS
+ // case 0x42: // EXCEPTION_PARAMETER
+ // case 0x43: // INSTANCEOF
+ // case 0x44: // NEW
+ // case 0x45: // CONSTRUCTOR_REFERENCE
+ // case 0x46: // METHOD_REFERENCE
+ default:
+ target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000;
+ u += 3;
+ break;
+ }
+ int pathLength = readByte(u);
+ context.typeRef = target;
+ context.typePath = pathLength == 0 ? null : new TypePath(b, u);
+ return u + 1 + 2 * pathLength;
}
/**
* Reads parameter annotations and makes the given visitor visit them.
- *
- * @param v start offset in {@link #b b} of the annotations to be read.
- * @param desc the method descriptor.
- * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or
- * {@link #readConst readConst}.
- * @param visible true if the annotations to be read are visible
- * at runtime.
- * @param mv the visitor that must visit the annotations.
+ *
+ * @param mv
+ * the visitor that must visit the annotations.
+ * @param context
+ * information about the class being parsed.
+ * @param v
+ * start offset in {@link #b b} of the annotations to be read.
+ * @param visible
+ * true if the annotations to be read are visible at
+ * runtime.
*/
- private void readParameterAnnotations(
- int v,
- final String desc,
- final char[] buf,
- final boolean visible,
- final MethodVisitor mv)
- {
+ private void readParameterAnnotations(final MethodVisitor mv,
+ final Context context, int v, final boolean visible) {
int i;
int n = b[v++] & 0xFF;
// workaround for a bug in javac (javac compiler generates a parameter
@@ -1483,7 +1731,7 @@ private void readParameterAnnotations(
// equal to the number of parameters in the method descriptor - which
// includes the synthetic parameters added by the compiler). This work-
// around supposes that the synthetic parameters are the first ones.
- int synthetics = Type.getArgumentTypes(desc).length - n;
+ int synthetics = Type.getArgumentTypes(context.desc).length - n;
AnnotationVisitor av;
for (i = 0; i < synthetics; ++i) {
// virtual annotation to detect synthetic parameters in MethodWriter
@@ -1492,34 +1740,36 @@ private void readParameterAnnotations(
av.visitEnd();
}
}
+ char[] c = context.buffer;
for (; i < n + synthetics; ++i) {
int j = readUnsignedShort(v);
v += 2;
for (; j > 0; --j) {
- av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
- v = readAnnotationValues(v + 2, buf, true, av);
+ av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible);
+ v = readAnnotationValues(v + 2, c, true, av);
}
}
}
/**
* Reads the values of an annotation and makes the given visitor visit them.
- *
- * @param v the start offset in {@link #b b} of the values to be read
- * (including the unsigned short that gives the number of values).
- * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or
- * {@link #readConst readConst}.
- * @param named if the annotation values are named or not.
- * @param av the visitor that must visit the values.
+ *
+ * @param v
+ * the start offset in {@link #b b} of the values to be read
+ * (including the unsigned short that gives the number of
+ * values).
+ * @param buf
+ * buffer to be used to call {@link #readUTF8 readUTF8},
+ * {@link #readClass(int,char[]) readClass} or {@link #readConst
+ * readConst}.
+ * @param named
+ * if the annotation values are named or not.
+ * @param av
+ * the visitor that must visit the values.
* @return the end offset of the annotation values.
*/
- private int readAnnotationValues(
- int v,
- final char[] buf,
- final boolean named,
- final AnnotationVisitor av)
- {
+ private int readAnnotationValues(int v, final char[] buf,
+ final boolean named, final AnnotationVisitor av) {
int i = readUnsignedShort(v);
v += 2;
if (named) {
@@ -1539,211 +1789,369 @@ private int readAnnotationValues(
/**
* Reads a value of an annotation and makes the given visitor visit it.
- *
- * @param v the start offset in {@link #b b} of the value to be read (not
- * including the value name constant pool index).
- * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or
- * {@link #readConst readConst}.
- * @param name the name of the value to be read.
- * @param av the visitor that must visit the value.
+ *
+ * @param v
+ * the start offset in {@link #b b} of the value to be read
+ * (not including the value name constant pool index).
+ * @param buf
+ * buffer to be used to call {@link #readUTF8 readUTF8},
+ * {@link #readClass(int,char[]) readClass} or {@link #readConst
+ * readConst}.
+ * @param name
+ * the name of the value to be read.
+ * @param av
+ * the visitor that must visit the value.
* @return the end offset of the annotation value.
*/
- private int readAnnotationValue(
- int v,
- final char[] buf,
- final String name,
- final AnnotationVisitor av)
- {
+ private int readAnnotationValue(int v, final char[] buf, final String name,
+ final AnnotationVisitor av) {
int i;
if (av == null) {
switch (b[v] & 0xFF) {
- case 'e': // enum_const_value
- return v + 5;
- case '@': // annotation_value
- return readAnnotationValues(v + 3, buf, true, null);
- case '[': // array_value
- return readAnnotationValues(v + 1, buf, false, null);
- default:
- return v + 3;
+ case 'e': // enum_const_value
+ return v + 5;
+ case '@': // annotation_value
+ return readAnnotationValues(v + 3, buf, true, null);
+ case '[': // array_value
+ return readAnnotationValues(v + 1, buf, false, null);
+ default:
+ return v + 3;
}
}
switch (b[v++] & 0xFF) {
- case 'I': // pointer to CONSTANT_Integer
- case 'J': // pointer to CONSTANT_Long
- case 'F': // pointer to CONSTANT_Float
- case 'D': // pointer to CONSTANT_Double
- av.visit(name, readConst(readUnsignedShort(v), buf));
- v += 2;
- break;
- case 'B': // pointer to CONSTANT_Byte
- av.visit(name,
- new Byte((byte) readInt(items[readUnsignedShort(v)])));
- v += 2;
- break;
- case 'Z': // pointer to CONSTANT_Boolean
- av.visit(name, readInt(items[readUnsignedShort(v)]) == 0
- ? Boolean.FALSE
- : Boolean.TRUE);
- v += 2;
- break;
- case 'S': // pointer to CONSTANT_Short
- av.visit(name,
- new Short((short) readInt(items[readUnsignedShort(v)])));
- v += 2;
+ case 'I': // pointer to CONSTANT_Integer
+ case 'J': // pointer to CONSTANT_Long
+ case 'F': // pointer to CONSTANT_Float
+ case 'D': // pointer to CONSTANT_Double
+ av.visit(name, readConst(readUnsignedShort(v), buf));
+ v += 2;
+ break;
+ case 'B': // pointer to CONSTANT_Byte
+ av.visit(name,
+ new Byte((byte) readInt(items[readUnsignedShort(v)])));
+ v += 2;
+ break;
+ case 'Z': // pointer to CONSTANT_Boolean
+ av.visit(name,
+ readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE
+ : Boolean.TRUE);
+ v += 2;
+ break;
+ case 'S': // pointer to CONSTANT_Short
+ av.visit(name, new Short(
+ (short) readInt(items[readUnsignedShort(v)])));
+ v += 2;
+ break;
+ case 'C': // pointer to CONSTANT_Char
+ av.visit(name, new Character(
+ (char) readInt(items[readUnsignedShort(v)])));
+ v += 2;
+ break;
+ case 's': // pointer to CONSTANT_Utf8
+ av.visit(name, readUTF8(v, buf));
+ v += 2;
+ break;
+ case 'e': // enum_const_value
+ av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
+ v += 4;
+ break;
+ case 'c': // class_info
+ av.visit(name, Type.getType(readUTF8(v, buf)));
+ v += 2;
+ break;
+ case '@': // annotation_value
+ v = readAnnotationValues(v + 2, buf, true,
+ av.visitAnnotation(name, readUTF8(v, buf)));
+ break;
+ case '[': // array_value
+ int size = readUnsignedShort(v);
+ v += 2;
+ if (size == 0) {
+ return readAnnotationValues(v - 2, buf, false,
+ av.visitArray(name));
+ }
+ switch (this.b[v++] & 0xFF) {
+ case 'B':
+ byte[] bv = new byte[size];
+ for (i = 0; i < size; i++) {
+ bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, bv);
+ --v;
break;
- case 'C': // pointer to CONSTANT_Char
- av.visit(name,
- new Character((char) readInt(items[readUnsignedShort(v)])));
- v += 2;
+ case 'Z':
+ boolean[] zv = new boolean[size];
+ for (i = 0; i < size; i++) {
+ zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
+ v += 3;
+ }
+ av.visit(name, zv);
+ --v;
break;
- case 's': // pointer to CONSTANT_Utf8
- av.visit(name, readUTF8(v, buf));
- v += 2;
+ case 'S':
+ short[] sv = new short[size];
+ for (i = 0; i < size; i++) {
+ sv[i] = (short) readInt(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, sv);
+ --v;
break;
- case 'e': // enum_const_value
- av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
- v += 4;
+ case 'C':
+ char[] cv = new char[size];
+ for (i = 0; i < size; i++) {
+ cv[i] = (char) readInt(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, cv);
+ --v;
break;
- case 'c': // class_info
- av.visit(name, Type.getType(readUTF8(v, buf)));
- v += 2;
+ case 'I':
+ int[] iv = new int[size];
+ for (i = 0; i < size; i++) {
+ iv[i] = readInt(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, iv);
+ --v;
break;
- case '@': // annotation_value
- v = readAnnotationValues(v + 2,
- buf,
- true,
- av.visitAnnotation(name, readUTF8(v, buf)));
+ case 'J':
+ long[] lv = new long[size];
+ for (i = 0; i < size; i++) {
+ lv[i] = readLong(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, lv);
+ --v;
break;
- case '[': // array_value
- int size = readUnsignedShort(v);
- v += 2;
- if (size == 0) {
- return readAnnotationValues(v - 2,
- buf,
- false,
- av.visitArray(name));
+ case 'F':
+ float[] fv = new float[size];
+ for (i = 0; i < size; i++) {
+ fv[i] = Float
+ .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
+ v += 3;
}
- switch (this.b[v++] & 0xFF) {
- case 'B':
- byte[] bv = new byte[size];
- for (i = 0; i < size; i++) {
- bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, bv);
- --v;
- break;
- case 'Z':
- boolean[] zv = new boolean[size];
- for (i = 0; i < size; i++) {
- zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
- v += 3;
- }
- av.visit(name, zv);
- --v;
- break;
- case 'S':
- short[] sv = new short[size];
- for (i = 0; i < size; i++) {
- sv[i] = (short) readInt(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, sv);
- --v;
- break;
- case 'C':
- char[] cv = new char[size];
- for (i = 0; i < size; i++) {
- cv[i] = (char) readInt(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, cv);
- --v;
- break;
- case 'I':
- int[] iv = new int[size];
- for (i = 0; i < size; i++) {
- iv[i] = readInt(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, iv);
- --v;
- break;
- case 'J':
- long[] lv = new long[size];
- for (i = 0; i < size; i++) {
- lv[i] = readLong(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, lv);
- --v;
- break;
- case 'F':
- float[] fv = new float[size];
- for (i = 0; i < size; i++) {
- fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)]));
- v += 3;
- }
- av.visit(name, fv);
- --v;
- break;
- case 'D':
- double[] dv = new double[size];
- for (i = 0; i < size; i++) {
- dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)]));
- v += 3;
- }
- av.visit(name, dv);
- --v;
- break;
- default:
- v = readAnnotationValues(v - 3,
- buf,
- false,
- av.visitArray(name));
+ av.visit(name, fv);
+ --v;
+ break;
+ case 'D':
+ double[] dv = new double[size];
+ for (i = 0; i < size; i++) {
+ dv[i] = Double
+ .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
+ v += 3;
}
+ av.visit(name, dv);
+ --v;
+ break;
+ default:
+ v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
+ }
}
return v;
}
- private int readFrameType(
- final Object[] frame,
- final int index,
- int v,
- final char[] buf,
- final Label[] labels)
- {
- int type = b[v++] & 0xFF;
- switch (type) {
- case 0:
- frame[index] = Opcodes.TOP;
- break;
- case 1:
- frame[index] = Opcodes.INTEGER;
- break;
- case 2:
- frame[index] = Opcodes.FLOAT;
+ /**
+ * Computes the implicit frame of the method currently being parsed (as
+ * defined in the given {@link Context}) and stores it in the given context.
+ *
+ * @param frame
+ * information about the class being parsed.
+ */
+ private void getImplicitFrame(final Context frame) {
+ String desc = frame.desc;
+ Object[] locals = frame.local;
+ int local = 0;
+ if ((frame.access & Opcodes.ACC_STATIC) == 0) {
+ if ("".equals(frame.name)) {
+ locals[local++] = Opcodes.UNINITIALIZED_THIS;
+ } else {
+ locals[local++] = readClass(header + 2, frame.buffer);
+ }
+ }
+ int i = 1;
+ loop: while (true) {
+ int j = i;
+ switch (desc.charAt(i++)) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ locals[local++] = Opcodes.INTEGER;
break;
- case 3:
- frame[index] = Opcodes.DOUBLE;
+ case 'F':
+ locals[local++] = Opcodes.FLOAT;
break;
- case 4:
- frame[index] = Opcodes.LONG;
+ case 'J':
+ locals[local++] = Opcodes.LONG;
break;
- case 5:
- frame[index] = Opcodes.NULL;
+ case 'D':
+ locals[local++] = Opcodes.DOUBLE;
break;
- case 6:
- frame[index] = Opcodes.UNINITIALIZED_THIS;
+ case '[':
+ while (desc.charAt(i) == '[') {
+ ++i;
+ }
+ if (desc.charAt(i) == 'L') {
+ ++i;
+ while (desc.charAt(i) != ';') {
+ ++i;
+ }
+ }
+ locals[local++] = desc.substring(j, ++i);
break;
- case 7: // Object
- frame[index] = readClass(v, buf);
- v += 2;
+ case 'L':
+ while (desc.charAt(i) != ';') {
+ ++i;
+ }
+ locals[local++] = desc.substring(j + 1, i++);
break;
- default: // Uninitialized
- frame[index] = readLabel(readUnsignedShort(v), labels);
- v += 2;
+ default:
+ break loop;
+ }
+ }
+ frame.localCount = local;
+ }
+
+ /**
+ * Reads a stack map frame and stores the result in the given
+ * {@link Context} object.
+ *
+ * @param stackMap
+ * the start offset of a stack map frame in the class file.
+ * @param zip
+ * if the stack map frame at stackMap is compressed or not.
+ * @param unzip
+ * if the stack map frame must be uncompressed.
+ * @param frame
+ * where the parsed stack map frame must be stored.
+ * @return the offset of the first byte following the parsed frame.
+ */
+ private int readFrame(int stackMap, boolean zip, boolean unzip,
+ Context frame) {
+ char[] c = frame.buffer;
+ Label[] labels = frame.labels;
+ int tag;
+ int delta;
+ if (zip) {
+ tag = b[stackMap++] & 0xFF;
+ } else {
+ tag = MethodWriter.FULL_FRAME;
+ frame.offset = -1;
+ }
+ frame.localDiff = 0;
+ if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
+ delta = tag;
+ frame.mode = Opcodes.F_SAME;
+ frame.stackCount = 0;
+ } else if (tag < MethodWriter.RESERVED) {
+ delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
+ stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
+ frame.mode = Opcodes.F_SAME1;
+ frame.stackCount = 1;
+ } else {
+ delta = readUnsignedShort(stackMap);
+ stackMap += 2;
+ if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+ stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
+ frame.mode = Opcodes.F_SAME1;
+ frame.stackCount = 1;
+ } else if (tag >= MethodWriter.CHOP_FRAME
+ && tag < MethodWriter.SAME_FRAME_EXTENDED) {
+ frame.mode = Opcodes.F_CHOP;
+ frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag;
+ frame.localCount -= frame.localDiff;
+ frame.stackCount = 0;
+ } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
+ frame.mode = Opcodes.F_SAME;
+ frame.stackCount = 0;
+ } else if (tag < MethodWriter.FULL_FRAME) {
+ int local = unzip ? frame.localCount : 0;
+ for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) {
+ stackMap = readFrameType(frame.local, local++, stackMap, c,
+ labels);
+ }
+ frame.mode = Opcodes.F_APPEND;
+ frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED;
+ frame.localCount += frame.localDiff;
+ frame.stackCount = 0;
+ } else { // if (tag == FULL_FRAME) {
+ frame.mode = Opcodes.F_FULL;
+ int n = readUnsignedShort(stackMap);
+ stackMap += 2;
+ frame.localDiff = n;
+ frame.localCount = n;
+ for (int local = 0; n > 0; n--) {
+ stackMap = readFrameType(frame.local, local++, stackMap, c,
+ labels);
+ }
+ n = readUnsignedShort(stackMap);
+ stackMap += 2;
+ frame.stackCount = n;
+ for (int stack = 0; n > 0; n--) {
+ stackMap = readFrameType(frame.stack, stack++, stackMap, c,
+ labels);
+ }
+ }
+ }
+ frame.offset += delta + 1;
+ readLabel(frame.offset, labels);
+ return stackMap;
+ }
+
+ /**
+ * Reads a stack map frame type and stores it at the given index in the
+ * given array.
+ *
+ * @param frame
+ * the array where the parsed type must be stored.
+ * @param index
+ * the index in 'frame' where the parsed type must be stored.
+ * @param v
+ * the start offset of the stack map frame type to read.
+ * @param buf
+ * a buffer to read strings.
+ * @param labels
+ * the labels of the method currently being parsed, indexed by
+ * their offset. If the parsed type is an Uninitialized type, a
+ * new label for the corresponding NEW instruction is stored in
+ * this array if it does not already exist.
+ * @return the offset of the first byte after the parsed type.
+ */
+ private int readFrameType(final Object[] frame, final int index, int v,
+ final char[] buf, final Label[] labels) {
+ int type = b[v++] & 0xFF;
+ switch (type) {
+ case 0:
+ frame[index] = Opcodes.TOP;
+ break;
+ case 1:
+ frame[index] = Opcodes.INTEGER;
+ break;
+ case 2:
+ frame[index] = Opcodes.FLOAT;
+ break;
+ case 3:
+ frame[index] = Opcodes.DOUBLE;
+ break;
+ case 4:
+ frame[index] = Opcodes.LONG;
+ break;
+ case 5:
+ frame[index] = Opcodes.NULL;
+ break;
+ case 6:
+ frame[index] = Opcodes.UNINITIALIZED_THIS;
+ break;
+ case 7: // Object
+ frame[index] = readClass(v, buf);
+ v += 2;
+ break;
+ default: // Uninitialized
+ frame[index] = readLabel(readUnsignedShort(v), labels);
+ v += 2;
}
return v;
}
@@ -1752,11 +2160,13 @@ private int readFrameType(
* Returns the label corresponding to the given offset. The default
* implementation of this method creates a label for the given offset if it
* has not been already created.
- *
- * @param offset a bytecode offset in a method.
- * @param labels the already created labels, indexed by their offset. If a
- * label already exists for offset this method must not create a new
- * one. Otherwise it must store the new label in this array.
+ *
+ * @param offset
+ * a bytecode offset in a method.
+ * @param labels
+ * the already created labels, indexed by their offset. If a
+ * label already exists for offset this method must not create a
+ * new one. Otherwise it must store the new label in this array.
* @return a non null Label, which must be equal to labels[offset].
*/
protected Label readLabel(int offset, Label[] labels) {
@@ -1766,40 +2176,68 @@ protected Label readLabel(int offset, Label[] labels) {
return labels[offset];
}
+ /**
+ * Returns the start index of the attribute_info structure of this class.
+ *
+ * @return the start index of the attribute_info structure of this class.
+ */
+ private int getAttributes() {
+ // skips the header
+ int u = header + 8 + readUnsignedShort(header + 6) * 2;
+ // skips fields and methods
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ for (int j = readUnsignedShort(u + 8); j > 0; --j) {
+ u += 6 + readInt(u + 12);
+ }
+ u += 8;
+ }
+ u += 2;
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ for (int j = readUnsignedShort(u + 8); j > 0; --j) {
+ u += 6 + readInt(u + 12);
+ }
+ u += 8;
+ }
+ // the attribute_info structure starts just after the methods
+ return u + 2;
+ }
+
/**
* Reads an attribute in {@link #b b}.
- *
- * @param attrs prototypes of the attributes that must be parsed during the
- * visit of the class. Any attribute whose type is not equal to the
- * type of one the prototypes is ignored (i.e. an empty
- * {@link Attribute} instance is returned).
- * @param type the type of the attribute.
- * @param off index of the first byte of the attribute's content in
- * {@link #b b}. The 6 attribute header bytes, containing the type
- * and the length of the attribute, are not taken into account here
- * (they have already been read).
- * @param len the length of the attribute's content.
- * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or
- * {@link #readConst readConst}.
- * @param codeOff index of the first byte of code's attribute content in
- * {@link #b b}, or -1 if the attribute to be read is not a code
- * attribute. The 6 attribute header bytes, containing the type and
- * the length of the attribute, are not taken into account here.
- * @param labels the labels of the method's code, or null if the
- * attribute to be read is not a code attribute.
+ *
+ * @param attrs
+ * prototypes of the attributes that must be parsed during the
+ * visit of the class. Any attribute whose type is not equal to
+ * the type of one the prototypes is ignored (i.e. an empty
+ * {@link Attribute} instance is returned).
+ * @param type
+ * the type of the attribute.
+ * @param off
+ * index of the first byte of the attribute's content in
+ * {@link #b b}. The 6 attribute header bytes, containing the
+ * type and the length of the attribute, are not taken into
+ * account here (they have already been read).
+ * @param len
+ * the length of the attribute's content.
+ * @param buf
+ * buffer to be used to call {@link #readUTF8 readUTF8},
+ * {@link #readClass(int,char[]) readClass} or {@link #readConst
+ * readConst}.
+ * @param codeOff
+ * index of the first byte of code's attribute content in
+ * {@link #b b}, or -1 if the attribute to be read is not a code
+ * attribute. The 6 attribute header bytes, containing the type
+ * and the length of the attribute, are not taken into account
+ * here.
+ * @param labels
+ * the labels of the method's code, or null if the
+ * attribute to be read is not a code attribute.
* @return the attribute that has been read, or null to skip this
* attribute.
*/
- private Attribute readAttribute(
- final Attribute[] attrs,
- final String type,
- final int off,
- final int len,
- final char[] buf,
- final int codeOff,
- final Label[] labels)
- {
+ private Attribute readAttribute(final Attribute[] attrs, final String type,
+ final int off, final int len, final char[] buf, final int codeOff,
+ final Label[] labels) {
for (int i = 0; i < attrs.length; ++i) {
if (attrs[i].type.equals(type)) {
return attrs[i].read(this, off, len, buf, codeOff, labels);
@@ -1812,12 +2250,22 @@ private Attribute readAttribute(
// Utility methods: low level parsing
// ------------------------------------------------------------------------
+ /**
+ * Returns the number of constant pool items in {@link #b b}.
+ *
+ * @return the number of constant pool items in {@link #b b}.
+ */
+ public int getItemCount() {
+ return items.length;
+ }
+
/**
* Returns the start index of the constant pool item in {@link #b b}, plus
* one. This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
- *
- * @param item the index a constant pool item.
+ *
+ * @param item
+ * the index a constant pool item.
* @return the start index of the constant pool item in {@link #b b}, plus
* one.
*/
@@ -1825,12 +2273,24 @@ public int getItem(final int item) {
return items[item];
}
+ /**
+ * Returns the maximum length of the strings contained in the constant pool
+ * of the class.
+ *
+ * @return the maximum length of the strings contained in the constant pool
+ * of the class.
+ */
+ public int getMaxStringLength() {
+ return maxStringLength;
+ }
+
/**
* Reads a byte value in {@link #b b}. This method is intended for
* {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
- *
- * @param index the start index of the value to be read in {@link #b b}.
+ *
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public int readByte(final int index) {
@@ -1838,11 +2298,12 @@ public int readByte(final int index) {
}
/**
- * Reads an unsigned short value in {@link #b b}. This method is
- * intended for {@link Attribute} sub classes, and is normally not needed by
- * class generators or adapters.
- *
- * @param index the start index of the value to be read in {@link #b b}.
+ * Reads an unsigned short value in {@link #b b}. This method is intended
+ * for {@link Attribute} sub classes, and is normally not needed by class
+ * generators or adapters.
+ *
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public int readUnsignedShort(final int index) {
@@ -1854,8 +2315,9 @@ public int readUnsignedShort(final int index) {
* Reads a signed short value in {@link #b b}. This method is intended
* for {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
- *
- * @param index the start index of the value to be read in {@link #b b}.
+ *
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public short readShort(final int index) {
@@ -1867,8 +2329,9 @@ public short readShort(final int index) {
* Reads a signed int value in {@link #b b}. This method is intended for
* {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
- *
- * @param index the start index of the value to be read in {@link #b b}.
+ *
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public int readInt(final int index) {
@@ -1878,11 +2341,12 @@ public int readInt(final int index) {
}
/**
- * Reads a signed long value in {@link #b b}. This method is intended
- * for {@link Attribute} sub classes, and is normally not needed by class
+ * Reads a signed long value in {@link #b b}. This method is intended for
+ * {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
- *
- * @param index the start index of the value to be read in {@link #b b}.
+ *
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public long readLong(final int index) {
@@ -1895,15 +2359,20 @@ public long readLong(final int index) {
* Reads an UTF8 string constant pool item in {@link #b b}. This method
* is intended for {@link Attribute} sub classes, and is normally not needed
* by class generators or adapters.
- *
- * @param index the start index of an unsigned short value in {@link #b b},
- * whose value is the index of an UTF8 constant pool item.
- * @param buf buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
+ *
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of an UTF8 constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the String corresponding to the specified UTF8 item.
*/
public String readUTF8(int index, final char[] buf) {
int item = readUnsignedShort(index);
+ if (index == 0 || item == 0) {
+ return null;
+ }
String s = strings[item];
if (s != null) {
return s;
@@ -1914,45 +2383,48 @@ public String readUTF8(int index, final char[] buf) {
/**
* Reads UTF8 string in {@link #b b}.
- *
- * @param index start offset of the UTF8 string to be read.
- * @param utfLen length of the UTF8 string to be read.
- * @param buf buffer to be used to read the string. This buffer must be
- * sufficiently large. It is not automatically resized.
+ *
+ * @param index
+ * start offset of the UTF8 string to be read.
+ * @param utfLen
+ * length of the UTF8 string to be read.
+ * @param buf
+ * buffer to be used to read the string. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the String corresponding to the specified UTF8 string.
*/
private String readUTF(int index, final int utfLen, final char[] buf) {
int endIndex = index + utfLen;
byte[] b = this.b;
int strLen = 0;
- int c, d, e;
+ int c;
+ int st = 0;
+ char cc = 0;
while (index < endIndex) {
- c = b[index++] & 0xFF;
- switch (c >> 4) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- // 0xxxxxxx
+ c = b[index++];
+ switch (st) {
+ case 0:
+ c = c & 0xFF;
+ if (c < 0x80) { // 0xxxxxxx
buf[strLen++] = (char) c;
- break;
- case 12:
- case 13:
- // 110x xxxx 10xx xxxx
- d = b[index++];
- buf[strLen++] = (char) (((c & 0x1F) << 6) | (d & 0x3F));
- break;
- default:
- // 1110 xxxx 10xx xxxx 10xx xxxx
- d = b[index++];
- e = b[index++];
- buf[strLen++] = (char) (((c & 0x0F) << 12)
- | ((d & 0x3F) << 6) | (e & 0x3F));
- break;
+ } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
+ cc = (char) (c & 0x1F);
+ st = 1;
+ } else { // 1110 xxxx 10xx xxxx 10xx xxxx
+ cc = (char) (c & 0x0F);
+ st = 2;
+ }
+ break;
+
+ case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
+ buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
+ st = 0;
+ break;
+
+ case 2: // byte 2 of 3-byte char
+ cc = (char) ((cc << 6) | (c & 0x3F));
+ st = 1;
+ break;
}
}
return new String(buf, 0, strLen);
@@ -1962,11 +2434,13 @@ private String readUTF(int index, final int utfLen, final char[] buf) {
* Reads a class constant pool item in {@link #b b}. This method is
* intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.
- *
- * @param index the start index of an unsigned short value in {@link #b b},
- * whose value is the index of a class constant pool item.
- * @param buf buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
+ *
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of a class constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the String corresponding to the specified class item.
*/
public String readClass(final int index, final char[] buf) {
@@ -1980,30 +2454,42 @@ public String readClass(final int index, final char[] buf) {
* Reads a numeric or string constant pool item in {@link #b b}. This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.
- *
- * @param item the index of a constant pool item.
- * @param buf buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
- * @return the {@link Integer}, {@link Float}, {@link Long},
- * {@link Double}, {@link String} or {@link Type} corresponding to
+ *
+ * @param item
+ * the index of a constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
+ * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
+ * {@link String}, {@link Type} or {@link Handle} corresponding to
* the given constant pool item.
*/
public Object readConst(final int item, final char[] buf) {
int index = items[item];
switch (b[index - 1]) {
- case ClassWriter.INT:
- return new Integer(readInt(index));
- case ClassWriter.FLOAT:
- return new Float(Float.intBitsToFloat(readInt(index)));
- case ClassWriter.LONG:
- return new Long(readLong(index));
- case ClassWriter.DOUBLE:
- return new Double(Double.longBitsToDouble(readLong(index)));
- case ClassWriter.CLASS:
- return Type.getObjectType(readUTF8(index, buf));
- // case ClassWriter.STR:
- default:
- return readUTF8(index, buf);
+ case ClassWriter.INT:
+ return new Integer(readInt(index));
+ case ClassWriter.FLOAT:
+ return new Float(Float.intBitsToFloat(readInt(index)));
+ case ClassWriter.LONG:
+ return new Long(readLong(index));
+ case ClassWriter.DOUBLE:
+ return new Double(Double.longBitsToDouble(readLong(index)));
+ case ClassWriter.CLASS:
+ return Type.getObjectType(readUTF8(index, buf));
+ case ClassWriter.STR:
+ return readUTF8(index, buf);
+ case ClassWriter.MTYPE:
+ return Type.getMethodType(readUTF8(index, buf));
+ default: // case ClassWriter.HANDLE_BASE + [1..9]:
+ int tag = readByte(index);
+ int[] items = this.items;
+ int cpIndex = items[readUnsignedShort(index + 1)];
+ String owner = readClass(cpIndex, buf);
+ cpIndex = items[readUnsignedShort(cpIndex + 2)];
+ String name = readUTF8(cpIndex, buf);
+ String desc = readUTF8(cpIndex + 2, buf);
+ return new Handle(tag, owner, name, desc);
}
}
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java
index aaaafa982..3cdb9f8dc 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,167 +30,291 @@
package jersey.repackaged.org.objectweb.asm;
/**
- * A visitor to visit a Java class. The methods of this interface must be called
- * in the following order: visit [ visitSource ] [
+ * A visitor to visit a Java class. The methods of this class must be called in
+ * the following order: visit [ visitSource ] [
* visitOuterClass ] ( visitAnnotation |
- * visitAttribute )* (visitInnerClass |
- * visitField | visitMethod )* visitEnd.
- *
+ * visitTypeAnnotation | visitAttribute )* (
+ * visitInnerClass | visitField | visitMethod )*
+ * visitEnd.
+ *
* @author Eric Bruneton
*/
-public interface ClassVisitor {
+public abstract class ClassVisitor {
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ protected final int api;
+
+ /**
+ * The class visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected ClassVisitor cv;
+
+ /**
+ * Constructs a new {@link ClassVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ public ClassVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link ClassVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * @param cv
+ * the class visitor to which this visitor must delegate method
+ * calls. May be null.
+ */
+ public ClassVisitor(final int api, final ClassVisitor cv) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ throw new IllegalArgumentException();
+ }
+ this.api = api;
+ this.cv = cv;
+ }
/**
* Visits the header of the class.
- *
- * @param version the class version.
- * @param access the class's access flags (see {@link Opcodes}). This
- * parameter also indicates if the class is deprecated.
- * @param name the internal name of the class (see
- * {@link Type#getInternalName() getInternalName}).
- * @param signature the signature of this class. May be null if
- * the class is not a generic one, and does not extend or implement
- * generic classes or interfaces.
- * @param superName the internal of name of the super class (see
- * {@link Type#getInternalName() getInternalName}). For interfaces,
- * the super class is {@link Object}. May be null, but
- * only for the {@link Object} class.
- * @param interfaces the internal names of the class's interfaces (see
- * {@link Type#getInternalName() getInternalName}). May be
- * null.
+ *
+ * @param version
+ * the class version.
+ * @param access
+ * the class's access flags (see {@link Opcodes}). This parameter
+ * also indicates if the class is deprecated.
+ * @param name
+ * the internal name of the class (see
+ * {@link Type#getInternalName() getInternalName}).
+ * @param signature
+ * the signature of this class. May be null if the class
+ * is not a generic one, and does not extend or implement generic
+ * classes or interfaces.
+ * @param superName
+ * the internal of name of the super class (see
+ * {@link Type#getInternalName() getInternalName}). For
+ * interfaces, the super class is {@link Object}. May be
+ * null, but only for the {@link Object} class.
+ * @param interfaces
+ * the internal names of the class's interfaces (see
+ * {@link Type#getInternalName() getInternalName}). May be
+ * null.
*/
- void visit(
- int version,
- int access,
- String name,
- String signature,
- String superName,
- String[] interfaces);
+ public void visit(int version, int access, String name, String signature,
+ String superName, String[] interfaces) {
+ if (cv != null) {
+ cv.visit(version, access, name, signature, superName, interfaces);
+ }
+ }
/**
* Visits the source of the class.
- *
- * @param source the name of the source file from which the class was
- * compiled. May be null.
- * @param debug additional debug information to compute the correspondance
- * between source and compiled elements of the class. May be
- * null.
+ *
+ * @param source
+ * the name of the source file from which the class was compiled.
+ * May be null.
+ * @param debug
+ * additional debug information to compute the correspondance
+ * between source and compiled elements of the class. May be
+ * null.
*/
- void visitSource(String source, String debug);
+ public void visitSource(String source, String debug) {
+ if (cv != null) {
+ cv.visitSource(source, debug);
+ }
+ }
/**
* Visits the enclosing class of the class. This method must be called only
* if the class has an enclosing class.
- *
- * @param owner internal name of the enclosing class of the class.
- * @param name the name of the method that contains the class, or
- * null if the class is not enclosed in a method of its
- * enclosing class.
- * @param desc the descriptor of the method that contains the class, or
- * null if the class is not enclosed in a method of its
- * enclosing class.
+ *
+ * @param owner
+ * internal name of the enclosing class of the class.
+ * @param name
+ * the name of the method that contains the class, or
+ * null if the class is not enclosed in a method of its
+ * enclosing class.
+ * @param desc
+ * the descriptor of the method that contains the class, or
+ * null if the class is not enclosed in a method of its
+ * enclosing class.
*/
- void visitOuterClass(String owner, String name, String desc);
+ public void visitOuterClass(String owner, String name, String desc) {
+ if (cv != null) {
+ cv.visitOuterClass(owner, name, desc);
+ }
+ }
/**
* Visits an annotation of the class.
- *
- * @param desc the class descriptor of the annotation class.
- * @param visible true if the annotation is visible at runtime.
+ *
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ if (cv != null) {
+ return cv.visitAnnotation(desc, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits an annotation on a type in the class signature.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#CLASS_TYPE_PARAMETER
+ * CLASS_TYPE_PARAMETER},
+ * {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND
+ * CLASS_TYPE_PARAMETER_BOUND} or
+ * {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See
+ * {@link TypeReference}.
+ * @param typePath
+ * the path to the annotated type argument, wildcard bound, array
+ * element type, or static inner type within 'typeRef'. May be
+ * null if the annotation targets 'typeRef' as a whole.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or null if
* this visitor is not interested in visiting this annotation.
*/
- AnnotationVisitor visitAnnotation(String desc, boolean visible);
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (cv != null) {
+ return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
/**
* Visits a non standard attribute of the class.
- *
- * @param attr an attribute.
+ *
+ * @param attr
+ * an attribute.
*/
- void visitAttribute(Attribute attr);
+ public void visitAttribute(Attribute attr) {
+ if (cv != null) {
+ cv.visitAttribute(attr);
+ }
+ }
/**
* Visits information about an inner class. This inner class is not
* necessarily a member of the class being visited.
- *
- * @param name the internal name of an inner class (see
- * {@link Type#getInternalName() getInternalName}).
- * @param outerName the internal name of the class to which the inner class
- * belongs (see {@link Type#getInternalName() getInternalName}). May
- * be null for not member classes.
- * @param innerName the (simple) name of the inner class inside its
- * enclosing class. May be null for anonymous inner
- * classes.
- * @param access the access flags of the inner class as originally declared
- * in the enclosing class.
+ *
+ * @param name
+ * the internal name of an inner class (see
+ * {@link Type#getInternalName() getInternalName}).
+ * @param outerName
+ * the internal name of the class to which the inner class
+ * belongs (see {@link Type#getInternalName() getInternalName}).
+ * May be null for not member classes.
+ * @param innerName
+ * the (simple) name of the inner class inside its enclosing
+ * class. May be null for anonymous inner classes.
+ * @param access
+ * the access flags of the inner class as originally declared in
+ * the enclosing class.
*/
- void visitInnerClass(
- String name,
- String outerName,
- String innerName,
- int access);
+ public void visitInnerClass(String name, String outerName,
+ String innerName, int access) {
+ if (cv != null) {
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+ }
/**
* Visits a field of the class.
- *
- * @param access the field's access flags (see {@link Opcodes}). This
- * parameter also indicates if the field is synthetic and/or
- * deprecated.
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link Type Type}).
- * @param signature the field's signature. May be null if the
- * field's type does not use generic types.
- * @param value the field's initial value. This parameter, which may be
- * null if the field does not have an initial value, must
- * be an {@link Integer}, a {@link Float}, a {@link Long}, a
- * {@link Double} or a {@link String} (for int,
- * float, long or String fields
- * respectively). This parameter is only used for static fields.
- * Its value is ignored for non static fields, which must be
- * initialized through bytecode instructions in constructors or
- * methods.
+ *
+ * @param access
+ * the field's access flags (see {@link Opcodes}). This parameter
+ * also indicates if the field is synthetic and/or deprecated.
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link Type Type}).
+ * @param signature
+ * the field's signature. May be null if the field's
+ * type does not use generic types.
+ * @param value
+ * the field's initial value. This parameter, which may be
+ * null if the field does not have an initial value,
+ * must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double} or a {@link String} (for int,
+ * float, long or String fields
+ * respectively). This parameter is only used for static
+ * fields. Its value is ignored for non static fields, which
+ * must be initialized through bytecode instructions in
+ * constructors or methods.
* @return a visitor to visit field annotations and attributes, or
- * null if this class visitor is not interested in
- * visiting these annotations and attributes.
+ * null if this class visitor is not interested in visiting
+ * these annotations and attributes.
*/
- FieldVisitor visitField(
- int access,
- String name,
- String desc,
- String signature,
- Object value);
+ public FieldVisitor visitField(int access, String name, String desc,
+ String signature, Object value) {
+ if (cv != null) {
+ return cv.visitField(access, name, desc, signature, value);
+ }
+ return null;
+ }
/**
* Visits a method of the class. This method must return a new
- * {@link MethodVisitor} instance (or null) each time it is
- * called, i.e., it should not return a previously returned visitor.
- *
- * @param access the method's access flags (see {@link Opcodes}). This
- * parameter also indicates if the method is synthetic and/or
- * deprecated.
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type Type}).
- * @param signature the method's signature. May be null if the
- * method parameters, return type and exceptions do not use generic
- * types.
- * @param exceptions the internal names of the method's exception classes
- * (see {@link Type#getInternalName() getInternalName}). May be
- * null.
+ * {@link MethodVisitor} instance (or null) each time it is called,
+ * i.e., it should not return a previously returned visitor.
+ *
+ * @param access
+ * the method's access flags (see {@link Opcodes}). This
+ * parameter also indicates if the method is synthetic and/or
+ * deprecated.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
+ * @param signature
+ * the method's signature. May be null if the method
+ * parameters, return type and exceptions do not use generic
+ * types.
+ * @param exceptions
+ * the internal names of the method's exception classes (see
+ * {@link Type#getInternalName() getInternalName}). May be
+ * null.
* @return an object to visit the byte code of the method, or null
* if this class visitor is not interested in visiting the code of
* this method.
*/
- MethodVisitor visitMethod(
- int access,
- String name,
- String desc,
- String signature,
- String[] exceptions);
+ public MethodVisitor visitMethod(int access, String name, String desc,
+ String signature, String[] exceptions) {
+ if (cv != null) {
+ return cv.visitMethod(access, name, desc, signature, exceptions);
+ }
+ return null;
+ }
/**
* Visits the end of the class. This method, which is the last one to be
* called, is used to inform the visitor that all the fields and methods of
* the class have been visited.
*/
- void visitEnd();
+ public void visitEnd() {
+ if (cv != null) {
+ cv.visitEnd();
+ }
+ }
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
index dc16736b6..43d55d174 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,10 +35,10 @@
* file format. It can be used alone, to generate a Java class "from scratch",
* or with one or more {@link ClassReader ClassReader} and adapter class visitor
* to generate a modified class from one or more existing Java classes.
- *
+ *
* @author Eric Bruneton
*/
-public class ClassWriter implements ClassVisitor {
+public class ClassWriter extends ClassVisitor {
/**
* Flag to automatically compute the maximum stack size and the maximum
@@ -47,7 +47,7 @@ public class ClassWriter implements ClassVisitor {
* {@link MethodVisitor} returned by the {@link #visitMethod visitMethod}
* method will be ignored, and computed automatically from the signature and
* the bytecode of each method.
- *
+ *
* @see #ClassWriter(int)
*/
public static final int COMPUTE_MAXS = 1;
@@ -60,11 +60,23 @@ public class ClassWriter implements ClassVisitor {
* {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
* recomputed from the bytecode. In other words, computeFrames implies
* computeMaxs.
- *
+ *
* @see #ClassWriter(int)
*/
public static final int COMPUTE_FRAMES = 2;
+ /**
+ * Pseudo access flag to distinguish between the synthetic attribute and the
+ * synthetic access flag.
+ */
+ static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
+
+ /**
+ * Factor to convert from ACC_SYNTHETIC_ATTRIBUTE to Opcode.ACC_SYNTHETIC.
+ */
+ static final int TO_ACC_SYNTHETIC = ACC_SYNTHETIC_ATTRIBUTE
+ / Opcodes.ACC_SYNTHETIC;
+
/**
* The type of instructions without any argument.
*/
@@ -101,54 +113,59 @@ public class ClassWriter implements ClassVisitor {
static final int FIELDORMETH_INSN = 6;
/**
- * The type of the INVOKEINTERFACE instruction.
+ * The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction.
*/
static final int ITFMETH_INSN = 7;
+ /**
+ * The type of the INVOKEDYNAMIC instruction.
+ */
+ static final int INDYMETH_INSN = 8;
+
/**
* The type of instructions with a 2 bytes bytecode offset label.
*/
- static final int LABEL_INSN = 8;
+ static final int LABEL_INSN = 9;
/**
* The type of instructions with a 4 bytes bytecode offset label.
*/
- static final int LABELW_INSN = 9;
+ static final int LABELW_INSN = 10;
/**
* The type of the LDC instruction.
*/
- static final int LDC_INSN = 10;
+ static final int LDC_INSN = 11;
/**
* The type of the LDC_W and LDC2_W instructions.
*/
- static final int LDCW_INSN = 11;
+ static final int LDCW_INSN = 12;
/**
* The type of the IINC instruction.
*/
- static final int IINC_INSN = 12;
+ static final int IINC_INSN = 13;
/**
* The type of the TABLESWITCH instruction.
*/
- static final int TABL_INSN = 13;
+ static final int TABL_INSN = 14;
/**
* The type of the LOOKUPSWITCH instruction.
*/
- static final int LOOK_INSN = 14;
+ static final int LOOK_INSN = 15;
/**
* The type of the MULTIANEWARRAY instruction.
*/
- static final int MANA_INSN = 15;
+ static final int MANA_INSN = 16;
/**
* The type of the WIDE instruction.
*/
- static final int WIDE_INSN = 16;
+ static final int WIDE_INSN = 17;
/**
* The instruction types of all JVM opcodes.
@@ -210,12 +227,34 @@ public class ClassWriter implements ClassVisitor {
*/
static final int UTF8 = 1;
+ /**
+ * The type of CONSTANT_MethodType constant pool items.
+ */
+ static final int MTYPE = 16;
+
+ /**
+ * The type of CONSTANT_MethodHandle constant pool items.
+ */
+ static final int HANDLE = 15;
+
+ /**
+ * The type of CONSTANT_InvokeDynamic constant pool items.
+ */
+ static final int INDY = 18;
+
+ /**
+ * The base value for all CONSTANT_MethodHandle constant pool items.
+ * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
+ * different items.
+ */
+ static final int HANDLE_BASE = 20;
+
/**
* Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
* instead of the constant pool, in order to avoid clashes with normal
* constant pool items in the ClassWriter constant pool's hash table.
*/
- static final int TYPE_NORMAL = 13;
+ static final int TYPE_NORMAL = 30;
/**
* Uninitialized type Item stored in the ClassWriter
@@ -223,14 +262,20 @@ public class ClassWriter implements ClassVisitor {
* avoid clashes with normal constant pool items in the ClassWriter constant
* pool's hash table.
*/
- static final int TYPE_UNINIT = 14;
+ static final int TYPE_UNINIT = 31;
/**
* Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
* instead of the constant pool, in order to avoid clashes with normal
* constant pool items in the ClassWriter constant pool's hash table.
*/
- static final int TYPE_MERGED = 15;
+ static final int TYPE_MERGED = 32;
+
+ /**
+ * The type of BootstrapMethods items. These items are stored in a special
+ * class attribute named BootstrapMethods and not in the constant pool.
+ */
+ static final int BSM = 33;
/**
* The class reader from which this class writer was constructed, if any.
@@ -277,15 +322,20 @@ public class ClassWriter implements ClassVisitor {
*/
final Item key3;
+ /**
+ * A reusable key used to look for items in the {@link #items} hash table.
+ */
+ final Item key4;
+
/**
* A type table used to temporarily store internal names that will not
* necessarily be stored in the constant pool. This type table is used by
* the control flow and data flow analysis algorithm used to compute stack
* map frames from scratch. This array associates to each index i
- * the Item whose index is i. All Item objects stored in this
- * array are also stored in the {@link #items} hash table. These two arrays
- * allow to retrieve an Item from its index or, conversely, to get the index
- * of an Item from its value. Each Item stores an internal name in its
+ * the Item whose index is i. All Item objects stored in this array
+ * are also stored in the {@link #items} hash table. These two arrays allow
+ * to retrieve an Item from its index or, conversely, to get the index of an
+ * Item from its value. Each Item stores an internal name in its
* {@link Item#strVal1} field.
*/
Item[] typeTable;
@@ -366,6 +416,16 @@ public class ClassWriter implements ClassVisitor {
*/
private AnnotationWriter ianns;
+ /**
+ * The runtime visible type annotations of this class.
+ */
+ private AnnotationWriter tanns;
+
+ /**
+ * The runtime invisible type annotations of this class.
+ */
+ private AnnotationWriter itanns;
+
/**
* The non standard attributes of this class.
*/
@@ -381,26 +441,36 @@ public class ClassWriter implements ClassVisitor {
*/
private ByteVector innerClasses;
+ /**
+ * The number of entries in the BootstrapMethods attribute.
+ */
+ int bootstrapMethodsCount;
+
+ /**
+ * The BootstrapMethods attribute.
+ */
+ ByteVector bootstrapMethods;
+
/**
* The fields of this class. These fields are stored in a linked list of
* {@link FieldWriter} objects, linked to each other by their
- * {@link FieldWriter#next} field. This field stores the first element of
- * this list.
+ * {@link FieldWriter#fv} field. This field stores the first element of this
+ * list.
*/
FieldWriter firstField;
/**
* The fields of this class. These fields are stored in a linked list of
* {@link FieldWriter} objects, linked to each other by their
- * {@link FieldWriter#next} field. This field stores the last element of
- * this list.
+ * {@link FieldWriter#fv} field. This field stores the last element of this
+ * list.
*/
FieldWriter lastField;
/**
* The methods of this class. These methods are stored in a linked list of
* {@link MethodWriter} objects, linked to each other by their
- * {@link MethodWriter#next} field. This field stores the first element of
+ * {@link MethodWriter#mv} field. This field stores the first element of
* this list.
*/
MethodWriter firstMethod;
@@ -408,8 +478,8 @@ public class ClassWriter implements ClassVisitor {
/**
* The methods of this class. These methods are stored in a linked list of
* {@link MethodWriter} objects, linked to each other by their
- * {@link MethodWriter#next} field. This field stores the last element of
- * this list.
+ * {@link MethodWriter#mv} field. This field stores the last element of this
+ * list.
*/
MethodWriter lastMethod;
@@ -417,12 +487,12 @@ public class ClassWriter implements ClassVisitor {
* true if the maximum stack size and number of local variables
* must be automatically computed.
*/
- private final boolean computeMaxs;
+ private boolean computeMaxs;
/**
* true if the stack map frames must be recomputed from scratch.
*/
- private final boolean computeFrames;
+ private boolean computeFrames;
/**
* true if the stack map tables of this class are invalid. The
@@ -444,10 +514,10 @@ public class ClassWriter implements ClassVisitor {
static {
int i;
byte[] b = new byte[220];
- String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+ String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+ "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
- + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA"
- + "AAAAGGGGGGGHAFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII";
+ + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
+ + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
for (i = 0; i < b.length; ++i) {
b[i] = (byte) (s.charAt(i) - 'A');
}
@@ -488,6 +558,7 @@ public class ClassWriter implements ClassVisitor {
// b[i] = FIELDORMETH_INSN;
// }
// b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
+ // b[Constants.INVOKEDYNAMIC] = INDYMETH_INSN;
//
// // LABEL(W)_INSN instructions
// for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
@@ -527,11 +598,14 @@ public class ClassWriter implements ClassVisitor {
/**
* Constructs a new {@link ClassWriter} object.
- *
- * @param flags option flags that can be used to modify the default behavior
- * of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
+ *
+ * @param flags
+ * option flags that can be used to modify the default behavior
+ * of this class. See {@link #COMPUTE_MAXS},
+ * {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final int flags) {
+ super(Opcodes.ASM5);
index = 1;
pool = new ByteVector();
items = new Item[256];
@@ -539,6 +613,7 @@ public ClassWriter(final int flags) {
key = new Item();
key2 = new Item();
key3 = new Item();
+ key4 = new Item();
this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
}
@@ -547,25 +622,33 @@ public ClassWriter(final int flags) {
* Constructs a new {@link ClassWriter} object and enables optimizations for
* "mostly add" bytecode transformations. These optimizations are the
* following:
- *
- *
The constant pool from the original class is copied as is in
- * the new class, which saves time. New constant pool entries will be added
- * at the end if necessary, but unused constant pool entries won't be
- * removed.
Methods that are not transformed are copied as
- * is in the new class, directly from the original class bytecode (i.e.
- * without emitting visit events for all the method instructions), which
- * saves a lot of time. Untransformed methods are detected by the
- * fact that the {@link ClassReader} receives {@link MethodVisitor} objects
- * that come from a {@link ClassWriter} (and not from a custom
- * {@link ClassAdapter} or any other {@link ClassVisitor} instance).
+ *
+ *
+ *
The constant pool from the original class is copied as is in the new
+ * class, which saves time. New constant pool entries will be added at the
+ * end if necessary, but unused constant pool entries won't be
+ * removed.
+ *
Methods that are not transformed are copied as is in the new class,
+ * directly from the original class bytecode (i.e. without emitting visit
+ * events for all the method instructions), which saves a lot of
+ * time. Untransformed methods are detected by the fact that the
+ * {@link ClassReader} receives {@link MethodVisitor} objects that come from
+ * a {@link ClassWriter} (and not from any other {@link ClassVisitor}
+ * instance).
*
- *
- * @param classReader the {@link ClassReader} used to read the original
- * class. It will be used to copy the entire constant pool from the
- * original class and also to copy other fragments of original
- * bytecode where applicable.
- * @param flags option flags that can be used to modify the default behavior
- * of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
+ *
+ * @param classReader
+ * the {@link ClassReader} used to read the original class. It
+ * will be used to copy the entire constant pool from the
+ * original class and also to copy other fragments of original
+ * bytecode where applicable.
+ * @param flags
+ * option flags that can be used to modify the default behavior
+ * of this class. These option flags do not affect methods
+ * that are copied as is in the new class. This means that the
+ * maximum stack size nor the stack frames will be computed for
+ * these methods. See {@link #COMPUTE_MAXS},
+ * {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final ClassReader classReader, final int flags) {
this(flags);
@@ -574,17 +657,13 @@ public ClassWriter(final ClassReader classReader, final int flags) {
}
// ------------------------------------------------------------------------
- // Implementation of the ClassVisitor interface
+ // Implementation of the ClassVisitor abstract class
// ------------------------------------------------------------------------
- public void visit(
- final int version,
- final int access,
- final String name,
- final String signature,
- final String superName,
- final String[] interfaces)
- {
+ @Override
+ public final void visit(final int version, final int access,
+ final String name, final String signature, final String superName,
+ final String[] interfaces) {
this.version = version;
this.access = access;
this.name = newClass(name);
@@ -602,7 +681,8 @@ public void visit(
}
}
- public void visitSource(final String file, final String debug) {
+ @Override
+ public final void visitSource(final String file, final String debug) {
if (file != null) {
sourceFile = newUTF8(file);
}
@@ -611,21 +691,18 @@ public void visitSource(final String file, final String debug) {
}
}
- public void visitOuterClass(
- final String owner,
- final String name,
- final String desc)
- {
+ @Override
+ public final void visitOuterClass(final String owner, final String name,
+ final String desc) {
enclosingMethodOwner = newClass(owner);
if (name != null && desc != null) {
enclosingMethod = newNameType(name, desc);
}
}
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ @Override
+ public final AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
if (!ClassReader.ANNOTATIONS) {
return null;
}
@@ -643,17 +720,38 @@ public AnnotationVisitor visitAnnotation(
return aw;
}
- public void visitAttribute(final Attribute attr) {
+ @Override
+ public final AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, final String desc, final boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = tanns;
+ tanns = aw;
+ } else {
+ aw.next = itanns;
+ itanns = aw;
+ }
+ return aw;
+ }
+
+ @Override
+ public final void visitAttribute(final Attribute attr) {
attr.next = attrs;
attrs = attr;
}
- public void visitInnerClass(
- final String name,
- final String outerName,
- final String innerName,
- final int access)
- {
+ @Override
+ public final void visitInnerClass(final String name,
+ final String outerName, final String innerName, final int access) {
if (innerClasses == null) {
innerClasses = new ByteVector();
}
@@ -664,34 +762,21 @@ public void visitInnerClass(
innerClasses.putShort(access);
}
- public FieldVisitor visitField(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ @Override
+ public final FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
return new FieldWriter(this, access, name, desc, signature, value);
}
- public MethodVisitor visitMethod(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
- return new MethodWriter(this,
- access,
- name,
- desc,
- signature,
- exceptions,
- computeMaxs,
- computeFrames);
+ @Override
+ public final MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
+ return new MethodWriter(this, access, name, desc, signature,
+ exceptions, computeMaxs, computeFrames);
}
- public void visitEnd() {
+ @Override
+ public final void visitEnd() {
}
// ------------------------------------------------------------------------
@@ -700,10 +785,13 @@ public void visitEnd() {
/**
* Returns the bytecode of the class that was build with this class writer.
- *
+ *
* @return the bytecode of the class that was build with this class writer.
*/
public byte[] toByteArray() {
+ if (index > 0xFFFF) {
+ throw new RuntimeException("Class file too large!");
+ }
// computes the real size of the bytecode of this class
int size = 24 + 2 * interfaceCount;
int nbFields = 0;
@@ -711,16 +799,23 @@ public byte[] toByteArray() {
while (fb != null) {
++nbFields;
size += fb.getSize();
- fb = fb.next;
+ fb = (FieldWriter) fb.fv;
}
int nbMethods = 0;
MethodWriter mb = firstMethod;
while (mb != null) {
++nbMethods;
size += mb.getSize();
- mb = mb.next;
+ mb = (MethodWriter) mb.mv;
}
int attributeCount = 0;
+ if (bootstrapMethods != null) {
+ // we put it as first attribute in order to improve a bit
+ // ClassReader.copyBootstrapMethods
+ ++attributeCount;
+ size += 8 + bootstrapMethods.length;
+ newUTF8("BootstrapMethods");
+ }
if (ClassReader.SIGNATURES && signature != 0) {
++attributeCount;
size += 8;
@@ -746,12 +841,13 @@ public byte[] toByteArray() {
size += 6;
newUTF8("Deprecated");
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && (version & 0xffff) < Opcodes.V1_5)
- {
- ++attributeCount;
- size += 6;
- newUTF8("Synthetic");
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((version & 0xFFFF) < Opcodes.V1_5
+ || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ ++attributeCount;
+ size += 6;
+ newUTF8("Synthetic");
+ }
}
if (innerClasses != null) {
++attributeCount;
@@ -768,6 +864,16 @@ public byte[] toByteArray() {
size += 8 + ianns.getSize();
newUTF8("RuntimeInvisibleAnnotations");
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ ++attributeCount;
+ size += 8 + tanns.getSize();
+ newUTF8("RuntimeVisibleTypeAnnotations");
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ ++attributeCount;
+ size += 8 + itanns.getSize();
+ newUTF8("RuntimeInvisibleTypeAnnotations");
+ }
if (attrs != null) {
attributeCount += attrs.getCount();
size += attrs.getSize(this, null, 0, -1, -1);
@@ -778,7 +884,9 @@ public byte[] toByteArray() {
ByteVector out = new ByteVector(size);
out.putInt(0xCAFEBABE).putInt(version);
out.putShort(index).putByteArray(pool.data, 0, pool.length);
- out.putShort(access).putShort(name).putShort(superName);
+ int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE
+ | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC);
+ out.putShort(access & ~mask).putShort(name).putShort(superName);
out.putShort(interfaceCount);
for (int i = 0; i < interfaceCount; ++i) {
out.putShort(interfaces[i]);
@@ -787,15 +895,21 @@ public byte[] toByteArray() {
fb = firstField;
while (fb != null) {
fb.put(out);
- fb = fb.next;
+ fb = (FieldWriter) fb.fv;
}
out.putShort(nbMethods);
mb = firstMethod;
while (mb != null) {
mb.put(out);
- mb = mb.next;
+ mb = (MethodWriter) mb.mv;
}
out.putShort(attributeCount);
+ if (bootstrapMethods != null) {
+ out.putShort(newUTF8("BootstrapMethods"));
+ out.putInt(bootstrapMethods.length + 2).putShort(
+ bootstrapMethodsCount);
+ out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
+ }
if (ClassReader.SIGNATURES && signature != 0) {
out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
}
@@ -814,10 +928,11 @@ public byte[] toByteArray() {
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(newUTF8("Deprecated")).putInt(0);
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && (version & 0xffff) < Opcodes.V1_5)
- {
- out.putShort(newUTF8("Synthetic")).putInt(0);
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((version & 0xFFFF) < Opcodes.V1_5
+ || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ out.putShort(newUTF8("Synthetic")).putInt(0);
+ }
}
if (innerClasses != null) {
out.putShort(newUTF8("InnerClasses"));
@@ -832,13 +947,34 @@ public byte[] toByteArray() {
out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
+ tanns.put(out);
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
+ itanns.put(out);
+ }
if (attrs != null) {
attrs.put(this, null, 0, -1, -1, out);
}
if (invalidFrames) {
- ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
- new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES);
- return cw.toByteArray();
+ anns = null;
+ ianns = null;
+ attrs = null;
+ innerClassesCount = 0;
+ innerClasses = null;
+ bootstrapMethodsCount = 0;
+ bootstrapMethods = null;
+ firstField = null;
+ lastField = null;
+ firstMethod = null;
+ lastMethod = null;
+ computeMaxs = false;
+ computeFrames = true;
+ invalidFrames = false;
+ new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
+ return toByteArray();
}
return out.data;
}
@@ -850,11 +986,12 @@ public byte[] toByteArray() {
/**
* Adds a number or string constant to the constant pool of the class being
* build. Does nothing if the constant pool already contains a similar item.
- *
- * @param cst the value of the constant to be added to the constant pool.
- * This parameter must be an {@link Integer}, a {@link Float}, a
- * {@link Long}, a {@link Double}, a {@link String} or a
- * {@link Type}.
+ *
+ * @param cst
+ * the value of the constant to be added to the constant pool.
+ * This parameter must be an {@link Integer}, a {@link Float}, a
+ * {@link Long}, a {@link Double}, a {@link String} or a
+ * {@link Type}.
* @return a new or already existing constant item with the given value.
*/
Item newConstItem(final Object cst) {
@@ -886,9 +1023,17 @@ Item newConstItem(final Object cst) {
return newString((String) cst);
} else if (cst instanceof Type) {
Type t = (Type) cst;
- return newClassItem(t.getSort() == Type.OBJECT
- ? t.getInternalName()
- : t.getDescriptor());
+ int s = t.getSort();
+ if (s == Type.OBJECT) {
+ return newClassItem(t.getInternalName());
+ } else if (s == Type.METHOD) {
+ return newMethodTypeItem(t.getDescriptor());
+ } else { // s == primitive type or array
+ return newClassItem(t.getDescriptor());
+ }
+ } else if (cst instanceof Handle) {
+ Handle h = (Handle) cst;
+ return newHandleItem(h.tag, h.owner, h.name, h.desc);
} else {
throw new IllegalArgumentException("value " + cst);
}
@@ -899,10 +1044,11 @@ Item newConstItem(final Object cst) {
* build. Does nothing if the constant pool already contains a similar item.
* This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
- *
- * @param cst the value of the constant to be added to the constant pool.
- * This parameter must be an {@link Integer}, a {@link Float}, a
- * {@link Long}, a {@link Double} or a {@link String}.
+ *
+ * @param cst
+ * the value of the constant to be added to the constant pool.
+ * This parameter must be an {@link Integer}, a {@link Float}, a
+ * {@link Long}, a {@link Double} or a {@link String}.
* @return the index of a new or already existing constant item with the
* given value.
*/
@@ -915,8 +1061,9 @@ public int newConst(final Object cst) {
* nothing if the constant pool already contains a similar item. This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.
- *
- * @param value the String value.
+ *
+ * @param value
+ * the String value.
* @return the index of a new or already existing UTF8 item.
*/
public int newUTF8(final String value) {
@@ -935,8 +1082,9 @@ public int newUTF8(final String value) {
* Does nothing if the constant pool already contains a similar item.
* This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
- *
- * @param value the internal name of the class.
+ *
+ * @param value
+ * the internal name of the class.
* @return a new or already existing class reference item.
*/
Item newClassItem(final String value) {
@@ -955,25 +1103,240 @@ Item newClassItem(final String value) {
* Does nothing if the constant pool already contains a similar item.
* This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
- *
- * @param value the internal name of the class.
+ *
+ * @param value
+ * the internal name of the class.
* @return the index of a new or already existing class reference item.
*/
public int newClass(final String value) {
return newClassItem(value).index;
}
+ /**
+ * Adds a method type reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.
+ *
+ * @param methodDesc
+ * method descriptor of the method type.
+ * @return a new or already existing method type reference item.
+ */
+ Item newMethodTypeItem(final String methodDesc) {
+ key2.set(MTYPE, methodDesc, null, null);
+ Item result = get(key2);
+ if (result == null) {
+ pool.put12(MTYPE, newUTF8(methodDesc));
+ result = new Item(index++, key2);
+ put(result);
+ }
+ return result;
+ }
+
+ /**
+ * Adds a method type reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.
+ *
+ * @param methodDesc
+ * method descriptor of the method type.
+ * @return the index of a new or already existing method type reference
+ * item.
+ */
+ public int newMethodType(final String methodDesc) {
+ return newMethodTypeItem(methodDesc).index;
+ }
+
+ /**
+ * Adds a handle to the constant pool of the class being build. Does nothing
+ * if the constant pool already contains a similar item. This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.
+ *
+ * @param tag
+ * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+ * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+ * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+ * {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner
+ * the internal name of the field or method owner class.
+ * @param name
+ * the name of the field or method.
+ * @param desc
+ * the descriptor of the field or method.
+ * @return a new or an already existing method type reference item.
+ */
+ Item newHandleItem(final int tag, final String owner, final String name,
+ final String desc) {
+ key4.set(HANDLE_BASE + tag, owner, name, desc);
+ Item result = get(key4);
+ if (result == null) {
+ if (tag <= Opcodes.H_PUTSTATIC) {
+ put112(HANDLE, tag, newField(owner, name, desc));
+ } else {
+ put112(HANDLE,
+ tag,
+ newMethod(owner, name, desc,
+ tag == Opcodes.H_INVOKEINTERFACE));
+ }
+ result = new Item(index++, key4);
+ put(result);
+ }
+ return result;
+ }
+
+ /**
+ * Adds a handle to the constant pool of the class being build. Does nothing
+ * if the constant pool already contains a similar item. This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.
+ *
+ * @param tag
+ * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+ * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+ * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+ * {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner
+ * the internal name of the field or method owner class.
+ * @param name
+ * the name of the field or method.
+ * @param desc
+ * the descriptor of the field or method.
+ * @return the index of a new or already existing method type reference
+ * item.
+ */
+ public int newHandle(final int tag, final String owner, final String name,
+ final String desc) {
+ return newHandleItem(tag, owner, name, desc).index;
+ }
+
+ /**
+ * Adds an invokedynamic reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.
+ *
+ * @param name
+ * name of the invoked method.
+ * @param desc
+ * descriptor of the invoke method.
+ * @param bsm
+ * the bootstrap method.
+ * @param bsmArgs
+ * the bootstrap method constant arguments.
+ *
+ * @return a new or an already existing invokedynamic type reference item.
+ */
+ Item newInvokeDynamicItem(final String name, final String desc,
+ final Handle bsm, final Object... bsmArgs) {
+ // cache for performance
+ ByteVector bootstrapMethods = this.bootstrapMethods;
+ if (bootstrapMethods == null) {
+ bootstrapMethods = this.bootstrapMethods = new ByteVector();
+ }
+
+ int position = bootstrapMethods.length; // record current position
+
+ int hashCode = bsm.hashCode();
+ bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
+ bsm.desc));
+
+ int argsLength = bsmArgs.length;
+ bootstrapMethods.putShort(argsLength);
+
+ for (int i = 0; i < argsLength; i++) {
+ Object bsmArg = bsmArgs[i];
+ hashCode ^= bsmArg.hashCode();
+ bootstrapMethods.putShort(newConst(bsmArg));
+ }
+
+ byte[] data = bootstrapMethods.data;
+ int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
+ hashCode &= 0x7FFFFFFF;
+ Item result = items[hashCode % items.length];
+ loop: while (result != null) {
+ if (result.type != BSM || result.hashCode != hashCode) {
+ result = result.next;
+ continue;
+ }
+
+ // because the data encode the size of the argument
+ // we don't need to test if these size are equals
+ int resultPosition = result.intVal;
+ for (int p = 0; p < length; p++) {
+ if (data[position + p] != data[resultPosition + p]) {
+ result = result.next;
+ continue loop;
+ }
+ }
+ break;
+ }
+
+ int bootstrapMethodIndex;
+ if (result != null) {
+ bootstrapMethodIndex = result.index;
+ bootstrapMethods.length = position; // revert to old position
+ } else {
+ bootstrapMethodIndex = bootstrapMethodsCount++;
+ result = new Item(bootstrapMethodIndex);
+ result.set(position, hashCode);
+ put(result);
+ }
+
+ // now, create the InvokeDynamic constant
+ key3.set(name, desc, bootstrapMethodIndex);
+ result = get(key3);
+ if (result == null) {
+ put122(INDY, bootstrapMethodIndex, newNameType(name, desc));
+ result = new Item(index++, key3);
+ put(result);
+ }
+ return result;
+ }
+
+ /**
+ * Adds an invokedynamic reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.
+ *
+ * @param name
+ * name of the invoked method.
+ * @param desc
+ * descriptor of the invoke method.
+ * @param bsm
+ * the bootstrap method.
+ * @param bsmArgs
+ * the bootstrap method constant arguments.
+ *
+ * @return the index of a new or already existing invokedynamic reference
+ * item.
+ */
+ public int newInvokeDynamic(final String name, final String desc,
+ final Handle bsm, final Object... bsmArgs) {
+ return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index;
+ }
+
/**
* Adds a field reference to the constant pool of the class being build.
* Does nothing if the constant pool already contains a similar item.
- *
- * @param owner the internal name of the field's owner class.
- * @param name the field's name.
- * @param desc the field's descriptor.
+ *
+ * @param owner
+ * the internal name of the field's owner class.
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor.
* @return a new or already existing field reference item.
*/
- Item newFieldItem(final String owner, final String name, final String desc)
- {
+ Item newFieldItem(final String owner, final String name, final String desc) {
key3.set(FIELD, owner, name, desc);
Item result = get(key3);
if (result == null) {
@@ -989,33 +1352,35 @@ Item newFieldItem(final String owner, final String name, final String desc)
* Does nothing if the constant pool already contains a similar item.
* This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
- *
- * @param owner the internal name of the field's owner class.
- * @param name the field's name.
- * @param desc the field's descriptor.
+ *
+ * @param owner
+ * the internal name of the field's owner class.
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor.
* @return the index of a new or already existing field reference item.
*/
- public int newField(final String owner, final String name, final String desc)
- {
+ public int newField(final String owner, final String name, final String desc) {
return newFieldItem(owner, name, desc).index;
}
/**
* Adds a method reference to the constant pool of the class being build.
* Does nothing if the constant pool already contains a similar item.
- *
- * @param owner the internal name of the method's owner class.
- * @param name the method's name.
- * @param desc the method's descriptor.
- * @param itf true if owner is an interface.
+ *
+ * @param owner
+ * the internal name of the method's owner class.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor.
+ * @param itf
+ * true if owner is an interface.
* @return a new or already existing method reference item.
*/
- Item newMethodItem(
- final String owner,
- final String name,
- final String desc,
- final boolean itf)
- {
+ Item newMethodItem(final String owner, final String name,
+ final String desc, final boolean itf) {
int type = itf ? IMETH : METH;
key3.set(type, owner, name, desc);
Item result = get(key3);
@@ -1032,27 +1397,28 @@ Item newMethodItem(
* Does nothing if the constant pool already contains a similar item.
* This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
- *
- * @param owner the internal name of the method's owner class.
- * @param name the method's name.
- * @param desc the method's descriptor.
- * @param itf true if owner is an interface.
+ *
+ * @param owner
+ * the internal name of the method's owner class.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor.
+ * @param itf
+ * true if owner is an interface.
* @return the index of a new or already existing method reference item.
*/
- public int newMethod(
- final String owner,
- final String name,
- final String desc,
- final boolean itf)
- {
+ public int newMethod(final String owner, final String name,
+ final String desc, final boolean itf) {
return newMethodItem(owner, name, desc, itf).index;
}
/**
* Adds an integer to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item.
- *
- * @param value the int value.
+ *
+ * @param value
+ * the int value.
* @return a new or already existing int item.
*/
Item newInteger(final int value) {
@@ -1069,8 +1435,9 @@ Item newInteger(final int value) {
/**
* Adds a float to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
- *
- * @param value the float value.
+ *
+ * @param value
+ * the float value.
* @return a new or already existing float item.
*/
Item newFloat(final float value) {
@@ -1087,8 +1454,9 @@ Item newFloat(final float value) {
/**
* Adds a long to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
- *
- * @param value the long value.
+ *
+ * @param value
+ * the long value.
* @return a new or already existing long item.
*/
Item newLong(final long value) {
@@ -1097,8 +1465,8 @@ Item newLong(final long value) {
if (result == null) {
pool.putByte(LONG).putLong(value);
result = new Item(index, key);
- put(result);
index += 2;
+ put(result);
}
return result;
}
@@ -1106,8 +1474,9 @@ Item newLong(final long value) {
/**
* Adds a double to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
- *
- * @param value the double value.
+ *
+ * @param value
+ * the double value.
* @return a new or already existing double item.
*/
Item newDouble(final double value) {
@@ -1116,8 +1485,8 @@ Item newDouble(final double value) {
if (result == null) {
pool.putByte(DOUBLE).putLong(key.longVal);
result = new Item(index, key);
- put(result);
index += 2;
+ put(result);
}
return result;
}
@@ -1125,8 +1494,9 @@ Item newDouble(final double value) {
/**
* Adds a string to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
- *
- * @param value the String value.
+ *
+ * @param value
+ * the String value.
* @return a new or already existing string item.
*/
private Item newString(final String value) {
@@ -1145,12 +1515,28 @@ private Item newString(final String value) {
* nothing if the constant pool already contains a similar item. This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.
- *
- * @param name a name.
- * @param desc a type descriptor.
+ *
+ * @param name
+ * a name.
+ * @param desc
+ * a type descriptor.
* @return the index of a new or already existing name and type item.
*/
public int newNameType(final String name, final String desc) {
+ return newNameTypeItem(name, desc).index;
+ }
+
+ /**
+ * Adds a name and type to the constant pool of the class being build. Does
+ * nothing if the constant pool already contains a similar item.
+ *
+ * @param name
+ * a name.
+ * @param desc
+ * a type descriptor.
+ * @return a new or already existing name and type item.
+ */
+ Item newNameTypeItem(final String name, final String desc) {
key2.set(NAME_TYPE, name, desc, null);
Item result = get(key2);
if (result == null) {
@@ -1158,14 +1544,15 @@ public int newNameType(final String name, final String desc) {
result = new Item(index++, key2);
put(result);
}
- return result.index;
+ return result;
}
/**
* Adds the given internal name to {@link #typeTable} and returns its index.
* Does nothing if the type table already contains this internal name.
- *
- * @param type the internal name to be added to the type table.
+ *
+ * @param type
+ * the internal name to be added to the type table.
* @return the index of this internal name in the type table.
*/
int addType(final String type) {
@@ -1181,10 +1568,12 @@ int addType(final String type) {
* Adds the given "uninitialized" type to {@link #typeTable} and returns its
* index. This method is used for UNINITIALIZED types, made of an internal
* name and a bytecode offset.
- *
- * @param type the internal name to be added to the type table.
- * @param offset the bytecode offset of the NEW instruction that created
- * this UNINITIALIZED type value.
+ *
+ * @param type
+ * the internal name to be added to the type table.
+ * @param offset
+ * the bytecode offset of the NEW instruction that created this
+ * UNINITIALIZED type value.
* @return the index of this internal name in the type table.
*/
int addUninitializedType(final String type, final int offset) {
@@ -1201,8 +1590,9 @@ int addUninitializedType(final String type, final int offset) {
/**
* Adds the given Item to {@link #typeTable}.
- *
- * @param item the value to be added to the type table.
+ *
+ * @param item
+ * the value to be added to the type table.
* @return the added Item, which a new Item instance with the same value as
* the given Item.
*/
@@ -1227,9 +1617,11 @@ private Item addType(final Item item) {
* method calls {@link #getCommonSuperClass} and caches the result in the
* {@link #items} hash table to speedup future calls with the same
* parameters.
- *
- * @param type1 index of an internal name in {@link #typeTable}.
- * @param type2 index of an internal name in {@link #typeTable}.
+ *
+ * @param type1
+ * index of an internal name in {@link #typeTable}.
+ * @param type2
+ * index of an internal name in {@link #typeTable}.
* @return the index of the common super type of the two given types.
*/
int getMergedType(final int type1, final int type2) {
@@ -1249,24 +1641,26 @@ int getMergedType(final int type1, final int type2) {
/**
* Returns the common super type of the two given types. The default
- * implementation of this method loads the two given classes and uses
+ * implementation of this method loads the two given classes and uses
* the java.lang.Class methods to find the common super class. It can be
* overridden to compute this common super type in other ways, in particular
* without actually loading any class, or to take into account the class
* that is currently being generated by this ClassWriter, which can of
* course not be loaded since it is under construction.
- *
- * @param type1 the internal name of a class.
- * @param type2 the internal name of another class.
+ *
+ * @param type1
+ * the internal name of a class.
+ * @param type2
+ * the internal name of another class.
* @return the internal name of the common super class of the two given
* classes.
*/
- protected String getCommonSuperClass(final String type1, final String type2)
- {
- Class c, d;
+ protected String getCommonSuperClass(final String type1, final String type2) {
+ Class> c, d;
+ ClassLoader classLoader = getClass().getClassLoader();
try {
- c = Class.forName(type1.replace('/', '.'));
- d = Class.forName(type2.replace('/', '.'));
+ c = Class.forName(type1.replace('/', '.'), false, classLoader);
+ d = Class.forName(type2.replace('/', '.'), false, classLoader);
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
@@ -1289,14 +1683,15 @@ protected String getCommonSuperClass(final String type1, final String type2)
/**
* Returns the constant pool's hash table item which is equal to the given
* item.
- *
- * @param key a constant pool item.
+ *
+ * @param key
+ * a constant pool item.
* @return the constant pool's hash table item which is equal to the given
* item, or null if there is no such item.
*/
private Item get(final Item key) {
Item i = items[key.hashCode % items.length];
- while (i != null && !key.isEqualTo(i)) {
+ while (i != null && (i.type != key.type || !key.isEqualTo(i))) {
i = i.next;
}
return i;
@@ -1305,11 +1700,12 @@ private Item get(final Item key) {
/**
* Puts the given item in the constant pool's hash table. The hash table
* must not already contains this item.
- *
- * @param i the item to be added to the constant pool's hash table.
+ *
+ * @param i
+ * the item to be added to the constant pool's hash table.
*/
private void put(final Item i) {
- if (index > threshold) {
+ if (index + typeCount > threshold) {
int ll = items.length;
int nl = ll * 2 + 1;
Item[] newItems = new Item[nl];
@@ -1333,12 +1729,29 @@ private void put(final Item i) {
/**
* Puts one byte and two shorts into the constant pool.
- *
- * @param b a byte.
- * @param s1 a short.
- * @param s2 another short.
+ *
+ * @param b
+ * a byte.
+ * @param s1
+ * a short.
+ * @param s2
+ * another short.
*/
private void put122(final int b, final int s1, final int s2) {
pool.put12(b, s1).putShort(s2);
}
+
+ /**
+ * Puts two bytes and one short into the constant pool.
+ *
+ * @param b1
+ * a byte.
+ * @param b2
+ * another byte.
+ * @param s
+ * a short.
+ */
+ private void put112(final int b1, final int b2, final int s) {
+ pool.put11(b1, b2).putShort(s);
+ }
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Context.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Context.java
new file mode 100644
index 000000000..a4034f933
--- /dev/null
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Context.java
@@ -0,0 +1,145 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jersey.repackaged.org.objectweb.asm;
+
+/**
+ * Information about a class being parsed in a {@link ClassReader}.
+ *
+ * @author Eric Bruneton
+ */
+class Context {
+
+ /**
+ * Prototypes of the attributes that must be parsed for this class.
+ */
+ Attribute[] attrs;
+
+ /**
+ * The {@link ClassReader} option flags for the parsing of this class.
+ */
+ int flags;
+
+ /**
+ * The buffer used to read strings.
+ */
+ char[] buffer;
+
+ /**
+ * The start index of each bootstrap method.
+ */
+ int[] bootstrapMethods;
+
+ /**
+ * The access flags of the method currently being parsed.
+ */
+ int access;
+
+ /**
+ * The name of the method currently being parsed.
+ */
+ String name;
+
+ /**
+ * The descriptor of the method currently being parsed.
+ */
+ String desc;
+
+ /**
+ * The label objects, indexed by bytecode offset, of the method currently
+ * being parsed (only bytecode offsets for which a label is needed have a
+ * non null associated Label object).
+ */
+ Label[] labels;
+
+ /**
+ * The target of the type annotation currently being parsed.
+ */
+ int typeRef;
+
+ /**
+ * The path of the type annotation currently being parsed.
+ */
+ TypePath typePath;
+
+ /**
+ * The offset of the latest stack map frame that has been parsed.
+ */
+ int offset;
+
+ /**
+ * The labels corresponding to the start of the local variable ranges in the
+ * local variable type annotation currently being parsed.
+ */
+ Label[] start;
+
+ /**
+ * The labels corresponding to the end of the local variable ranges in the
+ * local variable type annotation currently being parsed.
+ */
+ Label[] end;
+
+ /**
+ * The local variable indices for each local variable range in the local
+ * variable type annotation currently being parsed.
+ */
+ int[] index;
+
+ /**
+ * The encoding of the latest stack map frame that has been parsed.
+ */
+ int mode;
+
+ /**
+ * The number of locals in the latest stack map frame that has been parsed.
+ */
+ int localCount;
+
+ /**
+ * The number locals in the latest stack map frame that has been parsed,
+ * minus the number of locals in the previous frame.
+ */
+ int localDiff;
+
+ /**
+ * The local values of the latest stack map frame that has been parsed.
+ */
+ Object[] local;
+
+ /**
+ * The stack size of the latest stack map frame that has been parsed.
+ */
+ int stackCount;
+
+ /**
+ * The stack values of the latest stack map frame that has been parsed.
+ */
+ Object[] stack;
+}
\ No newline at end of file
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Edge.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Edge.java
index bda2e7381..a0bfc9b9b 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Edge.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Edge.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
/**
* An edge in the control flow graph of a method body. See {@link Label Label}.
- *
+ *
* @author Eric Bruneton
*/
class Edge {
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldVisitor.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldVisitor.java
index 2cb619bad..3ed2bfb6d 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldVisitor.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldVisitor.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,35 +30,121 @@
package jersey.repackaged.org.objectweb.asm;
/**
- * A visitor to visit a Java field. The methods of this interface must be called
- * in the following order: ( visitAnnotation |
- * visitAttribute )* visitEnd.
- *
+ * A visitor to visit a Java field. The methods of this class must be called in
+ * the following order: ( visitAnnotation |
+ * visitTypeAnnotation | visitAttribute )* visitEnd.
+ *
* @author Eric Bruneton
*/
-public interface FieldVisitor {
+public abstract class FieldVisitor {
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ protected final int api;
+
+ /**
+ * The field visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected FieldVisitor fv;
+
+ /**
+ * Constructs a new {@link FieldVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ public FieldVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link FieldVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * @param fv
+ * the field visitor to which this visitor must delegate method
+ * calls. May be null.
+ */
+ public FieldVisitor(final int api, final FieldVisitor fv) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ throw new IllegalArgumentException();
+ }
+ this.api = api;
+ this.fv = fv;
+ }
/**
* Visits an annotation of the field.
- *
- * @param desc the class descriptor of the annotation class.
- * @param visible true if the annotation is visible at runtime.
+ *
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ if (fv != null) {
+ return fv.visitAnnotation(desc, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits an annotation on the type of the field.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#FIELD FIELD}. See
+ * {@link TypeReference}.
+ * @param typePath
+ * the path to the annotated type argument, wildcard bound, array
+ * element type, or static inner type within 'typeRef'. May be
+ * null if the annotation targets 'typeRef' as a whole.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or null if
* this visitor is not interested in visiting this annotation.
*/
- AnnotationVisitor visitAnnotation(String desc, boolean visible);
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (fv != null) {
+ return fv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
/**
* Visits a non standard attribute of the field.
- *
- * @param attr an attribute.
+ *
+ * @param attr
+ * an attribute.
*/
- void visitAttribute(Attribute attr);
+ public void visitAttribute(Attribute attr) {
+ if (fv != null) {
+ fv.visitAttribute(attr);
+ }
+ }
/**
* Visits the end of the field. This method, which is the last one to be
* called, is used to inform the visitor that all the annotations and
* attributes of the field have been visited.
*/
- void visitEnd();
+ public void visitEnd() {
+ if (fv != null) {
+ fv.visitEnd();
+ }
+ }
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldWriter.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldWriter.java
index 8b4f0aaac..87f136cf0 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldWriter.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldWriter.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,15 +31,10 @@
/**
* An {@link FieldVisitor} that generates Java fields in bytecode form.
- *
+ *
* @author Eric Bruneton
*/
-final class FieldWriter implements FieldVisitor {
-
- /**
- * Next field writer (see {@link ClassWriter#firstField firstField}).
- */
- FieldWriter next;
+final class FieldWriter extends FieldVisitor {
/**
* The class writer to which this field must be added.
@@ -85,6 +80,17 @@ final class FieldWriter implements FieldVisitor {
*/
private AnnotationWriter ianns;
+ /**
+ * The runtime visible type annotations of this field. May be null.
+ */
+ private AnnotationWriter tanns;
+
+ /**
+ * The runtime invisible type annotations of this field. May be
+ * null.
+ */
+ private AnnotationWriter itanns;
+
/**
* The non standard attributes of this field. May be null.
*/
@@ -96,26 +102,27 @@ final class FieldWriter implements FieldVisitor {
/**
* Constructs a new {@link FieldWriter}.
- *
- * @param cw the class writer to which this field must be added.
- * @param access the field's access flags (see {@link Opcodes}).
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link Type}).
- * @param signature the field's signature. May be null.
- * @param value the field's constant value. May be null.
+ *
+ * @param cw
+ * the class writer to which this field must be added.
+ * @param access
+ * the field's access flags (see {@link Opcodes}).
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link Type}).
+ * @param signature
+ * the field's signature. May be null.
+ * @param value
+ * the field's constant value. May be null.
*/
- FieldWriter(
- final ClassWriter cw,
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ FieldWriter(final ClassWriter cw, final int access, final String name,
+ final String desc, final String signature, final Object value) {
+ super(Opcodes.ASM5);
if (cw.firstField == null) {
cw.firstField = this;
} else {
- cw.lastField.next = this;
+ cw.lastField.fv = this;
}
cw.lastField = this;
this.cw = cw;
@@ -131,13 +138,12 @@ final class FieldWriter implements FieldVisitor {
}
// ------------------------------------------------------------------------
- // Implementation of the FieldVisitor interface
+ // Implementation of the FieldVisitor abstract class
// ------------------------------------------------------------------------
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ @Override
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
if (!ClassReader.ANNOTATIONS) {
return null;
}
@@ -155,11 +161,36 @@ public AnnotationVisitor visitAnnotation(
return aw;
}
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+ final TypePath typePath, final String desc, final boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = tanns;
+ tanns = aw;
+ } else {
+ aw.next = itanns;
+ itanns = aw;
+ }
+ return aw;
+ }
+
+ @Override
public void visitAttribute(final Attribute attr) {
attr.next = attrs;
attrs = attr;
}
+ @Override
public void visitEnd() {
}
@@ -169,7 +200,7 @@ public void visitEnd() {
/**
* Returns the size of this field.
- *
+ *
* @return the size of this field.
*/
int getSize() {
@@ -178,11 +209,12 @@ int getSize() {
cw.newUTF8("ConstantValue");
size += 8;
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && (cw.version & 0xffff) < Opcodes.V1_5)
- {
- cw.newUTF8("Synthetic");
- size += 6;
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ cw.newUTF8("Synthetic");
+ size += 6;
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cw.newUTF8("Deprecated");
@@ -200,6 +232,14 @@ int getSize() {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ cw.newUTF8("RuntimeVisibleTypeAnnotations");
+ size += 8 + tanns.getSize();
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+ size += 8 + itanns.getSize();
+ }
if (attrs != null) {
size += attrs.getSize(cw, null, 0, -1, -1);
}
@@ -208,19 +248,24 @@ int getSize() {
/**
* Puts the content of this field into the given byte vector.
- *
- * @param out where the content of this field must be put.
+ *
+ * @param out
+ * where the content of this field must be put.
*/
void put(final ByteVector out) {
- out.putShort(access).putShort(name).putShort(desc);
+ final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+ int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+ | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
+ out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0;
if (value != 0) {
++attributeCount;
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && (cw.version & 0xffff) < Opcodes.V1_5)
- {
- ++attributeCount;
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ ++attributeCount;
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
@@ -234,6 +279,12 @@ void put(final ByteVector out) {
if (ClassReader.ANNOTATIONS && ianns != null) {
++attributeCount;
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ ++attributeCount;
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ ++attributeCount;
+ }
if (attrs != null) {
attributeCount += attrs.getCount();
}
@@ -242,10 +293,11 @@ void put(final ByteVector out) {
out.putShort(cw.newUTF8("ConstantValue"));
out.putInt(2).putShort(value);
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && (cw.version & 0xffff) < Opcodes.V1_5)
- {
- out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
@@ -262,6 +314,14 @@ void put(final ByteVector out) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+ tanns.put(out);
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+ itanns.put(out);
+ }
if (attrs != null) {
attrs.put(cw, null, 0, -1, -1, out);
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Frame.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Frame.java
index bbba42a67..b2f3db0e9 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Frame.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Frame.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
/**
* Information about the input and output stack map frames of a basic block.
- *
+ *
* @author Eric Bruneton
*/
final class Frame {
@@ -42,18 +42,18 @@ final class Frame {
* updated by simulating the action of the instruction on the previous state
* of this so called "output frame". In visitMaxs, a fix point algorithm is
* used to compute the "input frame" of each basic block, i.e. the stack map
- * frame at the begining of the basic block, starting from the input frame
+ * frame at the beginning of the basic block, starting from the input frame
* of the first basic block (which is computed from the method descriptor),
* and by using the previously computed output frames to compute the input
* state of the other blocks.
- *
+ *
* All output and input frames are stored as arrays of integers. Reference
* and array types are represented by an index into a type table (which is
* not the same as the constant pool of the class, in order to avoid adding
* unnecessary constants in the pool - not all computed frames will end up
* being stored in the stack map table). This allows very fast type
* comparisons.
- *
+ *
* Output stack map frames are computed relatively to the input frame of the
* basic block, which is not yet known when output frames are computed. It
* is therefore necessary to be able to represent abstract types such as
@@ -61,7 +61,7 @@ final class Frame {
* position x from the top of the input frame stack" or even "the type at
* position x in the input frame, with y more (or less) array dimensions".
* This explains the rather complicated type format used in output frames.
- *
+ *
* This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a
* signed number of array dimensions (from -8 to 7). KIND is either BASE,
* LOCAL or STACK. BASE is used for types that are not relative to the input
@@ -72,21 +72,21 @@ final class Frame {
* relatively to the top of input frame stack. For BASE types, it is either
* one of the constants defined in FrameVisitor, or for OBJECT and
* UNINITIALIZED types, a tag and an index in the type table.
- *
+ *
* Output frames can contain types of any kind and with a positive or
* negative dimension (and even unassigned types, represented by 0 - which
* does not correspond to any valid type value). Input frames can only
* contain BASE types of positive or null dimension. In all cases the type
* table contains only internal type names (array type descriptors are
* forbidden - dimensions must be represented through the DIM field).
- *
- * The LONG and DOUBLE types are always represented by using two slots (LONG +
- * TOP or DOUBLE + TOP), for local variable types as well as in the operand
- * stack. This is necessary to be able to simulate DUPx_y instructions,
- * whose effect would be dependent on the actual type values if types were
- * always represented by a single slot in the stack (and this is not
- * possible, since actual type values are not always known - cf LOCAL and
- * STACK type kinds).
+ *
+ * The LONG and DOUBLE types are always represented by using two slots (LONG
+ * + TOP or DOUBLE + TOP), for local variable types as well as in the
+ * operand stack. This is necessary to be able to simulate DUPx_y
+ * instructions, whose effect would be dependent on the actual type values
+ * if types were always represented by a single slot in the stack (and this
+ * is not possible, since actual type values are not always known - cf LOCAL
+ * and STACK type kinds).
*/
/**
@@ -107,17 +107,26 @@ final class Frame {
/**
* Mask to get the kind of a frame type.
- *
+ *
* @see #BASE
* @see #LOCAL
* @see #STACK
*/
static final int KIND = 0xF000000;
+ /**
+ * Flag used for LOCAL and STACK types. Indicates that if this type happens
+ * to be a long or double type (during the computations of input frames),
+ * then it must be set to TOP because the second word of this value has been
+ * reused to store other data in the basic block. Hence the first word no
+ * longer stores a valid long or double value.
+ */
+ static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
+
/**
* Mask to get the value of a frame type.
*/
- static final int VALUE = 0xFFFFFF;
+ static final int VALUE = 0x7FFFFF;
/**
* Mask to get the kind of base types.
@@ -428,7 +437,7 @@ final class Frame {
// NA, //INVOKESPECIAL, // -
// NA, //INVOKESTATIC, // -
// NA, //INVOKEINTERFACE, // -
- // NA, //UNUSED, // NOT VISITED
+ // NA, //INVOKEDYNAMIC, // visitInvokeDynamicInsn
// 1, //NEW, // visitTypeInsn
// 0, //NEWARRAY, // visitIntInsn
// 0, //ANEWARRAY, // visitTypeInsn
@@ -480,10 +489,10 @@ final class Frame {
/**
* Relative size of the output stack. The exact semantics of this field
* depends on the algorithm that is used.
- *
+ *
* When only the maximum stack size is computed, this field is the size of
* the output stack relatively to the top of the input stack.
- *
+ *
* When the stack map frames are completely computed, this field is the
* actual number of types in {@link #outputStack}.
*/
@@ -491,7 +500,7 @@ final class Frame {
/**
* Number of types that are initialized in the basic block.
- *
+ *
* @see #initializations
*/
private int initializationCount;
@@ -513,8 +522,9 @@ final class Frame {
/**
* Returns the output frame local variable type at the given index.
- *
- * @param local the index of the local that must be returned.
+ *
+ * @param local
+ * the index of the local that must be returned.
* @return the output frame local variable type at the given index.
*/
private int get(final int local) {
@@ -535,9 +545,11 @@ private int get(final int local) {
/**
* Sets the output frame local variable type at the given index.
- *
- * @param local the index of the local that must be set.
- * @param type the value of the local that must be set.
+ *
+ * @param local
+ * the index of the local that must be set.
+ * @param type
+ * the value of the local that must be set.
*/
private void set(final int local, final int type) {
// creates and/or resizes the output local variables array if necessary
@@ -556,8 +568,9 @@ private void set(final int local, final int type) {
/**
* Pushes a new type onto the output frame stack.
- *
- * @param type the type that must be pushed.
+ *
+ * @param type
+ * the type that must be pushed.
*/
private void push(final int type) {
// creates and/or resizes the output stack array if necessary
@@ -581,11 +594,13 @@ private void push(final int type) {
/**
* Pushes a new type onto the output frame stack.
- *
- * @param cw the ClassWriter to which this label belongs.
- * @param desc the descriptor of the type to be pushed. Can also be a method
- * descriptor (in this case this method pushes its return type onto
- * the output frame stack).
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param desc
+ * the descriptor of the type to be pushed. Can also be a method
+ * descriptor (in this case this method pushes its return type
+ * onto the output frame stack).
*/
private void push(final ClassWriter cw, final String desc) {
int type = type(cw, desc);
@@ -599,79 +614,81 @@ private void push(final ClassWriter cw, final String desc) {
/**
* Returns the int encoding of the given type.
- *
- * @param cw the ClassWriter to which this label belongs.
- * @param desc a type descriptor.
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param desc
+ * a type descriptor.
* @return the int encoding of the given type.
*/
private static int type(final ClassWriter cw, final String desc) {
String t;
int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
switch (desc.charAt(index)) {
- case 'V':
- return 0;
+ case 'V':
+ return 0;
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ return INTEGER;
+ case 'F':
+ return FLOAT;
+ case 'J':
+ return LONG;
+ case 'D':
+ return DOUBLE;
+ case 'L':
+ // stores the internal name, not the descriptor!
+ t = desc.substring(index + 1, desc.length() - 1);
+ return OBJECT | cw.addType(t);
+ // case '[':
+ default:
+ // extracts the dimensions and the element type
+ int data;
+ int dims = index + 1;
+ while (desc.charAt(dims) == '[') {
+ ++dims;
+ }
+ switch (desc.charAt(dims)) {
case 'Z':
+ data = BOOLEAN;
+ break;
case 'C':
+ data = CHAR;
+ break;
case 'B':
+ data = BYTE;
+ break;
case 'S':
+ data = SHORT;
+ break;
case 'I':
- return INTEGER;
+ data = INTEGER;
+ break;
case 'F':
- return FLOAT;
+ data = FLOAT;
+ break;
case 'J':
- return LONG;
+ data = LONG;
+ break;
case 'D':
- return DOUBLE;
- case 'L':
- // stores the internal name, not the descriptor!
- t = desc.substring(index + 1, desc.length() - 1);
- return OBJECT | cw.addType(t);
- // case '[':
+ data = DOUBLE;
+ break;
+ // case 'L':
default:
- // extracts the dimensions and the element type
- int data;
- int dims = index + 1;
- while (desc.charAt(dims) == '[') {
- ++dims;
- }
- switch (desc.charAt(dims)) {
- case 'Z':
- data = BOOLEAN;
- break;
- case 'C':
- data = CHAR;
- break;
- case 'B':
- data = BYTE;
- break;
- case 'S':
- data = SHORT;
- break;
- case 'I':
- data = INTEGER;
- break;
- case 'F':
- data = FLOAT;
- break;
- case 'J':
- data = LONG;
- break;
- case 'D':
- data = DOUBLE;
- break;
- // case 'L':
- default:
- // stores the internal name, not the descriptor
- t = desc.substring(dims + 1, desc.length() - 1);
- data = OBJECT | cw.addType(t);
- }
- return (dims - index) << 28 | data;
+ // stores the internal name, not the descriptor
+ t = desc.substring(dims + 1, desc.length() - 1);
+ data = OBJECT | cw.addType(t);
+ }
+ return (dims - index) << 28 | data;
}
}
/**
* Pops a type from the output frame stack and returns its value.
- *
+ *
* @return the type that has been popped from the output frame stack.
*/
private int pop() {
@@ -685,8 +702,9 @@ private int pop() {
/**
* Pops the given number of types from the output frame stack.
- *
- * @param elements the number of types that must be popped.
+ *
+ * @param elements
+ * the number of types that must be popped.
*/
private void pop(final int elements) {
if (outputStackTop >= elements) {
@@ -702,15 +720,16 @@ private void pop(final int elements) {
/**
* Pops a type from the output frame stack.
- *
- * @param desc the descriptor of the type to be popped. Can also be a method
- * descriptor (in this case this method pops the types corresponding
- * to the method arguments).
+ *
+ * @param desc
+ * the descriptor of the type to be popped. Can also be a method
+ * descriptor (in this case this method pops the types
+ * corresponding to the method arguments).
*/
private void pop(final String desc) {
char c = desc.charAt(0);
if (c == '(') {
- pop((MethodWriter.getArgumentsAndReturnSizes(desc) >> 2) - 1);
+ pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);
} else if (c == 'J' || c == 'D') {
pop(2);
} else {
@@ -721,8 +740,9 @@ private void pop(final String desc) {
/**
* Adds a new type to the list of types on which a constructor is invoked in
* the basic block.
- *
- * @param var a type on a which a constructor is invoked.
+ *
+ * @param var
+ * a type on a which a constructor is invoked.
*/
private void init(final int var) {
// creates and/or resizes the initializations array if necessary
@@ -742,9 +762,11 @@ private void init(final int var) {
/**
* Replaces the given type with the appropriate type if it is one of the
* types on which a constructor is invoked in the basic block.
- *
- * @param cw the ClassWriter to which this label belongs.
- * @param t a type
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param t
+ * a type
* @return t or, if t is one of the types on which a constructor is invoked
* in the basic block, the type corresponding to this constructor.
*/
@@ -777,18 +799,18 @@ private int init(final ClassWriter cw, final int t) {
/**
* Initializes the input frame of the first basic block from the method
* descriptor.
- *
- * @param cw the ClassWriter to which this label belongs.
- * @param access the access flags of the method to which this label belongs.
- * @param args the formal parameter types of this method.
- * @param maxLocals the maximum number of local variables of this method.
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param access
+ * the access flags of the method to which this label belongs.
+ * @param args
+ * the formal parameter types of this method.
+ * @param maxLocals
+ * the maximum number of local variables of this method.
*/
- void initInputFrame(
- final ClassWriter cw,
- final int access,
- final Type[] args,
- final int maxLocals)
- {
+ void initInputFrame(final ClassWriter cw, final int access,
+ final Type[] args, final int maxLocals) {
inputLocals = new int[maxLocals];
inputStack = new int[0];
int i = 0;
@@ -813,422 +835,436 @@ void initInputFrame(
/**
* Simulates the action of the given instruction on the output stack frame.
- *
- * @param opcode the opcode of the instruction.
- * @param arg the operand of the instruction, if any.
- * @param cw the class writer to which this label belongs.
- * @param item the operand of the instructions, if any.
+ *
+ * @param opcode
+ * the opcode of the instruction.
+ * @param arg
+ * the operand of the instruction, if any.
+ * @param cw
+ * the class writer to which this label belongs.
+ * @param item
+ * the operand of the instructions, if any.
*/
- void execute(
- final int opcode,
- final int arg,
- final ClassWriter cw,
- final Item item)
- {
+ void execute(final int opcode, final int arg, final ClassWriter cw,
+ final Item item) {
int t1, t2, t3, t4;
switch (opcode) {
- case Opcodes.NOP:
- case Opcodes.INEG:
- case Opcodes.LNEG:
- case Opcodes.FNEG:
- case Opcodes.DNEG:
- case Opcodes.I2B:
- case Opcodes.I2C:
- case Opcodes.I2S:
- case Opcodes.GOTO:
- case Opcodes.RETURN:
- break;
- case Opcodes.ACONST_NULL:
- push(NULL);
- break;
- case Opcodes.ICONST_M1:
- case Opcodes.ICONST_0:
- case Opcodes.ICONST_1:
- case Opcodes.ICONST_2:
- case Opcodes.ICONST_3:
- case Opcodes.ICONST_4:
- case Opcodes.ICONST_5:
- case Opcodes.BIPUSH:
- case Opcodes.SIPUSH:
- case Opcodes.ILOAD:
+ case Opcodes.NOP:
+ case Opcodes.INEG:
+ case Opcodes.LNEG:
+ case Opcodes.FNEG:
+ case Opcodes.DNEG:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ case Opcodes.GOTO:
+ case Opcodes.RETURN:
+ break;
+ case Opcodes.ACONST_NULL:
+ push(NULL);
+ break;
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ case Opcodes.BIPUSH:
+ case Opcodes.SIPUSH:
+ case Opcodes.ILOAD:
+ push(INTEGER);
+ break;
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ case Opcodes.LLOAD:
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ case Opcodes.FLOAD:
+ push(FLOAT);
+ break;
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ case Opcodes.DLOAD:
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.LDC:
+ switch (item.type) {
+ case ClassWriter.INT:
push(INTEGER);
break;
- case Opcodes.LCONST_0:
- case Opcodes.LCONST_1:
- case Opcodes.LLOAD:
+ case ClassWriter.LONG:
push(LONG);
push(TOP);
break;
- case Opcodes.FCONST_0:
- case Opcodes.FCONST_1:
- case Opcodes.FCONST_2:
- case Opcodes.FLOAD:
+ case ClassWriter.FLOAT:
push(FLOAT);
break;
- case Opcodes.DCONST_0:
- case Opcodes.DCONST_1:
- case Opcodes.DLOAD:
+ case ClassWriter.DOUBLE:
push(DOUBLE);
push(TOP);
break;
- case Opcodes.LDC:
- switch (item.type) {
- case ClassWriter.INT:
- push(INTEGER);
- break;
- case ClassWriter.LONG:
- push(LONG);
- push(TOP);
- break;
- case ClassWriter.FLOAT:
- push(FLOAT);
- break;
- case ClassWriter.DOUBLE:
- push(DOUBLE);
- push(TOP);
- break;
- case ClassWriter.CLASS:
- push(OBJECT | cw.addType("java/lang/Class"));
- break;
- // case ClassWriter.STR:
- default:
- push(OBJECT | cw.addType("java/lang/String"));
- }
- break;
- case Opcodes.ALOAD:
- push(get(arg));
+ case ClassWriter.CLASS:
+ push(OBJECT | cw.addType("java/lang/Class"));
break;
- case Opcodes.IALOAD:
- case Opcodes.BALOAD:
- case Opcodes.CALOAD:
- case Opcodes.SALOAD:
- pop(2);
- push(INTEGER);
+ case ClassWriter.STR:
+ push(OBJECT | cw.addType("java/lang/String"));
break;
- case Opcodes.LALOAD:
- case Opcodes.D2L:
- pop(2);
- push(LONG);
- push(TOP);
+ case ClassWriter.MTYPE:
+ push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
break;
- case Opcodes.FALOAD:
- pop(2);
- push(FLOAT);
- break;
- case Opcodes.DALOAD:
- case Opcodes.L2D:
- pop(2);
- push(DOUBLE);
- push(TOP);
- break;
- case Opcodes.AALOAD:
- pop(1);
- t1 = pop();
- push(ELEMENT_OF + t1);
- break;
- case Opcodes.ISTORE:
- case Opcodes.FSTORE:
- case Opcodes.ASTORE:
- t1 = pop();
- set(arg, t1);
- if (arg > 0) {
- t2 = get(arg - 1);
- // if t2 is of kind STACK or LOCAL we cannot know its size!
- if (t2 == LONG || t2 == DOUBLE) {
- set(arg - 1, TOP);
- }
+ // case ClassWriter.HANDLE_BASE + [1..9]:
+ default:
+ push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
+ }
+ break;
+ case Opcodes.ALOAD:
+ push(get(arg));
+ break;
+ case Opcodes.IALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ pop(2);
+ push(INTEGER);
+ break;
+ case Opcodes.LALOAD:
+ case Opcodes.D2L:
+ pop(2);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.FALOAD:
+ pop(2);
+ push(FLOAT);
+ break;
+ case Opcodes.DALOAD:
+ case Opcodes.L2D:
+ pop(2);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.AALOAD:
+ pop(1);
+ t1 = pop();
+ push(ELEMENT_OF + t1);
+ break;
+ case Opcodes.ISTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.ASTORE:
+ t1 = pop();
+ set(arg, t1);
+ if (arg > 0) {
+ t2 = get(arg - 1);
+ // if t2 is of kind STACK or LOCAL we cannot know its size!
+ if (t2 == LONG || t2 == DOUBLE) {
+ set(arg - 1, TOP);
+ } else if ((t2 & KIND) != BASE) {
+ set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
}
- break;
- case Opcodes.LSTORE:
- case Opcodes.DSTORE:
- pop(1);
- t1 = pop();
- set(arg, t1);
- set(arg + 1, TOP);
- if (arg > 0) {
- t2 = get(arg - 1);
- // if t2 is of kind STACK or LOCAL we cannot know its size!
- if (t2 == LONG || t2 == DOUBLE) {
- set(arg - 1, TOP);
- }
+ }
+ break;
+ case Opcodes.LSTORE:
+ case Opcodes.DSTORE:
+ pop(1);
+ t1 = pop();
+ set(arg, t1);
+ set(arg + 1, TOP);
+ if (arg > 0) {
+ t2 = get(arg - 1);
+ // if t2 is of kind STACK or LOCAL we cannot know its size!
+ if (t2 == LONG || t2 == DOUBLE) {
+ set(arg - 1, TOP);
+ } else if ((t2 & KIND) != BASE) {
+ set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
}
- break;
- case Opcodes.IASTORE:
- case Opcodes.BASTORE:
- case Opcodes.CASTORE:
- case Opcodes.SASTORE:
- case Opcodes.FASTORE:
- case Opcodes.AASTORE:
- pop(3);
- break;
- case Opcodes.LASTORE:
- case Opcodes.DASTORE:
- pop(4);
- break;
- case Opcodes.POP:
- case Opcodes.IFEQ:
- case Opcodes.IFNE:
- case Opcodes.IFLT:
- case Opcodes.IFGE:
- case Opcodes.IFGT:
- case Opcodes.IFLE:
- case Opcodes.IRETURN:
- case Opcodes.FRETURN:
- case Opcodes.ARETURN:
- case Opcodes.TABLESWITCH:
- case Opcodes.LOOKUPSWITCH:
- case Opcodes.ATHROW:
- case Opcodes.MONITORENTER:
- case Opcodes.MONITOREXIT:
- case Opcodes.IFNULL:
- case Opcodes.IFNONNULL:
- pop(1);
- break;
- case Opcodes.POP2:
- case Opcodes.IF_ICMPEQ:
- case Opcodes.IF_ICMPNE:
- case Opcodes.IF_ICMPLT:
- case Opcodes.IF_ICMPGE:
- case Opcodes.IF_ICMPGT:
- case Opcodes.IF_ICMPLE:
- case Opcodes.IF_ACMPEQ:
- case Opcodes.IF_ACMPNE:
- case Opcodes.LRETURN:
- case Opcodes.DRETURN:
- pop(2);
- break;
- case Opcodes.DUP:
- t1 = pop();
- push(t1);
- push(t1);
- break;
- case Opcodes.DUP_X1:
- t1 = pop();
- t2 = pop();
- push(t1);
- push(t2);
- push(t1);
- break;
- case Opcodes.DUP_X2:
- t1 = pop();
- t2 = pop();
- t3 = pop();
- push(t1);
- push(t3);
- push(t2);
- push(t1);
- break;
- case Opcodes.DUP2:
- t1 = pop();
- t2 = pop();
- push(t2);
- push(t1);
- push(t2);
- push(t1);
- break;
- case Opcodes.DUP2_X1:
- t1 = pop();
- t2 = pop();
- t3 = pop();
- push(t2);
- push(t1);
- push(t3);
- push(t2);
- push(t1);
- break;
- case Opcodes.DUP2_X2:
- t1 = pop();
- t2 = pop();
- t3 = pop();
- t4 = pop();
- push(t2);
- push(t1);
- push(t4);
- push(t3);
- push(t2);
- push(t1);
- break;
- case Opcodes.SWAP:
+ }
+ break;
+ case Opcodes.IASTORE:
+ case Opcodes.BASTORE:
+ case Opcodes.CASTORE:
+ case Opcodes.SASTORE:
+ case Opcodes.FASTORE:
+ case Opcodes.AASTORE:
+ pop(3);
+ break;
+ case Opcodes.LASTORE:
+ case Opcodes.DASTORE:
+ pop(4);
+ break;
+ case Opcodes.POP:
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ case Opcodes.IRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.ARETURN:
+ case Opcodes.TABLESWITCH:
+ case Opcodes.LOOKUPSWITCH:
+ case Opcodes.ATHROW:
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ pop(1);
+ break;
+ case Opcodes.POP2:
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ case Opcodes.LRETURN:
+ case Opcodes.DRETURN:
+ pop(2);
+ break;
+ case Opcodes.DUP:
+ t1 = pop();
+ push(t1);
+ push(t1);
+ break;
+ case Opcodes.DUP_X1:
+ t1 = pop();
+ t2 = pop();
+ push(t1);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.DUP_X2:
+ t1 = pop();
+ t2 = pop();
+ t3 = pop();
+ push(t1);
+ push(t3);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.DUP2:
+ t1 = pop();
+ t2 = pop();
+ push(t2);
+ push(t1);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.DUP2_X1:
+ t1 = pop();
+ t2 = pop();
+ t3 = pop();
+ push(t2);
+ push(t1);
+ push(t3);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.DUP2_X2:
+ t1 = pop();
+ t2 = pop();
+ t3 = pop();
+ t4 = pop();
+ push(t2);
+ push(t1);
+ push(t4);
+ push(t3);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.SWAP:
+ t1 = pop();
+ t2 = pop();
+ push(t1);
+ push(t2);
+ break;
+ case Opcodes.IADD:
+ case Opcodes.ISUB:
+ case Opcodes.IMUL:
+ case Opcodes.IDIV:
+ case Opcodes.IREM:
+ case Opcodes.IAND:
+ case Opcodes.IOR:
+ case Opcodes.IXOR:
+ case Opcodes.ISHL:
+ case Opcodes.ISHR:
+ case Opcodes.IUSHR:
+ case Opcodes.L2I:
+ case Opcodes.D2I:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ pop(2);
+ push(INTEGER);
+ break;
+ case Opcodes.LADD:
+ case Opcodes.LSUB:
+ case Opcodes.LMUL:
+ case Opcodes.LDIV:
+ case Opcodes.LREM:
+ case Opcodes.LAND:
+ case Opcodes.LOR:
+ case Opcodes.LXOR:
+ pop(4);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.FADD:
+ case Opcodes.FSUB:
+ case Opcodes.FMUL:
+ case Opcodes.FDIV:
+ case Opcodes.FREM:
+ case Opcodes.L2F:
+ case Opcodes.D2F:
+ pop(2);
+ push(FLOAT);
+ break;
+ case Opcodes.DADD:
+ case Opcodes.DSUB:
+ case Opcodes.DMUL:
+ case Opcodes.DDIV:
+ case Opcodes.DREM:
+ pop(4);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.LSHL:
+ case Opcodes.LSHR:
+ case Opcodes.LUSHR:
+ pop(3);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.IINC:
+ set(arg, INTEGER);
+ break;
+ case Opcodes.I2L:
+ case Opcodes.F2L:
+ pop(1);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.I2F:
+ pop(1);
+ push(FLOAT);
+ break;
+ case Opcodes.I2D:
+ case Opcodes.F2D:
+ pop(1);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.F2I:
+ case Opcodes.ARRAYLENGTH:
+ case Opcodes.INSTANCEOF:
+ pop(1);
+ push(INTEGER);
+ break;
+ case Opcodes.LCMP:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ pop(4);
+ push(INTEGER);
+ break;
+ case Opcodes.JSR:
+ case Opcodes.RET:
+ throw new RuntimeException(
+ "JSR/RET are not supported with computeFrames option");
+ case Opcodes.GETSTATIC:
+ push(cw, item.strVal3);
+ break;
+ case Opcodes.PUTSTATIC:
+ pop(item.strVal3);
+ break;
+ case Opcodes.GETFIELD:
+ pop(1);
+ push(cw, item.strVal3);
+ break;
+ case Opcodes.PUTFIELD:
+ pop(item.strVal3);
+ pop();
+ break;
+ case Opcodes.INVOKEVIRTUAL:
+ case Opcodes.INVOKESPECIAL:
+ case Opcodes.INVOKESTATIC:
+ case Opcodes.INVOKEINTERFACE:
+ pop(item.strVal3);
+ if (opcode != Opcodes.INVOKESTATIC) {
t1 = pop();
- t2 = pop();
- push(t1);
- push(t2);
- break;
- case Opcodes.IADD:
- case Opcodes.ISUB:
- case Opcodes.IMUL:
- case Opcodes.IDIV:
- case Opcodes.IREM:
- case Opcodes.IAND:
- case Opcodes.IOR:
- case Opcodes.IXOR:
- case Opcodes.ISHL:
- case Opcodes.ISHR:
- case Opcodes.IUSHR:
- case Opcodes.L2I:
- case Opcodes.D2I:
- case Opcodes.FCMPL:
- case Opcodes.FCMPG:
- pop(2);
- push(INTEGER);
- break;
- case Opcodes.LADD:
- case Opcodes.LSUB:
- case Opcodes.LMUL:
- case Opcodes.LDIV:
- case Opcodes.LREM:
- case Opcodes.LAND:
- case Opcodes.LOR:
- case Opcodes.LXOR:
- pop(4);
- push(LONG);
- push(TOP);
- break;
- case Opcodes.FADD:
- case Opcodes.FSUB:
- case Opcodes.FMUL:
- case Opcodes.FDIV:
- case Opcodes.FREM:
- case Opcodes.L2F:
- case Opcodes.D2F:
- pop(2);
- push(FLOAT);
- break;
- case Opcodes.DADD:
- case Opcodes.DSUB:
- case Opcodes.DMUL:
- case Opcodes.DDIV:
- case Opcodes.DREM:
- pop(4);
- push(DOUBLE);
- push(TOP);
- break;
- case Opcodes.LSHL:
- case Opcodes.LSHR:
- case Opcodes.LUSHR:
- pop(3);
- push(LONG);
- push(TOP);
- break;
- case Opcodes.IINC:
- set(arg, INTEGER);
- break;
- case Opcodes.I2L:
- case Opcodes.F2L:
- pop(1);
- push(LONG);
- push(TOP);
- break;
- case Opcodes.I2F:
- pop(1);
- push(FLOAT);
- break;
- case Opcodes.I2D:
- case Opcodes.F2D:
- pop(1);
- push(DOUBLE);
- push(TOP);
- break;
- case Opcodes.F2I:
- case Opcodes.ARRAYLENGTH:
- case Opcodes.INSTANCEOF:
- pop(1);
- push(INTEGER);
- break;
- case Opcodes.LCMP:
- case Opcodes.DCMPL:
- case Opcodes.DCMPG:
- pop(4);
- push(INTEGER);
- break;
- case Opcodes.JSR:
- case Opcodes.RET:
- throw new RuntimeException("JSR/RET are not supported with computeFrames option");
- case Opcodes.GETSTATIC:
- push(cw, item.strVal3);
- break;
- case Opcodes.PUTSTATIC:
- pop(item.strVal3);
- break;
- case Opcodes.GETFIELD:
- pop(1);
- push(cw, item.strVal3);
+ if (opcode == Opcodes.INVOKESPECIAL
+ && item.strVal2.charAt(0) == '<') {
+ init(t1);
+ }
+ }
+ push(cw, item.strVal3);
+ break;
+ case Opcodes.INVOKEDYNAMIC:
+ pop(item.strVal2);
+ push(cw, item.strVal2);
+ break;
+ case Opcodes.NEW:
+ push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
+ break;
+ case Opcodes.NEWARRAY:
+ pop();
+ switch (arg) {
+ case Opcodes.T_BOOLEAN:
+ push(ARRAY_OF | BOOLEAN);
break;
- case Opcodes.PUTFIELD:
- pop(item.strVal3);
- pop();
+ case Opcodes.T_CHAR:
+ push(ARRAY_OF | CHAR);
break;
- case Opcodes.INVOKEVIRTUAL:
- case Opcodes.INVOKESPECIAL:
- case Opcodes.INVOKESTATIC:
- case Opcodes.INVOKEINTERFACE:
- pop(item.strVal3);
- if (opcode != Opcodes.INVOKESTATIC) {
- t1 = pop();
- if (opcode == Opcodes.INVOKESPECIAL
- && item.strVal2.charAt(0) == '<')
- {
- init(t1);
- }
- }
- push(cw, item.strVal3);
+ case Opcodes.T_BYTE:
+ push(ARRAY_OF | BYTE);
break;
- case Opcodes.NEW:
- push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
+ case Opcodes.T_SHORT:
+ push(ARRAY_OF | SHORT);
break;
- case Opcodes.NEWARRAY:
- pop();
- switch (arg) {
- case Opcodes.T_BOOLEAN:
- push(ARRAY_OF | BOOLEAN);
- break;
- case Opcodes.T_CHAR:
- push(ARRAY_OF | CHAR);
- break;
- case Opcodes.T_BYTE:
- push(ARRAY_OF | BYTE);
- break;
- case Opcodes.T_SHORT:
- push(ARRAY_OF | SHORT);
- break;
- case Opcodes.T_INT:
- push(ARRAY_OF | INTEGER);
- break;
- case Opcodes.T_FLOAT:
- push(ARRAY_OF | FLOAT);
- break;
- case Opcodes.T_DOUBLE:
- push(ARRAY_OF | DOUBLE);
- break;
- // case Opcodes.T_LONG:
- default:
- push(ARRAY_OF | LONG);
- break;
- }
+ case Opcodes.T_INT:
+ push(ARRAY_OF | INTEGER);
break;
- case Opcodes.ANEWARRAY:
- String s = item.strVal1;
- pop();
- if (s.charAt(0) == '[') {
- push(cw, '[' + s);
- } else {
- push(ARRAY_OF | OBJECT | cw.addType(s));
- }
+ case Opcodes.T_FLOAT:
+ push(ARRAY_OF | FLOAT);
break;
- case Opcodes.CHECKCAST:
- s = item.strVal1;
- pop();
- if (s.charAt(0) == '[') {
- push(cw, s);
- } else {
- push(OBJECT | cw.addType(s));
- }
+ case Opcodes.T_DOUBLE:
+ push(ARRAY_OF | DOUBLE);
break;
- // case Opcodes.MULTIANEWARRAY:
+ // case Opcodes.T_LONG:
default:
- pop(arg);
- push(cw, item.strVal1);
+ push(ARRAY_OF | LONG);
break;
+ }
+ break;
+ case Opcodes.ANEWARRAY:
+ String s = item.strVal1;
+ pop();
+ if (s.charAt(0) == '[') {
+ push(cw, '[' + s);
+ } else {
+ push(ARRAY_OF | OBJECT | cw.addType(s));
+ }
+ break;
+ case Opcodes.CHECKCAST:
+ s = item.strVal1;
+ pop();
+ if (s.charAt(0) == '[') {
+ push(cw, s);
+ } else {
+ push(OBJECT | cw.addType(s));
+ }
+ break;
+ // case Opcodes.MULTIANEWARRAY:
+ default:
+ pop(arg);
+ push(cw, item.strVal1);
+ break;
}
}
@@ -1236,11 +1272,14 @@ void execute(
* Merges the input frame of the given basic block with the input and output
* frames of this basic block. Returns true if the input frame of
* the given label has been changed by this operation.
- *
- * @param cw the ClassWriter to which this label belongs.
- * @param frame the basic block whose input frame must be updated.
- * @param edge the kind of the {@link Edge} between this label and 'label'.
- * See {@link Edge#info}.
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param frame
+ * the basic block whose input frame must be updated.
+ * @param edge
+ * the kind of the {@link Edge} between this label and 'label'.
+ * See {@link Edge#info}.
* @return true if the input frame of the given label has been
* changed by this operation.
*/
@@ -1263,12 +1302,18 @@ boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
} else {
dim = s & DIM;
kind = s & KIND;
- if (kind == LOCAL) {
- t = dim + inputLocals[s & VALUE];
- } else if (kind == STACK) {
- t = dim + inputStack[nStack - (s & VALUE)];
- } else {
+ if (kind == BASE) {
t = s;
+ } else {
+ if (kind == LOCAL) {
+ t = dim + inputLocals[s & VALUE];
+ } else {
+ t = dim + inputStack[nStack - (s & VALUE)];
+ }
+ if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+ && (t == LONG || t == DOUBLE)) {
+ t = TOP;
+ }
}
}
} else {
@@ -1310,12 +1355,18 @@ boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
s = outputStack[i];
dim = s & DIM;
kind = s & KIND;
- if (kind == LOCAL) {
- t = dim + inputLocals[s & VALUE];
- } else if (kind == STACK) {
- t = dim + inputStack[nStack - (s & VALUE)];
- } else {
+ if (kind == BASE) {
t = s;
+ } else {
+ if (kind == LOCAL) {
+ t = dim + inputLocals[s & VALUE];
+ } else {
+ t = dim + inputStack[nStack - (s & VALUE)];
+ }
+ if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+ && (t == LONG || t == DOUBLE)) {
+ t = TOP;
+ }
}
if (initializations != null) {
t = init(cw, t);
@@ -1329,20 +1380,20 @@ boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
* Merges the type at the given index in the given type array with the given
* type. Returns true if the type array has been modified by this
* operation.
- *
- * @param cw the ClassWriter to which this label belongs.
- * @param t the type with which the type array element must be merged.
- * @param types an array of types.
- * @param index the index of the type that must be merged in 'types'.
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param t
+ * the type with which the type array element must be merged.
+ * @param types
+ * an array of types.
+ * @param index
+ * the index of the type that must be merged in 'types'.
* @return true if the type array has been modified by this
* operation.
*/
- private static boolean merge(
- final ClassWriter cw,
- int t,
- final int[] types,
- final int index)
- {
+ private static boolean merge(final ClassWriter cw, int t,
+ final int[] types, final int index) {
int u = types[index];
if (u == t) {
// if the types are equal, merge(u,t)=u, so there is no change
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Handle.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Handle.java
new file mode 100644
index 000000000..1ac7ae3b7
--- /dev/null
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Handle.java
@@ -0,0 +1,170 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jersey.repackaged.org.objectweb.asm;
+
+/**
+ * A reference to a field or a method.
+ *
+ * @author Remi Forax
+ * @author Eric Bruneton
+ */
+public final class Handle {
+
+ /**
+ * The kind of field or method designated by this Handle. Should be
+ * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+ * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+ * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ */
+ final int tag;
+
+ /**
+ * The internal name of the class that owns the field or method designated
+ * by this handle.
+ */
+ final String owner;
+
+ /**
+ * The name of the field or method designated by this handle.
+ */
+ final String name;
+
+ /**
+ * The descriptor of the field or method designated by this handle.
+ */
+ final String desc;
+
+ /**
+ * Constructs a new field or method handle.
+ *
+ * @param tag
+ * the kind of field or method designated by this Handle. Must be
+ * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+ * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+ * {@link Opcodes#H_INVOKEVIRTUAL},
+ * {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner
+ * the internal name of the class that owns the field or method
+ * designated by this handle.
+ * @param name
+ * the name of the field or method designated by this handle.
+ * @param desc
+ * the descriptor of the field or method designated by this
+ * handle.
+ */
+ public Handle(int tag, String owner, String name, String desc) {
+ this.tag = tag;
+ this.owner = owner;
+ this.name = name;
+ this.desc = desc;
+ }
+
+ /**
+ * Returns the kind of field or method designated by this handle.
+ *
+ * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+ * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+ * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ */
+ public int getTag() {
+ return tag;
+ }
+
+ /**
+ * Returns the internal name of the class that owns the field or method
+ * designated by this handle.
+ *
+ * @return the internal name of the class that owns the field or method
+ * designated by this handle.
+ */
+ public String getOwner() {
+ return owner;
+ }
+
+ /**
+ * Returns the name of the field or method designated by this handle.
+ *
+ * @return the name of the field or method designated by this handle.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the descriptor of the field or method designated by this handle.
+ *
+ * @return the descriptor of the field or method designated by this handle.
+ */
+ public String getDesc() {
+ return desc;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof Handle)) {
+ return false;
+ }
+ Handle h = (Handle) obj;
+ return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
+ && desc.equals(h.desc);
+ }
+
+ @Override
+ public int hashCode() {
+ return tag + owner.hashCode() * name.hashCode() * desc.hashCode();
+ }
+
+ /**
+ * Returns the textual representation of this handle. The textual
+ * representation is:
+ *
+ *
+ * owner '.' name desc ' ' '(' tag ')'
+ *
+ *
+ * . As this format is unambiguous, it can be parsed if necessary.
+ */
+ @Override
+ public String toString() {
+ return owner + '.' + name + desc + " (" + tag + ')';
+ }
+}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Handler.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Handler.java
index 77c76bac8..5b86ef355 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Handler.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Handler.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
/**
* Information about an exception handler block.
- *
+ *
* @author Eric Bruneton
*/
class Handler {
@@ -67,4 +67,55 @@ class Handler {
* Next exception handler block info.
*/
Handler next;
+
+ /**
+ * Removes the range between start and end from the given exception
+ * handlers.
+ *
+ * @param h
+ * an exception handler list.
+ * @param start
+ * the start of the range to be removed.
+ * @param end
+ * the end of the range to be removed. Maybe null.
+ * @return the exception handler list with the start-end range removed.
+ */
+ static Handler remove(Handler h, Label start, Label end) {
+ if (h == null) {
+ return null;
+ } else {
+ h.next = remove(h.next, start, end);
+ }
+ int hstart = h.start.position;
+ int hend = h.end.position;
+ int s = start.position;
+ int e = end == null ? Integer.MAX_VALUE : end.position;
+ // if [hstart,hend[ and [s,e[ intervals intersect...
+ if (s < hend && e > hstart) {
+ if (s <= hstart) {
+ if (e >= hend) {
+ // [hstart,hend[ fully included in [s,e[, h removed
+ h = h.next;
+ } else {
+ // [hstart,hend[ minus [s,e[ = [e,hend[
+ h.start = end;
+ }
+ } else if (e >= hend) {
+ // [hstart,hend[ minus [s,e[ = [hstart,s[
+ h.end = start;
+ } else {
+ // [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[
+ Handler g = new Handler();
+ g.start = end;
+ g.end = h.end;
+ g.handler = h.handler;
+ g.desc = h.desc;
+ g.type = h.type;
+ g.next = h.next;
+ h.end = start;
+ h.next = g;
+ }
+ }
+ return h;
+ }
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Item.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Item.java
index 26f05be9e..9d5511c48 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Item.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Item.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
/**
* A constant pool item. Constant pool items can be created with the 'newXXX'
* methods in the {@link ClassWriter} class.
- *
+ *
* @author Eric Bruneton
*/
final class Item {
@@ -50,8 +50,13 @@ final class Item {
* {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
* {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
* {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
- * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}.
- *
+ * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+ * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
+ *
+ * MethodHandle constant 9 variations are stored using a range of 9 values
+ * from {@link ClassWriter#HANDLE_BASE} + 1 to
+ * {@link ClassWriter#HANDLE_BASE} + 9.
+ *
* Special Item types are used for Items that are stored in the ClassWriter
* {@link ClassWriter#typeTable}, instead of the constant pool, in order to
* avoid clashes with normal constant pool items in the ClassWriter constant
@@ -109,8 +114,9 @@ final class Item {
/**
* Constructs an uninitialized {@link Item} for constant pool element at
* given position.
- *
- * @param index index of the item to be constructed.
+ *
+ * @param index
+ * index of the item to be constructed.
*/
Item(final int index) {
this.index = index;
@@ -118,9 +124,11 @@ final class Item {
/**
* Constructs a copy of the given item.
- *
- * @param index index of the item to be constructed.
- * @param i the item that must be copied into the item to be constructed.
+ *
+ * @param index
+ * index of the item to be constructed.
+ * @param i
+ * the item that must be copied into the item to be constructed.
*/
Item(final int index, final Item i) {
this.index = index;
@@ -135,8 +143,9 @@ final class Item {
/**
* Sets this item to an integer item.
- *
- * @param intVal the value of this item.
+ *
+ * @param intVal
+ * the value of this item.
*/
void set(final int intVal) {
this.type = ClassWriter.INT;
@@ -146,8 +155,9 @@ void set(final int intVal) {
/**
* Sets this item to a long item.
- *
- * @param longVal the value of this item.
+ *
+ * @param longVal
+ * the value of this item.
*/
void set(final long longVal) {
this.type = ClassWriter.LONG;
@@ -157,8 +167,9 @@ void set(final long longVal) {
/**
* Sets this item to a float item.
- *
- * @param floatVal the value of this item.
+ *
+ * @param floatVal
+ * the value of this item.
*/
void set(final float floatVal) {
this.type = ClassWriter.FLOAT;
@@ -168,8 +179,9 @@ void set(final float floatVal) {
/**
* Sets this item to a double item.
- *
- * @param doubleVal the value of this item.
+ *
+ * @param doubleVal
+ * the value of this item.
*/
void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE;
@@ -179,78 +191,121 @@ void set(final double doubleVal) {
/**
* Sets this item to an item that do not hold a primitive value.
- *
- * @param type the type of this item.
- * @param strVal1 first part of the value of this item.
- * @param strVal2 second part of the value of this item.
- * @param strVal3 third part of the value of this item.
+ *
+ * @param type
+ * the type of this item.
+ * @param strVal1
+ * first part of the value of this item.
+ * @param strVal2
+ * second part of the value of this item.
+ * @param strVal3
+ * third part of the value of this item.
*/
- void set(
- final int type,
- final String strVal1,
- final String strVal2,
- final String strVal3)
- {
+ void set(final int type, final String strVal1, final String strVal2,
+ final String strVal3) {
this.type = type;
this.strVal1 = strVal1;
this.strVal2 = strVal2;
this.strVal3 = strVal3;
switch (type) {
- case ClassWriter.UTF8:
- case ClassWriter.STR:
- case ClassWriter.CLASS:
- case ClassWriter.TYPE_NORMAL:
- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
- return;
- case ClassWriter.NAME_TYPE:
- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
- * strVal2.hashCode());
- return;
- // ClassWriter.FIELD:
- // ClassWriter.METH:
- // ClassWriter.IMETH:
- default:
- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
- * strVal2.hashCode() * strVal3.hashCode());
+ case ClassWriter.UTF8:
+ case ClassWriter.STR:
+ case ClassWriter.CLASS:
+ case ClassWriter.MTYPE:
+ case ClassWriter.TYPE_NORMAL:
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
+ return;
+ case ClassWriter.NAME_TYPE: {
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+ * strVal2.hashCode());
+ return;
+ }
+ // ClassWriter.FIELD:
+ // ClassWriter.METH:
+ // ClassWriter.IMETH:
+ // ClassWriter.HANDLE_BASE + 1..9
+ default:
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+ * strVal2.hashCode() * strVal3.hashCode());
}
}
/**
- * Indicates if the given item is equal to this one.
- *
- * @param i the item to be compared to this one.
+ * Sets the item to an InvokeDynamic item.
+ *
+ * @param name
+ * invokedynamic's name.
+ * @param desc
+ * invokedynamic's desc.
+ * @param bsmIndex
+ * zero based index into the class attribute BootrapMethods.
+ */
+ void set(String name, String desc, int bsmIndex) {
+ this.type = ClassWriter.INDY;
+ this.longVal = bsmIndex;
+ this.strVal1 = name;
+ this.strVal2 = desc;
+ this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex
+ * strVal1.hashCode() * strVal2.hashCode());
+ }
+
+ /**
+ * Sets the item to a BootstrapMethod item.
+ *
+ * @param position
+ * position in byte in the class attribute BootrapMethods.
+ * @param hashCode
+ * hashcode of the item. This hashcode is processed from the
+ * hashcode of the bootstrap method and the hashcode of all
+ * bootstrap arguments.
+ */
+ void set(int position, int hashCode) {
+ this.type = ClassWriter.BSM;
+ this.intVal = position;
+ this.hashCode = hashCode;
+ }
+
+ /**
+ * Indicates if the given item is equal to this one. This method assumes
+ * that the two items have the same {@link #type}.
+ *
+ * @param i
+ * the item to be compared to this one. Both items must have the
+ * same {@link #type}.
* @return true if the given item if equal to this one,
* false otherwise.
*/
boolean isEqualTo(final Item i) {
- if (i.type == type) {
- switch (type) {
- case ClassWriter.INT:
- case ClassWriter.FLOAT:
- return i.intVal == intVal;
- case ClassWriter.TYPE_MERGED:
- case ClassWriter.LONG:
- case ClassWriter.DOUBLE:
- return i.longVal == longVal;
- case ClassWriter.UTF8:
- case ClassWriter.STR:
- case ClassWriter.CLASS:
- case ClassWriter.TYPE_NORMAL:
- return i.strVal1.equals(strVal1);
- case ClassWriter.TYPE_UNINIT:
- return i.intVal == intVal && i.strVal1.equals(strVal1);
- case ClassWriter.NAME_TYPE:
- return i.strVal1.equals(strVal1)
- && i.strVal2.equals(strVal2);
- // ClassWriter.FIELD:
- // ClassWriter.METH:
- // ClassWriter.IMETH:
- default:
- return i.strVal1.equals(strVal1)
- && i.strVal2.equals(strVal2)
- && i.strVal3.equals(strVal3);
- }
+ switch (type) {
+ case ClassWriter.UTF8:
+ case ClassWriter.STR:
+ case ClassWriter.CLASS:
+ case ClassWriter.MTYPE:
+ case ClassWriter.TYPE_NORMAL:
+ return i.strVal1.equals(strVal1);
+ case ClassWriter.TYPE_MERGED:
+ case ClassWriter.LONG:
+ case ClassWriter.DOUBLE:
+ return i.longVal == longVal;
+ case ClassWriter.INT:
+ case ClassWriter.FLOAT:
+ return i.intVal == intVal;
+ case ClassWriter.TYPE_UNINIT:
+ return i.intVal == intVal && i.strVal1.equals(strVal1);
+ case ClassWriter.NAME_TYPE:
+ return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
+ case ClassWriter.INDY: {
+ return i.longVal == longVal && i.strVal1.equals(strVal1)
+ && i.strVal2.equals(strVal2);
+ }
+ // case ClassWriter.FIELD:
+ // case ClassWriter.METH:
+ // case ClassWriter.IMETH:
+ // case ClassWriter.HANDLE_BASE + 1..9
+ default:
+ return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
+ && i.strVal3.equals(strVal3);
}
- return false;
}
+
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Label.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Label.java
index 853b5b5a7..dec1a3359 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Label.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Label.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,11 @@
/**
* A label represents a position in the bytecode of a method. Labels are used
- * for jump, goto, and switch instructions, and for try catch blocks.
- *
+ * for jump, goto, and switch instructions, and for try catch blocks. A label
+ * designates the instruction that is just after. Note however that there
+ * can be other elements between a label and the instruction it designates (such
+ * as other labels, stack map frames, line numbers, etc.).
+ *
* @author Eric Bruneton
*/
public class Label {
@@ -93,21 +96,28 @@ public class Label {
static final int SUBROUTINE = 512;
/**
- * Indicates if this subroutine basic block has been visited.
+ * Indicates if this subroutine basic block has been visited by a
+ * visitSubroutine(null, ...) call.
*/
static final int VISITED = 1024;
+ /**
+ * Indicates if this subroutine basic block has been visited by a
+ * visitSubroutine(!null, ...) call.
+ */
+ static final int VISITED2 = 2048;
+
/**
* Field used to associate user information to a label. Warning: this field
* is used by the ASM tree package. In order to use it with the ASM tree
- * package you must override the {@link
- * jersey.repackaged.org.objectweb.asm.tree.MethodNode#getLabelNode} method.
+ * package you must override the
+ * {@link org.objectweb.asm.tree.MethodNode#getLabelNode} method.
*/
public Object info;
/**
* Flags that indicate the status of this label.
- *
+ *
* @see #DEBUG
* @see #RESOLVED
* @see #RESIZED
@@ -144,7 +154,7 @@ public class Label {
* indicates if this reference uses 2 or 4 bytes, and its absolute value
* gives the position of the bytecode instruction. This array is also used
* as a bitset to store the subroutines to which a basic block belongs. This
- * information is needed in {@linked MethodWriter#visitMaxs}, after all
+ * information is needed in {@linked MethodWriter#visitMaxs}, after all
* forward references have been resolved. Hence the same array can be used
* for both purposes without problems.
*/
@@ -160,19 +170,19 @@ public class Label {
* represented by the Label object that corresponds to the first instruction
* of this basic block. Each node also stores the list of its successors in
* the graph, as a linked list of Edge objects.
- *
+ *
* The control flow analysis algorithms used to compute the maximum stack
* size or the stack map frames are similar and use two steps. The first
* step, during the visit of each instruction, builds information about the
* state of the local variables and the operand stack at the end of each
* basic block, called the "output frame", relatively to the frame
* state at the beginning of the basic block, which is called the "input
- * frame", and which is unknown during this step. The second step,
- * in {@link MethodWriter#visitMaxs}, is a fix point algorithm that
- * computes information about the input frame of each basic block, from the
- * input state of the first basic block (known from the method signature),
- * and by the using the previously computed relative output frames.
- *
+ * frame", and which is unknown during this step. The second step, in
+ * {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes
+ * information about the input frame of each basic block, from the input
+ * state of the first basic block (known from the method signature), and by
+ * the using the previously computed relative output frames.
+ *
* The algorithm used to compute the maximum stack size only computes the
* relative output and absolute input stack heights, while the algorithm
* used to compute stack map frames computes relative output frames and
@@ -182,10 +192,10 @@ public class Label {
/**
* Start of the output stack relatively to the input stack. The exact
* semantics of this field depends on the algorithm that is used.
- *
+ *
* When only the maximum stack size is computed, this field is the number of
* elements in the input stack.
- *
+ *
* When the stack map frames are completely computed, this field is the
* offset of the first output stack element relatively to the top of the
* input stack. This offset is always negative or null. A null offset means
@@ -228,8 +238,9 @@ public class Label {
/**
* The next basic block in the basic block stack. This stack is used in the
* main loop of the fix point algorithm used in the second step of the
- * control flow analysis algorithms.
- *
+ * control flow analysis algorithms. It is also used in
+ * {@link #visitSubroutine} to avoid using a recursive method.
+ *
* @see MethodWriter#visitMaxs
*/
Label next;
@@ -253,13 +264,15 @@ public Label() {
* from the start of the method's bytecode. This method is intended for
* {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
- *
+ *
* @return the offset corresponding to this label.
- * @throws IllegalStateException if this label is not resolved yet.
+ * @throws IllegalStateException
+ * if this label is not resolved yet.
*/
public int getOffset() {
if ((status & RESOLVED) == 0) {
- throw new IllegalStateException("Label offset position has not been resolved yet");
+ throw new IllegalStateException(
+ "Label offset position has not been resolved yet");
}
return position;
}
@@ -269,22 +282,22 @@ public int getOffset() {
* position of the label is known, the offset is computed and written
* directly. Otherwise, a null offset is written and a new forward reference
* is declared for this label.
- *
- * @param owner the code writer that calls this method.
- * @param out the bytecode of the method.
- * @param source the position of first byte of the bytecode instruction that
- * contains this label.
- * @param wideOffset true if the reference must be stored in 4
- * bytes, or false if it must be stored with 2 bytes.
- * @throws IllegalArgumentException if this label has not been created by
- * the given code writer.
- */
- void put(
- final MethodWriter owner,
- final ByteVector out,
- final int source,
- final boolean wideOffset)
- {
+ *
+ * @param owner
+ * the code writer that calls this method.
+ * @param out
+ * the bytecode of the method.
+ * @param source
+ * the position of first byte of the bytecode instruction that
+ * contains this label.
+ * @param wideOffset
+ * true if the reference must be stored in 4 bytes, or
+ * false if it must be stored with 2 bytes.
+ * @throws IllegalArgumentException
+ * if this label has not been created by the given code writer.
+ */
+ void put(final MethodWriter owner, final ByteVector out, final int source,
+ final boolean wideOffset) {
if ((status & RESOLVED) == 0) {
if (wideOffset) {
addReference(-1 - source, out.length);
@@ -307,26 +320,22 @@ void put(
* for a true forward reference, i.e. only if this label is not resolved
* yet. For backward references, the offset of the reference can be, and
* must be, computed and stored directly.
- *
- * @param sourcePosition the position of the referencing instruction. This
- * position will be used to compute the offset of this forward
- * reference.
- * @param referencePosition the position where the offset for this forward
- * reference must be stored.
- */
- private void addReference(
- final int sourcePosition,
- final int referencePosition)
- {
+ *
+ * @param sourcePosition
+ * the position of the referencing instruction. This position
+ * will be used to compute the offset of this forward reference.
+ * @param referencePosition
+ * the position where the offset for this forward reference must
+ * be stored.
+ */
+ private void addReference(final int sourcePosition,
+ final int referencePosition) {
if (srcAndRefPositions == null) {
srcAndRefPositions = new int[6];
}
if (referenceCount >= srcAndRefPositions.length) {
int[] a = new int[srcAndRefPositions.length + 6];
- System.arraycopy(srcAndRefPositions,
- 0,
- a,
- 0,
+ System.arraycopy(srcAndRefPositions, 0, a, 0,
srcAndRefPositions.length);
srcAndRefPositions = a;
}
@@ -339,10 +348,13 @@ private void addReference(
* when this label is added to the bytecode of the method, i.e. when its
* position becomes known. This method fills in the blanks that where left
* in the bytecode by each forward reference previously added to this label.
- *
- * @param owner the code writer that calls this method.
- * @param position the position of this label in the bytecode.
- * @param data the bytecode of the method.
+ *
+ * @param owner
+ * the code writer that calls this method.
+ * @param position
+ * the position of this label in the bytecode.
+ * @param data
+ * the bytecode of the method.
* @return true if a blank that was left for this label was to
* small to store the offset. In such a case the corresponding jump
* instruction is replaced with a pseudo instruction (using unused
@@ -350,14 +362,12 @@ private void addReference(
* instructions will need to be replaced with true instructions with
* wider offsets (4 bytes instead of 2). This is done in
* {@link MethodWriter#resizeInstructions}.
- * @throws IllegalArgumentException if this label has already been resolved,
- * or if it has not been created by the given code writer.
- */
- boolean resolve(
- final MethodWriter owner,
- final int position,
- final byte[] data)
- {
+ * @throws IllegalArgumentException
+ * if this label has already been resolved, or if it has not
+ * been created by the given code writer.
+ */
+ boolean resolve(final MethodWriter owner, final int position,
+ final byte[] data) {
boolean needUpdate = false;
this.status |= RESOLVED;
this.position = position;
@@ -406,7 +416,7 @@ boolean resolve(
* isolated label or for the first label in a series of successive labels,
* this method returns the label itself. For other labels it returns the
* first label of the series.
- *
+ *
* @return the first label of the series to which this label belongs.
*/
Label getFirst() {
@@ -419,8 +429,9 @@ Label getFirst() {
/**
* Returns true is this basic block belongs to the given subroutine.
- *
- * @param id a subroutine id.
+ *
+ * @param id
+ * a subroutine id.
* @return true is this basic block belongs to the given subroutine.
*/
boolean inSubroutine(final long id) {
@@ -433,12 +444,16 @@ boolean inSubroutine(final long id) {
/**
* Returns true if this basic block and the given one belong to a common
* subroutine.
- *
- * @param block another basic block.
+ *
+ * @param block
+ * another basic block.
* @return true if this basic block and the given one belong to a common
* subroutine.
*/
boolean inSameSubroutine(final Label block) {
+ if ((status & VISITED) == 0 || (block.status & VISITED) == 0) {
+ return false;
+ }
for (int i = 0; i < srcAndRefPositions.length; ++i) {
if ((srcAndRefPositions[i] & block.srcAndRefPositions[i]) != 0) {
return true;
@@ -449,9 +464,11 @@ boolean inSameSubroutine(final Label block) {
/**
* Marks this basic block as belonging to the given subroutine.
- *
- * @param id a subroutine id.
- * @param nbSubroutines the total number of subroutines in the method.
+ *
+ * @param id
+ * a subroutine id.
+ * @param nbSubroutines
+ * the total number of subroutines in the method.
*/
void addToSubroutine(final long id, final int nbSubroutines) {
if ((status & VISITED) == 0) {
@@ -463,51 +480,67 @@ void addToSubroutine(final long id, final int nbSubroutines) {
/**
* Finds the basic blocks that belong to a given subroutine, and marks these
- * blocks as belonging to this subroutine. This recursive method follows the
- * control flow graph to find all the blocks that are reachable from the
- * current block WITHOUT following any JSR target.
- *
- * @param JSR a JSR block that jumps to this subroutine. If this JSR is not
- * null it is added to the successor of the RET blocks found in the
- * subroutine.
- * @param id the id of this subroutine.
- * @param nbSubroutines the total number of subroutines in the method.
- */
- void visitSubroutine(final Label JSR, final long id, final int nbSubroutines)
- {
- if (JSR != null) {
- if ((status & VISITED) != 0) {
- return;
- }
- status |= VISITED;
- // adds JSR to the successors of this block, if it is a RET block
- if ((status & RET) != 0) {
- if (!inSameSubroutine(JSR)) {
- Edge e = new Edge();
- e.info = inputStackTop;
- e.successor = JSR.successors.successor;
- e.next = successors;
- successors = e;
+ * blocks as belonging to this subroutine. This method follows the control
+ * flow graph to find all the blocks that are reachable from the current
+ * block WITHOUT following any JSR target.
+ *
+ * @param JSR
+ * a JSR block that jumps to this subroutine. If this JSR is not
+ * null it is added to the successor of the RET blocks found in
+ * the subroutine.
+ * @param id
+ * the id of this subroutine.
+ * @param nbSubroutines
+ * the total number of subroutines in the method.
+ */
+ void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) {
+ // user managed stack of labels, to avoid using a recursive method
+ // (recursivity can lead to stack overflow with very large methods)
+ Label stack = this;
+ while (stack != null) {
+ // removes a label l from the stack
+ Label l = stack;
+ stack = l.next;
+ l.next = null;
+
+ if (JSR != null) {
+ if ((l.status & VISITED2) != 0) {
+ continue;
}
+ l.status |= VISITED2;
+ // adds JSR to the successors of l, if it is a RET block
+ if ((l.status & RET) != 0) {
+ if (!l.inSameSubroutine(JSR)) {
+ Edge e = new Edge();
+ e.info = l.inputStackTop;
+ e.successor = JSR.successors.successor;
+ e.next = l.successors;
+ l.successors = e;
+ }
+ }
+ } else {
+ // if the l block already belongs to subroutine 'id', continue
+ if (l.inSubroutine(id)) {
+ continue;
+ }
+ // marks the l block as belonging to subroutine 'id'
+ l.addToSubroutine(id, nbSubroutines);
}
- } else {
- // if this block already belongs to subroutine 'id', returns
- if (inSubroutine(id)) {
- return;
- }
- // marks this block as belonging to subroutine 'id'
- addToSubroutine(id, nbSubroutines);
- }
- // calls this method recursively on each successor, except JSR targets
- Edge e = successors;
- while (e != null) {
- // if this block is a JSR block, then 'successors.next' leads
- // to the JSR target (see {@link #visitJumpInsn}) and must therefore
- // not be followed
- if ((status & Label.JSR) == 0 || e != successors.next) {
- e.successor.visitSubroutine(JSR, id, nbSubroutines);
+ // pushes each successor of l on the stack, except JSR targets
+ Edge e = l.successors;
+ while (e != null) {
+ // if the l block is a JSR block, then 'l.successors.next' leads
+ // to the JSR target (see {@link #visitJumpInsn}) and must
+ // therefore not be followed
+ if ((l.status & Label.JSR) == 0 || e != l.successors.next) {
+ // pushes e.successor on the stack if it not already added
+ if (e.successor.next == null) {
+ e.successor.next = stack;
+ stack = e.successor;
+ }
+ }
+ e = e.next;
}
- e = e.next;
}
}
@@ -517,9 +550,10 @@ void visitSubroutine(final Label JSR, final long id, final int nbSubroutines)
/**
* Returns a string representation of this label.
- *
+ *
* @return a string representation of this label.
*/
+ @Override
public String toString() {
return "L" + System.identityHashCode(this);
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodVisitor.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodVisitor.java
index 87e6de935..5b67582ae 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodVisitor.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodVisitor.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,130 +30,286 @@
package jersey.repackaged.org.objectweb.asm;
/**
- * A visitor to visit a Java method. The methods of this interface must be
- * called in the following order: [ visitAnnotationDefault ] (
- * visitAnnotation | visitParameterAnnotation |
- * visitAttribute )* [ visitCode ( visitFrame |
- * visitXInsn
| visitLabel | visitTryCatchBlock |
- * visitLocalVariable | visitLineNumber)* visitMaxs ]
- * visitEnd. In addition, the visitXInsn
- * and visitLabel methods must be called in the sequential order of
- * the bytecode instructions of the visited code, visitTryCatchBlock
- * must be called before the labels passed as arguments have been
- * visited, and the visitLocalVariable and visitLineNumber
- * methods must be called after the labels passed as arguments have been
- * visited.
- *
+ * A visitor to visit a Java method. The methods of this class must be called in
+ * the following order: ( visitParameter )* [
+ * visitAnnotationDefault ] ( visitAnnotation |
+ * visitTypeAnnotation | visitAttribute )* [
+ * visitCode ( visitFrame | visitXInsn |
+ * visitLabel | visitInsnAnnotation |
+ * visitTryCatchBlock | visitTryCatchBlockAnnotation |
+ * visitLocalVariable | visitLocalVariableAnnotation |
+ * visitLineNumber )* visitMaxs ] visitEnd. In
+ * addition, the visitXInsn and visitLabel methods must
+ * be called in the sequential order of the bytecode instructions of the visited
+ * code, visitInsnAnnotation must be called after the annotated
+ * instruction, visitTryCatchBlock must be called before the
+ * labels passed as arguments have been visited,
+ * visitTryCatchBlockAnnotation must be called after the
+ * corresponding try catch block has been visited, and the
+ * visitLocalVariable, visitLocalVariableAnnotation and
+ * visitLineNumber methods must be called after the labels
+ * passed as arguments have been visited.
+ *
* @author Eric Bruneton
*/
-public interface MethodVisitor {
+public abstract class MethodVisitor {
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ protected final int api;
+
+ /**
+ * The method visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected MethodVisitor mv;
+
+ /**
+ * Constructs a new {@link MethodVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ public MethodVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link MethodVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * @param mv
+ * the method visitor to which this visitor must delegate method
+ * calls. May be null.
+ */
+ public MethodVisitor(final int api, final MethodVisitor mv) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ throw new IllegalArgumentException();
+ }
+ this.api = api;
+ this.mv = mv;
+ }
// -------------------------------------------------------------------------
- // Annotations and non standard attributes
+ // Parameters, annotations and non standard attributes
// -------------------------------------------------------------------------
+ /**
+ * Visits a parameter of this method.
+ *
+ * @param name
+ * parameter name or null if none is provided.
+ * @param access
+ * the parameter's access flags, only ACC_FINAL,
+ * ACC_SYNTHETIC or/and ACC_MANDATED are
+ * allowed (see {@link Opcodes}).
+ */
+ public void visitParameter(String name, int access) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ mv.visitParameter(name, access);
+ }
+ }
+
/**
* Visits the default value of this annotation interface method.
- *
+ *
* @return a visitor to the visit the actual default value of this
- * annotation interface method, or null if this visitor
- * is not interested in visiting this default value. The 'name'
+ * annotation interface method, or null if this visitor is
+ * not interested in visiting this default value. The 'name'
* parameters passed to the methods of this annotation visitor are
* ignored. Moreover, exacly one visit method must be called on this
* annotation visitor, followed by visitEnd.
*/
- AnnotationVisitor visitAnnotationDefault();
+ public AnnotationVisitor visitAnnotationDefault() {
+ if (mv != null) {
+ return mv.visitAnnotationDefault();
+ }
+ return null;
+ }
/**
* Visits an annotation of this method.
- *
- * @param desc the class descriptor of the annotation class.
- * @param visible true if the annotation is visible at runtime.
+ *
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or null if
* this visitor is not interested in visiting this annotation.
*/
- AnnotationVisitor visitAnnotation(String desc, boolean visible);
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ if (mv != null) {
+ return mv.visitAnnotation(desc, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits an annotation on a type in the method signature.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#METHOD_TYPE_PARAMETER
+ * METHOD_TYPE_PARAMETER},
+ * {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND
+ * METHOD_TYPE_PARAMETER_BOUND},
+ * {@link TypeReference#METHOD_RETURN METHOD_RETURN},
+ * {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER},
+ * {@link TypeReference#METHOD_FORMAL_PARAMETER
+ * METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS
+ * THROWS}. See {@link TypeReference}.
+ * @param typePath
+ * the path to the annotated type argument, wildcard bound, array
+ * element type, or static inner type within 'typeRef'. May be
+ * null if the annotation targets 'typeRef' as a whole.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ return mv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
/**
* Visits an annotation of a parameter this method.
- *
- * @param parameter the parameter index.
- * @param desc the class descriptor of the annotation class.
- * @param visible true if the annotation is visible at runtime.
+ *
+ * @param parameter
+ * the parameter index.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or null if
* this visitor is not interested in visiting this annotation.
*/
- AnnotationVisitor visitParameterAnnotation(
- int parameter,
- String desc,
- boolean visible);
+ public AnnotationVisitor visitParameterAnnotation(int parameter,
+ String desc, boolean visible) {
+ if (mv != null) {
+ return mv.visitParameterAnnotation(parameter, desc, visible);
+ }
+ return null;
+ }
/**
* Visits a non standard attribute of this method.
- *
- * @param attr an attribute.
+ *
+ * @param attr
+ * an attribute.
*/
- void visitAttribute(Attribute attr);
+ public void visitAttribute(Attribute attr) {
+ if (mv != null) {
+ mv.visitAttribute(attr);
+ }
+ }
/**
* Starts the visit of the method's code, if any (i.e. non abstract method).
*/
- void visitCode();
+ public void visitCode() {
+ if (mv != null) {
+ mv.visitCode();
+ }
+ }
/**
* Visits the current state of the local variables and operand stack
* elements. This method must(*) be called just before any
- * instruction i that follows an unconditionnal branch instruction
+ * instruction i that follows an unconditional branch instruction
* such as GOTO or THROW, that is the target of a jump instruction, or that
* starts an exception handler block. The visited types must describe the
* values of the local variables and of the operand stack elements just
- * beforei is executed.
(*) this is mandatory only
- * for classes whose version is greater than or equal to
- * {@link Opcodes#V1_6 V1_6}.
Packed frames are basically
- * "deltas" from the state of the previous frame (very first frame is
- * implicitly defined by the method's parameters and access flags):
+ * before
i is executed.
+ *
+ * (*) this is mandatory only for classes whose version is greater than or
+ * equal to {@link Opcodes#V1_6 V1_6}.
+ *
+ * The frames of a method must be given either in expanded form, or in
+ * compressed form (all frames must use the same format, i.e. you must not
+ * mix expanded and compressed frames within a single method):
+ *
+ *
In expanded form, all frames must have the F_NEW type.
+ *
In compressed form, frames are basically "deltas" from the state of
+ * the previous frame:
+ *
*
{@link Opcodes#F_SAME} representing frame with exactly the same
- * locals as the previous frame and with the empty stack.
{@link Opcodes#F_SAME1}
- * representing frame with exactly the same locals as the previous frame and
- * with single value on the stack (nStack is 1 and
- * stack[0] contains value for the type of the stack item).
+ * locals as the previous frame and with the empty stack.
+ *
{@link Opcodes#F_SAME1} representing frame with exactly the same
+ * locals as the previous frame and with single value on the stack (
+ * nStack is 1 and stack[0] contains value for the
+ * type of the stack item).
*
{@link Opcodes#F_APPEND} representing frame with current locals are
* the same as the locals in the previous frame, except that additional
* locals are defined (nLocal is 1, 2 or 3 and
* local elements contains values representing added types).
- *
{@link Opcodes#F_CHOP} representing frame with current locals are
- * the same as the locals in the previous frame, except that the last 1-3
- * locals are absent and with the empty stack (nLocals is 1,
- * 2 or 3).
- *
- * @param type the type of this stack map frame. Must be
- * {@link Opcodes#F_NEW} for expanded frames, or
- * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
- * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
- * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed
- * frames.
- * @param nLocal the number of local variables in the visited frame.
- * @param local the local variable types in this frame. This array must not
- * be modified. Primitive types are represented by
- * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
- * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
- * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
- * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
- * represented by a single element). Reference types are represented
- * by String objects (representing internal names), and uninitialized
- * types by Label objects (this label designates the NEW instruction
- * that created this uninitialized value).
- * @param nStack the number of operand stack elements in the visited frame.
- * @param stack the operand stack types in this frame. This array must not
- * be modified. Its content has the same format as the "local" array.
- */
- void visitFrame(
- int type,
- int nLocal,
- Object[] local,
- int nStack,
- Object[] stack);
+ *
{@link Opcodes#F_CHOP} representing frame with current locals are the
+ * same as the locals in the previous frame, except that the last 1-3 locals
+ * are absent and with the empty stack (nLocals is 1, 2 or 3).
+ *
+ *
+ *
+ *
+ * In both cases the first frame, corresponding to the method's parameters
+ * and access flags, is implicit and must not be visited. Also, it is
+ * illegal to visit two or more frames for the same code location (i.e., at
+ * least one instruction must be visited between two calls to visitFrame).
+ *
+ * @param type
+ * the type of this stack map frame. Must be
+ * {@link Opcodes#F_NEW} for expanded frames, or
+ * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
+ * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
+ * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
+ * compressed frames.
+ * @param nLocal
+ * the number of local variables in the visited frame.
+ * @param local
+ * the local variable types in this frame. This array must not be
+ * modified. Primitive types are represented by
+ * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+ * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+ * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+ * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+ * represented by a single element). Reference types are
+ * represented by String objects (representing internal names),
+ * and uninitialized types by Label objects (this label
+ * designates the NEW instruction that created this uninitialized
+ * value).
+ * @param nStack
+ * the number of operand stack elements in the visited frame.
+ * @param stack
+ * the operand stack types in this frame. This array must not be
+ * modified. Its content has the same format as the "local"
+ * array.
+ * @throws IllegalStateException
+ * if a frame is visited just after another one, without any
+ * instruction between the two (unless this frame is a
+ * Opcodes#F_SAME frame, in which case it is silently ignored).
+ */
+ public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+ Object[] stack) {
+ if (mv != null) {
+ mv.visitFrame(type, nLocal, local, nStack, stack);
+ }
+ }
// -------------------------------------------------------------------------
// Normal instructions
@@ -161,165 +317,351 @@ void visitFrame(
/**
* Visits a zero operand instruction.
- *
- * @param opcode the opcode of the instruction to be visited. This opcode is
- * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2,
- * ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0,
- * FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD,
- * DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE,
- * DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP,
- * DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD,
- * DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
- * FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL,
- * LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR,
- * I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B,
- * I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
- * FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
- * MONITORENTER, or MONITOREXIT.
- */
- void visitInsn(int opcode);
+ *
+ * @param opcode
+ * the opcode of the instruction to be visited. This opcode is
+ * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
+ * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
+ * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
+ * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
+ * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
+ * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
+ * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
+ * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
+ * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
+ * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
+ * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
+ * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+ * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
+ * or MONITOREXIT.
+ */
+ public void visitInsn(int opcode) {
+ if (mv != null) {
+ mv.visitInsn(opcode);
+ }
+ }
/**
* Visits an instruction with a single int operand.
- *
- * @param opcode the opcode of the instruction to be visited. This opcode is
- * either BIPUSH, SIPUSH or NEWARRAY.
- * @param operand the operand of the instruction to be visited. When
- * opcode is BIPUSH, operand value should be between Byte.MIN_VALUE
- * and Byte.MAX_VALUE. When opcode is SIPUSH, operand value
- * should be between Short.MIN_VALUE and Short.MAX_VALUE. When
- * opcode is NEWARRAY, operand value should be one of
- * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
- * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
- * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
- * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
- */
- void visitIntInsn(int opcode, int operand);
+ *
+ * @param opcode
+ * the opcode of the instruction to be visited. This opcode is
+ * either BIPUSH, SIPUSH or NEWARRAY.
+ * @param operand
+ * the operand of the instruction to be visited.
+ * When opcode is BIPUSH, operand value should be between
+ * Byte.MIN_VALUE and Byte.MAX_VALUE.
+ * When opcode is SIPUSH, operand value should be between
+ * Short.MIN_VALUE and Short.MAX_VALUE.
+ * When opcode is NEWARRAY, operand value should be one of
+ * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
+ * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
+ * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
+ * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
+ */
+ public void visitIntInsn(int opcode, int operand) {
+ if (mv != null) {
+ mv.visitIntInsn(opcode, operand);
+ }
+ }
/**
* Visits a local variable instruction. A local variable instruction is an
* instruction that loads or stores the value of a local variable.
- *
- * @param opcode the opcode of the local variable instruction to be visited.
- * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE,
- * LSTORE, FSTORE, DSTORE, ASTORE or RET.
- * @param var the operand of the instruction to be visited. This operand is
- * the index of a local variable.
+ *
+ * @param opcode
+ * the opcode of the local variable instruction to be visited.
+ * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
+ * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+ * @param var
+ * the operand of the instruction to be visited. This operand is
+ * the index of a local variable.
*/
- void visitVarInsn(int opcode, int var);
+ public void visitVarInsn(int opcode, int var) {
+ if (mv != null) {
+ mv.visitVarInsn(opcode, var);
+ }
+ }
/**
* Visits a type instruction. A type instruction is an instruction that
* takes the internal name of a class as parameter.
- *
- * @param opcode the opcode of the type instruction to be visited. This
- * opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
- * @param type the operand of the instruction to be visited. This operand
- * must be the internal name of an object or array class (see {@link
- * Type#getInternalName() getInternalName}).
+ *
+ * @param opcode
+ * the opcode of the type instruction to be visited. This opcode
+ * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
+ * @param type
+ * the operand of the instruction to be visited. This operand
+ * must be the internal name of an object or array class (see
+ * {@link Type#getInternalName() getInternalName}).
*/
- void visitTypeInsn(int opcode, String type);
+ public void visitTypeInsn(int opcode, String type) {
+ if (mv != null) {
+ mv.visitTypeInsn(opcode, type);
+ }
+ }
/**
* Visits a field instruction. A field instruction is an instruction that
* loads or stores the value of a field of an object.
- *
- * @param opcode the opcode of the type instruction to be visited. This
- * opcode is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
- * @param owner the internal name of the field's owner class (see {@link
- * Type#getInternalName() getInternalName}).
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link Type Type}).
+ *
+ * @param opcode
+ * the opcode of the type instruction to be visited. This opcode
+ * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+ * @param owner
+ * the internal name of the field's owner class (see
+ * {@link Type#getInternalName() getInternalName}).
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link Type Type}).
*/
- void visitFieldInsn(int opcode, String owner, String name, String desc);
+ public void visitFieldInsn(int opcode, String owner, String name,
+ String desc) {
+ if (mv != null) {
+ mv.visitFieldInsn(opcode, owner, name, desc);
+ }
+ }
/**
* Visits a method instruction. A method instruction is an instruction that
* invokes a method.
- *
- * @param opcode the opcode of the type instruction to be visited. This
- * opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
- * INVOKEINTERFACE.
- * @param owner the internal name of the method's owner class (see {@link
- * Type#getInternalName() getInternalName}).
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type Type}).
+ *
+ * @param opcode
+ * the opcode of the type instruction to be visited. This opcode
+ * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+ * INVOKEINTERFACE.
+ * @param owner
+ * the internal name of the method's owner class (see
+ * {@link Type#getInternalName() getInternalName}).
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
+ */
+ public void visitMethodInsn(int opcode, String owner, String name,
+ String desc) {
+ if (mv != null) {
+ mv.visitMethodInsn(opcode, owner, name, desc);
+ }
+ }
+
+ /**
+ * Visits an invokedynamic instruction.
+ *
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
+ * @param bsm
+ * the bootstrap method.
+ * @param bsmArgs
+ * the bootstrap method constant arguments. Each argument must be
+ * an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double}, {@link String}, {@link Type} or {@link Handle}
+ * value. This method is allowed to modify the content of the
+ * array so a caller should expect that this array may change.
*/
- void visitMethodInsn(int opcode, String owner, String name, String desc);
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
+ if (mv != null) {
+ mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+ }
+ }
/**
* Visits a jump instruction. A jump instruction is an instruction that may
* jump to another instruction.
- *
- * @param opcode the opcode of the type instruction to be visited. This
- * opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
- * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
- * IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
- * @param label the operand of the instruction to be visited. This operand
- * is a label that designates the instruction to which the jump
- * instruction may jump.
+ *
+ * @param opcode
+ * the opcode of the type instruction to be visited. This opcode
+ * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+ * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+ * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+ * @param label
+ * the operand of the instruction to be visited. This operand is
+ * a label that designates the instruction to which the jump
+ * instruction may jump.
*/
- void visitJumpInsn(int opcode, Label label);
+ public void visitJumpInsn(int opcode, Label label) {
+ if (mv != null) {
+ mv.visitJumpInsn(opcode, label);
+ }
+ }
/**
* Visits a label. A label designates the instruction that will be visited
* just after it.
- *
- * @param label a {@link Label Label} object.
+ *
+ * @param label
+ * a {@link Label Label} object.
*/
- void visitLabel(Label label);
+ public void visitLabel(Label label) {
+ if (mv != null) {
+ mv.visitLabel(label);
+ }
+ }
// -------------------------------------------------------------------------
// Special instructions
// -------------------------------------------------------------------------
/**
- * Visits a LDC instruction.
- *
- * @param cst the constant to be loaded on the stack. This parameter must be
- * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
- * {@link Double} a {@link String} (or a {@link Type} for
- * .class constants, for classes whose version is 49.0 or
- * more).
+ * Visits a LDC instruction. Note that new constant types may be added in
+ * future versions of the Java Virtual Machine. To easily detect new
+ * constant types, implementations of this method should check for
+ * unexpected constant types, like this:
+ *
+ *
+ *
+ * @param cst
+ * the constant to be loaded on the stack. This parameter must be
+ * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double}, a {@link String}, a {@link Type} of OBJECT or
+ * ARRAY sort for .class constants, for classes whose
+ * version is 49.0, a {@link Type} of METHOD sort or a
+ * {@link Handle} for MethodType and MethodHandle constants, for
+ * classes whose version is 51.0.
*/
- void visitLdcInsn(Object cst);
+ public void visitLdcInsn(Object cst) {
+ if (mv != null) {
+ mv.visitLdcInsn(cst);
+ }
+ }
/**
* Visits an IINC instruction.
- *
- * @param var index of the local variable to be incremented.
- * @param increment amount to increment the local variable by.
+ *
+ * @param var
+ * index of the local variable to be incremented.
+ * @param increment
+ * amount to increment the local variable by.
*/
- void visitIincInsn(int var, int increment);
+ public void visitIincInsn(int var, int increment) {
+ if (mv != null) {
+ mv.visitIincInsn(var, increment);
+ }
+ }
/**
* Visits a TABLESWITCH instruction.
- *
- * @param min the minimum key value.
- * @param max the maximum key value.
- * @param dflt beginning of the default handler block.
- * @param labels beginnings of the handler blocks. labels[i] is
- * the beginning of the handler block for the min + i key.
+ *
+ * @param min
+ * the minimum key value.
+ * @param max
+ * the maximum key value.
+ * @param dflt
+ * beginning of the default handler block.
+ * @param labels
+ * beginnings of the handler blocks. labels[i] is the
+ * beginning of the handler block for the min + i key.
*/
- void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels);
+ public void visitTableSwitchInsn(int min, int max, Label dflt,
+ Label... labels) {
+ if (mv != null) {
+ mv.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+ }
/**
* Visits a LOOKUPSWITCH instruction.
- *
- * @param dflt beginning of the default handler block.
- * @param keys the values of the keys.
- * @param labels beginnings of the handler blocks. labels[i] is
- * the beginning of the handler block for the keys[i] key.
+ *
+ * @param dflt
+ * beginning of the default handler block.
+ * @param keys
+ * the values of the keys.
+ * @param labels
+ * beginnings of the handler blocks. labels[i] is the
+ * beginning of the handler block for the keys[i] key.
*/
- void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels);
+ public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+ if (mv != null) {
+ mv.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+ }
/**
* Visits a MULTIANEWARRAY instruction.
- *
- * @param desc an array type descriptor (see {@link Type Type}).
- * @param dims number of dimensions of the array to allocate.
+ *
+ * @param desc
+ * an array type descriptor (see {@link Type Type}).
+ * @param dims
+ * number of dimensions of the array to allocate.
*/
- void visitMultiANewArrayInsn(String desc, int dims);
+ public void visitMultiANewArrayInsn(String desc, int dims) {
+ if (mv != null) {
+ mv.visitMultiANewArrayInsn(desc, dims);
+ }
+ }
+
+ /**
+ * Visits an annotation on an instruction. This method must be called just
+ * after the annotated instruction. It can be called several times
+ * for the same instruction.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#INSTANCEOF INSTANCEOF},
+ * {@link TypeReference#NEW NEW},
+ * {@link TypeReference#CONSTRUCTOR_REFERENCE
+ * CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE
+ * METHOD_REFERENCE}, {@link TypeReference#CAST CAST},
+ * {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+ * {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT
+ * METHOD_INVOCATION_TYPE_ARGUMENT},
+ * {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+ * {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT
+ * METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
+ * @param typePath
+ * the path to the annotated type argument, wildcard bound, array
+ * element type, or static inner type within 'typeRef'. May be
+ * null if the annotation targets 'typeRef' as a whole.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitInsnAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ return mv.visitInsnAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
// -------------------------------------------------------------------------
// Exceptions table entries, debug information, max stack and max locals
@@ -327,69 +669,173 @@ void visitFrame(
/**
* Visits a try catch block.
- *
- * @param start beginning of the exception handler's scope (inclusive).
- * @param end end of the exception handler's scope (exclusive).
- * @param handler beginning of the exception handler's code.
- * @param type internal name of the type of exceptions handled by the
- * handler, or null to catch any exceptions (for "finally"
- * blocks).
- * @throws IllegalArgumentException if one of the labels has already been
- * visited by this visitor (by the {@link #visitLabel visitLabel}
- * method).
+ *
+ * @param start
+ * beginning of the exception handler's scope (inclusive).
+ * @param end
+ * end of the exception handler's scope (exclusive).
+ * @param handler
+ * beginning of the exception handler's code.
+ * @param type
+ * internal name of the type of exceptions handled by the
+ * handler, or null to catch any exceptions (for
+ * "finally" blocks).
+ * @throws IllegalArgumentException
+ * if one of the labels has already been visited by this visitor
+ * (by the {@link #visitLabel visitLabel} method).
*/
- void visitTryCatchBlock(Label start, Label end, Label handler, String type);
+ public void visitTryCatchBlock(Label start, Label end, Label handler,
+ String type) {
+ if (mv != null) {
+ mv.visitTryCatchBlock(start, end, handler, type);
+ }
+ }
+
+ /**
+ * Visits an annotation on an exception handler type. This method must be
+ * called after the {@link #visitTryCatchBlock} for the annotated
+ * exception handler. It can be called several times for the same exception
+ * handler.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#EXCEPTION_PARAMETER
+ * EXCEPTION_PARAMETER}. See {@link TypeReference}.
+ * @param typePath
+ * the path to the annotated type argument, wildcard bound, array
+ * element type, or static inner type within 'typeRef'. May be
+ * null if the annotation targets 'typeRef' as a whole.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
/**
* Visits a local variable declaration.
- *
- * @param name the name of a local variable.
- * @param desc the type descriptor of this local variable.
- * @param signature the type signature of this local variable. May be
- * null if the local variable type does not use generic
- * types.
- * @param start the first instruction corresponding to the scope of this
- * local variable (inclusive).
- * @param end the last instruction corresponding to the scope of this local
- * variable (exclusive).
- * @param index the local variable's index.
- * @throws IllegalArgumentException if one of the labels has not already
- * been visited by this visitor (by the
- * {@link #visitLabel visitLabel} method).
- */
- void visitLocalVariable(
- String name,
- String desc,
- String signature,
- Label start,
- Label end,
- int index);
+ *
+ * @param name
+ * the name of a local variable.
+ * @param desc
+ * the type descriptor of this local variable.
+ * @param signature
+ * the type signature of this local variable. May be
+ * null if the local variable type does not use generic
+ * types.
+ * @param start
+ * the first instruction corresponding to the scope of this local
+ * variable (inclusive).
+ * @param end
+ * the last instruction corresponding to the scope of this local
+ * variable (exclusive).
+ * @param index
+ * the local variable's index.
+ * @throws IllegalArgumentException
+ * if one of the labels has not already been visited by this
+ * visitor (by the {@link #visitLabel visitLabel} method).
+ */
+ public void visitLocalVariable(String name, String desc, String signature,
+ Label start, Label end, int index) {
+ if (mv != null) {
+ mv.visitLocalVariable(name, desc, signature, start, end, index);
+ }
+ }
+
+ /**
+ * Visits an annotation on a local variable type.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#LOCAL_VARIABLE
+ * LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE
+ * RESOURCE_VARIABLE}. See {@link TypeReference}.
+ * @param typePath
+ * the path to the annotated type argument, wildcard bound, array
+ * element type, or static inner type within 'typeRef'. May be
+ * null if the annotation targets 'typeRef' as a whole.
+ * @param start
+ * the fist instructions corresponding to the continuous ranges
+ * that make the scope of this local variable (inclusive).
+ * @param end
+ * the last instructions corresponding to the continuous ranges
+ * that make the scope of this local variable (exclusive). This
+ * array must have the same size as the 'start' array.
+ * @param index
+ * the local variable's index in each range. This array must have
+ * the same size as the 'start' array.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * true if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+ TypePath typePath, Label[] start, Label[] end, int[] index,
+ String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ return mv.visitLocalVariableAnnotation(typeRef, typePath, start,
+ end, index, desc, visible);
+ }
+ return null;
+ }
/**
* Visits a line number declaration.
- *
- * @param line a line number. This number refers to the source file from
- * which the class was compiled.
- * @param start the first instruction corresponding to this line number.
- * @throws IllegalArgumentException if start has not already been
- * visited by this visitor (by the {@link #visitLabel visitLabel}
- * method).
+ *
+ * @param line
+ * a line number. This number refers to the source file from
+ * which the class was compiled.
+ * @param start
+ * the first instruction corresponding to this line number.
+ * @throws IllegalArgumentException
+ * if start has not already been visited by this
+ * visitor (by the {@link #visitLabel visitLabel} method).
*/
- void visitLineNumber(int line, Label start);
+ public void visitLineNumber(int line, Label start) {
+ if (mv != null) {
+ mv.visitLineNumber(line, start);
+ }
+ }
/**
* Visits the maximum stack size and the maximum number of local variables
* of the method.
- *
- * @param maxStack maximum stack size of the method.
- * @param maxLocals maximum number of local variables for the method.
+ *
+ * @param maxStack
+ * maximum stack size of the method.
+ * @param maxLocals
+ * maximum number of local variables for the method.
*/
- void visitMaxs(int maxStack, int maxLocals);
+ public void visitMaxs(int maxStack, int maxLocals) {
+ if (mv != null) {
+ mv.visitMaxs(maxStack, maxLocals);
+ }
+ }
/**
* Visits the end of the method. This method, which is the last one to be
* called, is used to inform the visitor that all the annotations and
* attributes of the method have been visited.
*/
- void visitEnd();
+ public void visitEnd() {
+ if (mv != null) {
+ mv.visitEnd();
+ }
+ }
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
index 3775cf976..1fa10c67a 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,17 +33,17 @@
* A {@link MethodVisitor} that generates methods in bytecode form. Each visit
* method of this class appends the bytecode corresponding to the visited
* instruction to a byte vector, in the order these methods are called.
- *
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
-class MethodWriter implements MethodVisitor {
+class MethodWriter extends MethodVisitor {
/**
* Pseudo access flag used to denote constructors.
*/
- static final int ACC_CONSTRUCTOR = 262144;
-
+ static final int ACC_CONSTRUCTOR = 0x80000;
+
/**
* Frame has exactly the same locals as the previous stack map frame and
* number of stack items is zero.
@@ -96,7 +96,7 @@ class MethodWriter implements MethodVisitor {
* Indicates that the stack map frames must be recomputed from scratch. In
* this case the maximum stack size and number of local variables is also
* recomputed from scratch.
- *
+ *
* @see #compute
*/
private static final int FRAMES = 0;
@@ -104,23 +104,18 @@ class MethodWriter implements MethodVisitor {
/**
* Indicates that the maximum stack size and number of local variables must
* be automatically computed.
- *
+ *
* @see #compute
*/
private static final int MAXS = 1;
/**
* Indicates that nothing must be automatically computed.
- *
+ *
* @see #compute
*/
private static final int NOTHING = 2;
- /**
- * Next method writer (see {@link ClassWriter#firstMethod firstMethod}).
- */
- MethodWriter next;
-
/**
* The class writer to which this method must be added.
*/
@@ -196,6 +191,18 @@ class MethodWriter implements MethodVisitor {
*/
private AnnotationWriter ianns;
+ /**
+ * The runtime visible type annotations of this method. May be null
+ * .
+ */
+ private AnnotationWriter tanns;
+
+ /**
+ * The runtime invisible type annotations of this method. May be
+ * null.
+ */
+ private AnnotationWriter itanns;
+
/**
* The runtime visible parameter annotations of this method. May be
* null.
@@ -233,6 +240,11 @@ class MethodWriter implements MethodVisitor {
*/
private int maxLocals;
+ /**
+ * Number of local variables in the current stack map frame.
+ */
+ private int currentLocals;
+
/**
* Number of stack map frames in the StackMapTable attribute.
*/
@@ -251,16 +263,11 @@ class MethodWriter implements MethodVisitor {
/**
* The last frame that was written in the StackMapTable attribute.
- *
+ *
* @see #frame
*/
private int[] previousFrame;
- /**
- * Index of the next element to be added in {@link #frame}.
- */
- private int frameIndex;
-
/**
* The current stack map frame. The first element contains the offset of the
* instruction to which the frame corresponds, the second element is the
@@ -287,6 +294,16 @@ class MethodWriter implements MethodVisitor {
*/
private Handler lastHandler;
+ /**
+ * Number of entries in the MethodParameters attribute.
+ */
+ private int methodParametersCount;
+
+ /**
+ * The MethodParameters attribute.
+ */
+ private ByteVector methodParameters;
+
/**
* Number of entries in the LocalVariableTable attribute.
*/
@@ -317,6 +334,21 @@ class MethodWriter implements MethodVisitor {
*/
private ByteVector lineNumber;
+ /**
+ * The start offset of the last visited instruction.
+ */
+ private int lastCodeOffset;
+
+ /**
+ * The runtime visible type annotations of the code. May be null.
+ */
+ private AnnotationWriter ctanns;
+
+ /**
+ * The runtime invisible type annotations of the code. May be null.
+ */
+ private AnnotationWriter ictanns;
+
/**
* The non standard attributes of the method's code.
*/
@@ -346,7 +378,7 @@ class MethodWriter implements MethodVisitor {
/**
* Indicates what must be automatically computed.
- *
+ *
* @see #FRAMES
* @see #MAXS
* @see #NOTHING
@@ -357,7 +389,8 @@ class MethodWriter implements MethodVisitor {
* A list of labels. This list is the list of basic blocks in the method,
* i.e. a list of Label objects linked to each other by their
* {@link Label#successor} field, in the order they are visited by
- * {@link MethodVisitor#visitLabel}, and starting with the first basic block.
+ * {@link MethodVisitor#visitLabel}, and starting with the first basic
+ * block.
*/
private Label labels;
@@ -395,37 +428,43 @@ class MethodWriter implements MethodVisitor {
/**
* Constructs a new {@link MethodWriter}.
- *
- * @param cw the class writer in which the method must be added.
- * @param access the method's access flags (see {@link Opcodes}).
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type}).
- * @param signature the method's signature. May be null.
- * @param exceptions the internal names of the method's exceptions. May be
- * null.
- * @param computeMaxs true if the maximum stack size and number
- * of local variables must be automatically computed.
- * @param computeFrames true if the stack map tables must be
- * recomputed from scratch.
- */
- MethodWriter(
- final ClassWriter cw,
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions,
- final boolean computeMaxs,
- final boolean computeFrames)
- {
+ *
+ * @param cw
+ * the class writer in which the method must be added.
+ * @param access
+ * the method's access flags (see {@link Opcodes}).
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type}).
+ * @param signature
+ * the method's signature. May be null.
+ * @param exceptions
+ * the internal names of the method's exceptions. May be
+ * null.
+ * @param computeMaxs
+ * true if the maximum stack size and number of local
+ * variables must be automatically computed.
+ * @param computeFrames
+ * true if the stack map tables must be recomputed from
+ * scratch.
+ */
+ MethodWriter(final ClassWriter cw, final int access, final String name,
+ final String desc, final String signature,
+ final String[] exceptions, final boolean computeMaxs,
+ final boolean computeFrames) {
+ super(Opcodes.ASM5);
if (cw.firstMethod == null) {
cw.firstMethod = this;
} else {
- cw.lastMethod.next = this;
+ cw.lastMethod.mv = this;
}
cw.lastMethod = this;
this.cw = cw;
this.access = access;
+ if ("".equals(name)) {
+ this.access |= ACC_CONSTRUCTOR;
+ }
this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc);
this.descriptor = desc;
@@ -441,15 +480,13 @@ class MethodWriter implements MethodVisitor {
}
this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
if (computeMaxs || computeFrames) {
- if (computeFrames && "".equals(name)) {
- this.access |= ACC_CONSTRUCTOR;
- }
// updates maxLocals
- int size = getArgumentsAndReturnSizes(descriptor) >> 2;
+ int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
if ((access & Opcodes.ACC_STATIC) != 0) {
--size;
}
maxLocals = size;
+ currentLocals = size;
// creates and visits the label for the first basic block
labels = new Label();
labels.status |= Label.PUSHED;
@@ -458,9 +495,20 @@ class MethodWriter implements MethodVisitor {
}
// ------------------------------------------------------------------------
- // Implementation of the MethodVisitor interface
+ // Implementation of the MethodVisitor abstract class
// ------------------------------------------------------------------------
+ @Override
+ public void visitParameter(String name, int access) {
+ if (methodParameters == null) {
+ methodParameters = new ByteVector();
+ }
+ ++methodParametersCount;
+ methodParameters.putShort((name == null) ? 0 : cw.newUTF8(name))
+ .putShort(access);
+ }
+
+ @Override
public AnnotationVisitor visitAnnotationDefault() {
if (!ClassReader.ANNOTATIONS) {
return null;
@@ -469,10 +517,9 @@ public AnnotationVisitor visitAnnotationDefault() {
return new AnnotationWriter(cw, false, annd, null, 0);
}
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ @Override
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
if (!ClassReader.ANNOTATIONS) {
return null;
}
@@ -490,11 +537,32 @@ public AnnotationVisitor visitAnnotation(
return aw;
}
- public AnnotationVisitor visitParameterAnnotation(
- final int parameter,
- final String desc,
- final boolean visible)
- {
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+ final TypePath typePath, final String desc, final boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = tanns;
+ tanns = aw;
+ } else {
+ aw.next = itanns;
+ itanns = aw;
+ }
+ return aw;
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
if (!ClassReader.ANNOTATIONS) {
return null;
}
@@ -524,6 +592,7 @@ public AnnotationVisitor visitParameterAnnotation(
return aw;
}
+ @Override
public void visitAttribute(final Attribute attr) {
if (attr.isCodeAttribute()) {
attr.next = cattrs;
@@ -534,22 +603,23 @@ public void visitAttribute(final Attribute attr) {
}
}
+ @Override
public void visitCode() {
}
- public void visitFrame(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack)
- {
+ @Override
+ public void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack) {
if (!ClassReader.FRAMES || compute == FRAMES) {
return;
}
if (type == Opcodes.F_NEW) {
- startFrame(code.length, nLocal, nStack);
+ if (previousFrame == null) {
+ visitImplicitFirstFrame();
+ }
+ currentLocals = nLocal;
+ int frameIndex = startFrame(code.length, nLocal, nStack);
for (int i = 0; i < nLocal; ++i) {
if (local[i] instanceof String) {
frame[frameIndex++] = Frame.OBJECT
@@ -582,56 +652,67 @@ public void visitFrame(
delta = code.length;
} else {
delta = code.length - previousFrameOffset - 1;
+ if (delta < 0) {
+ if (type == Opcodes.F_SAME) {
+ return;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
}
switch (type) {
- case Opcodes.F_FULL:
- stackMap.putByte(FULL_FRAME)
- .putShort(delta)
- .putShort(nLocal);
- for (int i = 0; i < nLocal; ++i) {
- writeFrameType(local[i]);
- }
- stackMap.putShort(nStack);
- for (int i = 0; i < nStack; ++i) {
- writeFrameType(stack[i]);
- }
- break;
- case Opcodes.F_APPEND:
- stackMap.putByte(SAME_FRAME_EXTENDED + nLocal)
- .putShort(delta);
- for (int i = 0; i < nLocal; ++i) {
- writeFrameType(local[i]);
- }
- break;
- case Opcodes.F_CHOP:
- stackMap.putByte(SAME_FRAME_EXTENDED - nLocal)
+ case Opcodes.F_FULL:
+ currentLocals = nLocal;
+ stackMap.putByte(FULL_FRAME).putShort(delta).putShort(nLocal);
+ for (int i = 0; i < nLocal; ++i) {
+ writeFrameType(local[i]);
+ }
+ stackMap.putShort(nStack);
+ for (int i = 0; i < nStack; ++i) {
+ writeFrameType(stack[i]);
+ }
+ break;
+ case Opcodes.F_APPEND:
+ currentLocals += nLocal;
+ stackMap.putByte(SAME_FRAME_EXTENDED + nLocal).putShort(delta);
+ for (int i = 0; i < nLocal; ++i) {
+ writeFrameType(local[i]);
+ }
+ break;
+ case Opcodes.F_CHOP:
+ currentLocals -= nLocal;
+ stackMap.putByte(SAME_FRAME_EXTENDED - nLocal).putShort(delta);
+ break;
+ case Opcodes.F_SAME:
+ if (delta < 64) {
+ stackMap.putByte(delta);
+ } else {
+ stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+ }
+ break;
+ case Opcodes.F_SAME1:
+ if (delta < 64) {
+ stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+ } else {
+ stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
.putShort(delta);
- break;
- case Opcodes.F_SAME:
- if (delta < 64) {
- stackMap.putByte(delta);
- } else {
- stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
- }
- break;
- case Opcodes.F_SAME1:
- if (delta < 64) {
- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
- } else {
- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
- .putShort(delta);
- }
- writeFrameType(stack[0]);
- break;
+ }
+ writeFrameType(stack[0]);
+ break;
}
previousFrameOffset = code.length;
++frameCount;
}
+
+ maxStack = Math.max(maxStack, nStack);
+ maxLocals = Math.max(maxLocals, currentLocals);
}
+ @Override
public void visitInsn(final int opcode) {
+ lastCodeOffset = code.length;
// adds the instruction to the bytecode of the method
code.putByte(opcode);
// update currentBlock
@@ -649,14 +730,15 @@ public void visitInsn(final int opcode) {
}
// if opcode == ATHROW or xRETURN, ends current block (no successor)
if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
- || opcode == Opcodes.ATHROW)
- {
+ || opcode == Opcodes.ATHROW) {
noSuccessor();
}
}
}
+ @Override
public void visitIntInsn(final int opcode, final int operand) {
+ lastCodeOffset = code.length;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
if (compute == FRAMES) {
@@ -679,7 +761,9 @@ public void visitIntInsn(final int opcode, final int operand) {
}
}
+ @Override
public void visitVarInsn(final int opcode, final int var) {
+ lastCodeOffset = code.length;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
if (compute == FRAMES) {
@@ -706,8 +790,7 @@ public void visitVarInsn(final int opcode, final int var) {
// updates max locals
int n;
if (opcode == Opcodes.LLOAD || opcode == Opcodes.DLOAD
- || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE)
- {
+ || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE) {
n = var + 2;
} else {
n = var + 1;
@@ -737,7 +820,9 @@ public void visitVarInsn(final int opcode, final int var) {
}
}
+ @Override
public void visitTypeInsn(final int opcode, final String type) {
+ lastCodeOffset = code.length;
Item i = cw.newClassItem(type);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -757,12 +842,10 @@ public void visitTypeInsn(final int opcode, final String type) {
code.put12(opcode, i.index);
}
- public void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ @Override
+ public void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc) {
+ lastCodeOffset = code.length;
Item i = cw.newFieldItem(owner, name, desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -773,19 +856,19 @@ public void visitFieldInsn(
// computes the stack size variation
char c = desc.charAt(0);
switch (opcode) {
- case Opcodes.GETSTATIC:
- size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
- break;
- case Opcodes.PUTSTATIC:
- size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
- break;
- case Opcodes.GETFIELD:
- size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
- break;
- // case Constants.PUTFIELD:
- default:
- size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
- break;
+ case Opcodes.GETSTATIC:
+ size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
+ break;
+ case Opcodes.PUTSTATIC:
+ size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
+ break;
+ case Opcodes.GETFIELD:
+ size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
+ break;
+ // case Constants.PUTFIELD:
+ default:
+ size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
+ break;
}
// updates current and max stack sizes
if (size > maxStackSize) {
@@ -798,12 +881,10 @@ public void visitFieldInsn(
code.put12(opcode, i.index);
}
- public void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ @Override
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc) {
+ lastCodeOffset = code.length;
boolean itf = opcode == Opcodes.INVOKEINTERFACE;
Item i = cw.newMethodItem(owner, name, desc, itf);
int argSize = i.intVal;
@@ -823,7 +904,7 @@ public void visitMethodInsn(
if (argSize == 0) {
// the above sizes have not been computed yet,
// so we compute them...
- argSize = getArgumentsAndReturnSizes(desc);
+ argSize = Type.getArgumentsAndReturnSizes(desc);
// ... and we save them in order
// not to recompute them in the future
i.intVal = argSize;
@@ -844,7 +925,7 @@ public void visitMethodInsn(
// adds the instruction to the bytecode of the method
if (itf) {
if (argSize == 0) {
- argSize = getArgumentsAndReturnSizes(desc);
+ argSize = Type.getArgumentsAndReturnSizes(desc);
i.intVal = argSize;
}
code.put12(Opcodes.INVOKEINTERFACE, i.index).put11(argSize >> 2, 0);
@@ -853,7 +934,50 @@ public void visitMethodInsn(
}
}
+ @Override
+ public void visitInvokeDynamicInsn(final String name, final String desc,
+ final Handle bsm, final Object... bsmArgs) {
+ lastCodeOffset = code.length;
+ Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
+ int argSize = i.intVal;
+ // Label currentBlock = this.currentBlock;
+ if (currentBlock != null) {
+ if (compute == FRAMES) {
+ currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
+ } else {
+ /*
+ * computes the stack size variation. In order not to recompute
+ * several times this variation for the same Item, we use the
+ * intVal field of this item to store this variation, once it
+ * has been computed. More precisely this intVal field stores
+ * the sizes of the arguments and of the return value
+ * corresponding to desc.
+ */
+ if (argSize == 0) {
+ // the above sizes have not been computed yet,
+ // so we compute them...
+ argSize = Type.getArgumentsAndReturnSizes(desc);
+ // ... and we save them in order
+ // not to recompute them in the future
+ i.intVal = argSize;
+ }
+ int size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1;
+
+ // updates current and max stack sizes
+ if (size > maxStackSize) {
+ maxStackSize = size;
+ }
+ stackSize = size;
+ }
+ }
+ // adds the instruction to the bytecode of the method
+ code.put12(Opcodes.INVOKEDYNAMIC, i.index);
+ code.putShort(0);
+ }
+
+ @Override
public void visitJumpInsn(final int opcode, final Label label) {
+ lastCodeOffset = code.length;
Label nextInsn = null;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -894,8 +1018,7 @@ public void visitJumpInsn(final int opcode, final Label label) {
}
// adds the instruction to the bytecode of the method
if ((label.status & Label.RESOLVED) != 0
- && label.position - code.length < Short.MIN_VALUE)
- {
+ && label.position - code.length < Short.MIN_VALUE) {
/*
* case of a backward jump with an offset < -32768. In this case we
* automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
@@ -913,8 +1036,7 @@ public void visitJumpInsn(final int opcode, final Label label) {
if (nextInsn != null) {
nextInsn.status |= Label.TARGET;
}
- code.putByte(opcode <= 166
- ? ((opcode + 1) ^ 1) - 1
+ code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
: opcode ^ 1);
code.putShort(8); // jump offset
code.putByte(200); // GOTO_W
@@ -944,6 +1066,7 @@ public void visitJumpInsn(final int opcode, final Label label) {
}
}
+ @Override
public void visitLabel(final Label label) {
// resolves previous forward references to label, if any
resize |= label.resolve(this, code.length, code.data);
@@ -998,7 +1121,9 @@ public void visitLabel(final Label label) {
}
}
+ @Override
public void visitLdcInsn(final Object cst) {
+ lastCodeOffset = code.length;
Item i = cw.newConstItem(cst);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -1007,8 +1132,7 @@ public void visitLdcInsn(final Object cst) {
} else {
int size;
// computes the stack size variation
- if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE)
- {
+ if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
size = stackSize + 2;
} else {
size = stackSize + 1;
@@ -1031,7 +1155,9 @@ public void visitLdcInsn(final Object cst) {
}
}
+ @Override
public void visitIincInsn(final int var, final int increment) {
+ lastCodeOffset = code.length;
if (currentBlock != null) {
if (compute == FRAMES) {
currentBlock.frame.execute(Opcodes.IINC, var, null, null);
@@ -1046,24 +1172,21 @@ public void visitIincInsn(final int var, final int increment) {
}
// adds the instruction to the bytecode of the method
if ((var > 255) || (increment > 127) || (increment < -128)) {
- code.putByte(196 /* WIDE */)
- .put12(Opcodes.IINC, var)
+ code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var)
.putShort(increment);
} else {
code.putByte(Opcodes.IINC).put11(var, increment);
}
}
- public void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label[] labels)
- {
+ @Override
+ public void visitTableSwitchInsn(final int min, final int max,
+ final Label dflt, final Label... labels) {
+ lastCodeOffset = code.length;
// adds the instruction to the bytecode of the method
int source = code.length;
code.putByte(Opcodes.TABLESWITCH);
- code.length += (4 - code.length % 4) % 4;
+ code.putByteArray(null, 0, (4 - code.length % 4) % 4);
dflt.put(this, code, source, true);
code.putInt(min).putInt(max);
for (int i = 0; i < labels.length; ++i) {
@@ -1073,15 +1196,14 @@ public void visitTableSwitchInsn(
visitSwitchInsn(dflt, labels);
}
- public void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels)
- {
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+ final Label[] labels) {
+ lastCodeOffset = code.length;
// adds the instruction to the bytecode of the method
int source = code.length;
code.putByte(Opcodes.LOOKUPSWITCH);
- code.length += (4 - code.length % 4) % 4;
+ code.putByteArray(null, 0, (4 - code.length % 4) % 4);
dflt.put(this, code, source, true);
code.putInt(labels.length);
for (int i = 0; i < labels.length; ++i) {
@@ -1118,7 +1240,9 @@ private void visitSwitchInsn(final Label dflt, final Label[] labels) {
}
}
+ @Override
public void visitMultiANewArrayInsn(final String desc, final int dims) {
+ lastCodeOffset = code.length;
Item i = cw.newClassItem(desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -1134,12 +1258,33 @@ public void visitMultiANewArrayInsn(final String desc, final int dims) {
code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims);
}
- public void visitTryCatchBlock(
- final Label start,
- final Label end,
- final Label handler,
- final String type)
- {
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = ctanns;
+ ctanns = aw;
+ } else {
+ aw.next = ictanns;
+ ictanns = aw;
+ }
+ return aw;
+ }
+
+ @Override
+ public void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type) {
++handlerCount;
Handler h = new Handler();
h.start = start;
@@ -1155,14 +1300,33 @@ public void visitTryCatchBlock(
lastHandler = h;
}
- public void visitLocalVariable(
- final String name,
- final String desc,
- final String signature,
- final Label start,
- final Label end,
- final int index)
- {
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = ctanns;
+ ctanns = aw;
+ } else {
+ aw.next = ictanns;
+ ictanns = aw;
+ }
+ return aw;
+ }
+
+ @Override
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
if (signature != null) {
if (localVarType == null) {
localVarType = new ByteVector();
@@ -1170,8 +1334,7 @@ public void visitLocalVariable(
++localVarTypeCount;
localVarType.putShort(start.position)
.putShort(end.position - start.position)
- .putShort(cw.newUTF8(name))
- .putShort(cw.newUTF8(signature))
+ .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(signature))
.putShort(index);
}
if (localVar == null) {
@@ -1180,8 +1343,7 @@ public void visitLocalVariable(
++localVarCount;
localVar.putShort(start.position)
.putShort(end.position - start.position)
- .putShort(cw.newUTF8(name))
- .putShort(cw.newUTF8(desc))
+ .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(desc))
.putShort(index);
if (compute != NOTHING) {
// updates max locals
@@ -1193,6 +1355,42 @@ public void visitLocalVariable(
}
}
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+ TypePath typePath, Label[] start, Label[] end, int[] index,
+ String desc, boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ bv.putByte(typeRef >>> 24).putShort(start.length);
+ for (int i = 0; i < start.length; ++i) {
+ bv.putShort(start[i].position)
+ .putShort(end[i].position - start[i].position)
+ .putShort(index[i]);
+ }
+ if (typePath == null) {
+ bv.putByte(0);
+ } else {
+ int length = typePath.b[typePath.offset] * 2 + 1;
+ bv.putByteArray(typePath.b, typePath.offset, length);
+ }
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = ctanns;
+ ctanns = aw;
+ } else {
+ aw.next = ictanns;
+ ictanns = aw;
+ }
+ return aw;
+ }
+
+ @Override
public void visitLineNumber(final int line, final Label start) {
if (lineNumber == null) {
lineNumber = new ByteVector();
@@ -1202,6 +1400,7 @@ public void visitLineNumber(final int line, final Label start) {
lineNumber.putShort(line);
}
+ @Override
public void visitMaxs(final int maxStack, final int maxLocals) {
if (ClassReader.FRAMES && compute == FRAMES) {
// completes the control flow graph with exception handler blocks
@@ -1211,8 +1410,7 @@ public void visitMaxs(final int maxStack, final int maxLocals) {
Label h = handler.handler.getFirst();
Label e = handler.end.getFirst();
// computes the kind of the edges to 'h'
- String t = handler.desc == null
- ? "java/lang/Throwable"
+ String t = handler.desc == null ? "java/lang/Throwable"
: handler.desc;
int kind = Frame.OBJECT | cw.addType(t);
// h is an exception handler
@@ -1252,11 +1450,11 @@ public void visitMaxs(final int maxStack, final int maxLocals) {
changed = changed.next;
l.next = null;
f = l.frame;
- // a reacheable jump target must be stored in the stack map
+ // a reachable jump target must be stored in the stack map
if ((l.status & Label.TARGET) != 0) {
l.status |= Label.STORE;
}
- // all visited labels are reacheable, by definition
+ // all visited labels are reachable, by definition
l.status |= Label.REACHABLE;
// updates the (absolute) maximum stack size
int blockMax = f.inputStack.length + l.outputStackMax;
@@ -1277,7 +1475,6 @@ public void visitMaxs(final int maxStack, final int maxLocals) {
e = e.next;
}
}
- this.maxStack = max;
// visits all the frames that must be stored in the stack map
Label l = labels;
@@ -1293,20 +1490,33 @@ public void visitMaxs(final int maxStack, final int maxLocals) {
int end = (k == null ? code.length : k.position) - 1;
// if non empty basic block
if (end >= start) {
+ max = Math.max(max, 1);
// replaces instructions with NOP ... NOP ATHROW
for (int i = start; i < end; ++i) {
code.data[i] = Opcodes.NOP;
}
code.data[end] = (byte) Opcodes.ATHROW;
// emits a frame for this unreachable block
- startFrame(start, 0, 1);
- frame[frameIndex++] = Frame.OBJECT
+ int frameIndex = startFrame(start, 0, 1);
+ frame[frameIndex] = Frame.OBJECT
| cw.addType("java/lang/Throwable");
endFrame();
+ // removes the start-end range from the exception
+ // handlers
+ firstHandler = Handler.remove(firstHandler, l, k);
}
}
l = l.successor;
}
+
+ handler = firstHandler;
+ handlerCount = 0;
+ while (handler != null) {
+ handlerCount += 1;
+ handler = handler.next;
+ }
+
+ this.maxStack = max;
} else if (compute == MAXS) {
// completes the control flow graph with exception handler blocks
Handler handler = firstHandler;
@@ -1368,7 +1578,7 @@ public void visitMaxs(final int maxStack, final int maxLocals) {
if ((l.status & Label.JSR) != 0) {
Label L = labels;
while (L != null) {
- L.status &= ~Label.VISITED;
+ L.status &= ~Label.VISITED2;
L = L.successor;
}
// the subroutine is defined by l's TARGET, not by l
@@ -1423,13 +1633,14 @@ public void visitMaxs(final int maxStack, final int maxLocals) {
b = b.next;
}
}
- this.maxStack = max;
+ this.maxStack = Math.max(maxStack, max);
} else {
this.maxStack = maxStack;
this.maxLocals = maxLocals;
}
}
+ @Override
public void visitEnd() {
}
@@ -1437,49 +1648,13 @@ public void visitEnd() {
// Utility methods: control flow analysis algorithm
// ------------------------------------------------------------------------
- /**
- * Computes the size of the arguments and of the return value of a method.
- *
- * @param desc the descriptor of a method.
- * @return the size of the arguments of the method (plus one for the
- * implicit this argument), argSize, and the size of its return
- * value, retSize, packed into a single int i =
- * (argSize << 2) | retSize (argSize is therefore equal
- * to i >> 2, and retSize to i & 0x03).
- */
- static int getArgumentsAndReturnSizes(final String desc) {
- int n = 1;
- int c = 1;
- while (true) {
- char car = desc.charAt(c++);
- if (car == ')') {
- car = desc.charAt(c);
- return n << 2
- | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
- } else if (car == 'L') {
- while (desc.charAt(c++) != ';') {
- }
- n += 1;
- } else if (car == '[') {
- while ((car = desc.charAt(c)) == '[') {
- ++c;
- }
- if (car == 'D' || car == 'J') {
- n -= 1;
- }
- } else if (car == 'D' || car == 'J') {
- n += 2;
- } else {
- n += 1;
- }
- }
- }
-
/**
* Adds a successor to the {@link #currentBlock currentBlock} block.
- *
- * @param info information about the control flow edge to be added.
- * @param successor the successor block to be added to the current block.
+ *
+ * @param info
+ * information about the control flow edge to be added.
+ * @param successor
+ * the successor block to be added to the current block.
*/
private void addSuccessor(final int info, final Label successor) {
// creates and initializes an Edge object...
@@ -1515,8 +1690,9 @@ private void noSuccessor() {
/**
* Visits a frame that has been computed from scratch.
- *
- * @param f the frame that must be visited.
+ *
+ * @param f
+ * the frame that must be visited.
*/
private void visitFrame(final Frame f) {
int i, t;
@@ -1549,7 +1725,7 @@ private void visitFrame(final Frame f) {
}
}
// visits the frame and its content
- startFrame(f.owner.position, nLocal, nStack);
+ int frameIndex = startFrame(f.owner.position, nLocal, nStack);
for (i = 0; nLocal > 0; ++i, --nLocal) {
t = locals[i];
frame[frameIndex++] = t;
@@ -1567,16 +1743,79 @@ private void visitFrame(final Frame f) {
endFrame();
}
+ /**
+ * Visit the implicit first frame of this method.
+ */
+ private void visitImplicitFirstFrame() {
+ // There can be at most descriptor.length() + 1 locals
+ int frameIndex = startFrame(0, descriptor.length() + 1, 0);
+ if ((access & Opcodes.ACC_STATIC) == 0) {
+ if ((access & ACC_CONSTRUCTOR) == 0) {
+ frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
+ } else {
+ frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
+ }
+ }
+ int i = 1;
+ loop: while (true) {
+ int j = i;
+ switch (descriptor.charAt(i++)) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ frame[frameIndex++] = 1; // Opcodes.INTEGER;
+ break;
+ case 'F':
+ frame[frameIndex++] = 2; // Opcodes.FLOAT;
+ break;
+ case 'J':
+ frame[frameIndex++] = 4; // Opcodes.LONG;
+ break;
+ case 'D':
+ frame[frameIndex++] = 3; // Opcodes.DOUBLE;
+ break;
+ case '[':
+ while (descriptor.charAt(i) == '[') {
+ ++i;
+ }
+ if (descriptor.charAt(i) == 'L') {
+ ++i;
+ while (descriptor.charAt(i) != ';') {
+ ++i;
+ }
+ }
+ frame[frameIndex++] = Frame.OBJECT
+ | cw.addType(descriptor.substring(j, ++i));
+ break;
+ case 'L':
+ while (descriptor.charAt(i) != ';') {
+ ++i;
+ }
+ frame[frameIndex++] = Frame.OBJECT
+ | cw.addType(descriptor.substring(j + 1, i++));
+ break;
+ default:
+ break loop;
+ }
+ }
+ frame[1] = frameIndex - 3;
+ endFrame();
+ }
+
/**
* Starts the visit of a stack map frame.
- *
- * @param offset the offset of the instruction to which the frame
- * corresponds.
- * @param nLocal the number of local variables in the frame.
- * @param nStack the number of stack elements in the frame.
- */
- private void startFrame(final int offset, final int nLocal, final int nStack)
- {
+ *
+ * @param offset
+ * the offset of the instruction to which the frame corresponds.
+ * @param nLocal
+ * the number of local variables in the frame.
+ * @param nStack
+ * the number of stack elements in the frame.
+ * @return the index of the next element to be written in this frame.
+ */
+ private int startFrame(final int offset, final int nLocal, final int nStack) {
int n = 3 + nLocal + nStack;
if (frame == null || frame.length < n) {
frame = new int[n];
@@ -1584,7 +1823,7 @@ private void startFrame(final int offset, final int nLocal, final int nStack)
frame[0] = offset;
frame[1] = nLocal;
frame[2] = nStack;
- frameIndex = 3;
+ return 3;
}
/**
@@ -1629,24 +1868,23 @@ private void writeFrame() {
if (cstackSize == 0) {
k = clocalsSize - localsSize;
switch (k) {
- case -3:
- case -2:
- case -1:
- type = CHOP_FRAME;
- localsSize = clocalsSize;
- break;
- case 0:
- type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
- break;
- case 1:
- case 2:
- case 3:
- type = APPEND_FRAME;
- break;
+ case -3:
+ case -2:
+ case -1:
+ type = CHOP_FRAME;
+ localsSize = clocalsSize;
+ break;
+ case 0:
+ type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ type = APPEND_FRAME;
+ break;
}
} else if (clocalsSize == localsSize && cstackSize == 1) {
- type = delta < 63
- ? SAME_LOCALS_1_STACK_ITEM_FRAME
+ type = delta < 63 ? SAME_LOCALS_1_STACK_ITEM_FRAME
: SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
}
if (type != FULL_FRAME) {
@@ -1661,36 +1899,34 @@ private void writeFrame() {
}
}
switch (type) {
- case SAME_FRAME:
- stackMap.putByte(delta);
- break;
- case SAME_LOCALS_1_STACK_ITEM_FRAME:
- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
- writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
- break;
- case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
- .putShort(delta);
- writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
- break;
- case SAME_FRAME_EXTENDED:
- stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
- break;
- case CHOP_FRAME:
- stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
- break;
- case APPEND_FRAME:
- stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
- writeFrameTypes(3 + localsSize, 3 + clocalsSize);
- break;
- // case FULL_FRAME:
- default:
- stackMap.putByte(FULL_FRAME)
- .putShort(delta)
- .putShort(clocalsSize);
- writeFrameTypes(3, 3 + clocalsSize);
- stackMap.putShort(cstackSize);
- writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
+ case SAME_FRAME:
+ stackMap.putByte(delta);
+ break;
+ case SAME_LOCALS_1_STACK_ITEM_FRAME:
+ stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+ writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+ break;
+ case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
+ stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED).putShort(
+ delta);
+ writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+ break;
+ case SAME_FRAME_EXTENDED:
+ stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+ break;
+ case CHOP_FRAME:
+ stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+ break;
+ case APPEND_FRAME:
+ stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+ writeFrameTypes(3 + localsSize, 3 + clocalsSize);
+ break;
+ // case FULL_FRAME:
+ default:
+ stackMap.putByte(FULL_FRAME).putShort(delta).putShort(clocalsSize);
+ writeFrameTypes(3, 3 + clocalsSize);
+ stackMap.putShort(cstackSize);
+ writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
}
}
@@ -1699,9 +1935,11 @@ private void writeFrame() {
* StackMapTableAttribute. This method converts types from the format used
* in {@link Label} to the format used in StackMapTable attributes. In
* particular, it converts type table indexes to constant pool indexes.
- *
- * @param start index of the first type in {@link #frame} to write.
- * @param end index of last type in {@link #frame} to write (exclusive).
+ *
+ * @param start
+ * index of the first type in {@link #frame} to write.
+ * @param end
+ * index of last type in {@link #frame} to write (exclusive).
*/
private void writeFrameTypes(final int start, final int end) {
for (int i = start; i < end; ++i) {
@@ -1710,15 +1948,15 @@ private void writeFrameTypes(final int start, final int end) {
if (d == 0) {
int v = t & Frame.BASE_VALUE;
switch (t & Frame.BASE_KIND) {
- case Frame.OBJECT:
- stackMap.putByte(7)
- .putShort(cw.newClass(cw.typeTable[v].strVal1));
- break;
- case Frame.UNINITIALIZED:
- stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
- break;
- default:
- stackMap.putByte(v);
+ case Frame.OBJECT:
+ stackMap.putByte(7).putShort(
+ cw.newClass(cw.typeTable[v].strVal1));
+ break;
+ case Frame.UNINITIALIZED:
+ stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
+ break;
+ default:
+ stackMap.putByte(v);
}
} else {
StringBuffer buf = new StringBuffer();
@@ -1732,29 +1970,29 @@ private void writeFrameTypes(final int start, final int end) {
buf.append(';');
} else {
switch (t & 0xF) {
- case 1:
- buf.append('I');
- break;
- case 2:
- buf.append('F');
- break;
- case 3:
- buf.append('D');
- break;
- case 9:
- buf.append('Z');
- break;
- case 10:
- buf.append('B');
- break;
- case 11:
- buf.append('C');
- break;
- case 12:
- buf.append('S');
- break;
- default:
- buf.append('J');
+ case 1:
+ buf.append('I');
+ break;
+ case 2:
+ buf.append('F');
+ break;
+ case 3:
+ buf.append('D');
+ break;
+ case 9:
+ buf.append('Z');
+ break;
+ case 10:
+ buf.append('B');
+ break;
+ case 11:
+ buf.append('C');
+ break;
+ case 12:
+ buf.append('S');
+ break;
+ default:
+ buf.append('J');
}
}
stackMap.putByte(7).putShort(cw.newClass(buf.toString()));
@@ -1778,7 +2016,7 @@ private void writeFrameType(final Object type) {
/**
* Returns the size of the bytecode of this method.
- *
+ *
* @return the size of the bytecode of this method.
*/
final int getSize() {
@@ -1795,6 +2033,9 @@ final int getSize() {
}
int size = 8;
if (code.length > 0) {
+ if (code.length > 65536) {
+ throw new RuntimeException("Method code too large!");
+ }
cw.newUTF8("Code");
size += 18 + code.length + 8 * handlerCount;
if (localVar != null) {
@@ -1814,11 +2055,16 @@ final int getSize() {
cw.newUTF8(zip ? "StackMapTable" : "StackMap");
size += 8 + stackMap.length;
}
+ if (ClassReader.ANNOTATIONS && ctanns != null) {
+ cw.newUTF8("RuntimeVisibleTypeAnnotations");
+ size += 8 + ctanns.getSize();
+ }
+ if (ClassReader.ANNOTATIONS && ictanns != null) {
+ cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+ size += 8 + ictanns.getSize();
+ }
if (cattrs != null) {
- size += cattrs.getSize(cw,
- code.data,
- code.length,
- maxStack,
+ size += cattrs.getSize(cw, code.data, code.length, maxStack,
maxLocals);
}
}
@@ -1826,11 +2072,12 @@ final int getSize() {
cw.newUTF8("Exceptions");
size += 8 + 2 * exceptionCount;
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && (cw.version & 0xffff) < Opcodes.V1_5)
- {
- cw.newUTF8("Synthetic");
- size += 6;
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ cw.newUTF8("Synthetic");
+ size += 6;
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cw.newUTF8("Deprecated");
@@ -1841,6 +2088,10 @@ final int getSize() {
cw.newUTF8(signature);
size += 8;
}
+ if (methodParameters != null) {
+ cw.newUTF8("MethodParameters");
+ size += 7 + methodParameters.length;
+ }
if (ClassReader.ANNOTATIONS && annd != null) {
cw.newUTF8("AnnotationDefault");
size += 6 + annd.length;
@@ -1853,6 +2104,14 @@ final int getSize() {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ cw.newUTF8("RuntimeVisibleTypeAnnotations");
+ size += 8 + tanns.getSize();
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+ size += 8 + itanns.getSize();
+ }
if (ClassReader.ANNOTATIONS && panns != null) {
cw.newUTF8("RuntimeVisibleParameterAnnotations");
size += 7 + 2 * (panns.length - synthetics);
@@ -1875,12 +2134,17 @@ final int getSize() {
/**
* Puts the bytecode of this method in the given byte vector.
- *
- * @param out the byte vector into which the bytecode of this method must be
- * copied.
+ *
+ * @param out
+ * the byte vector into which the bytecode of this method must be
+ * copied.
*/
final void put(final ByteVector out) {
- out.putShort(access).putShort(name).putShort(desc);
+ final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+ int mask = ACC_CONSTRUCTOR | Opcodes.ACC_DEPRECATED
+ | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+ | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
+ out.putShort(access & ~mask).putShort(name).putShort(desc);
if (classReaderOffset != 0) {
out.putByteArray(cw.cr.b, classReaderOffset, classReaderLength);
return;
@@ -1892,10 +2156,11 @@ final void put(final ByteVector out) {
if (exceptionCount > 0) {
++attributeCount;
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && (cw.version & 0xffff) < Opcodes.V1_5)
- {
- ++attributeCount;
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ ++attributeCount;
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
@@ -1903,6 +2168,9 @@ final void put(final ByteVector out) {
if (ClassReader.SIGNATURES && signature != null) {
++attributeCount;
}
+ if (methodParameters != null) {
+ ++attributeCount;
+ }
if (ClassReader.ANNOTATIONS && annd != null) {
++attributeCount;
}
@@ -1912,6 +2180,12 @@ final void put(final ByteVector out) {
if (ClassReader.ANNOTATIONS && ianns != null) {
++attributeCount;
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ ++attributeCount;
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ ++attributeCount;
+ }
if (ClassReader.ANNOTATIONS && panns != null) {
++attributeCount;
}
@@ -1936,11 +2210,14 @@ final void put(final ByteVector out) {
if (stackMap != null) {
size += 8 + stackMap.length;
}
+ if (ClassReader.ANNOTATIONS && ctanns != null) {
+ size += 8 + ctanns.getSize();
+ }
+ if (ClassReader.ANNOTATIONS && ictanns != null) {
+ size += 8 + ictanns.getSize();
+ }
if (cattrs != null) {
- size += cattrs.getSize(cw,
- code.data,
- code.length,
- maxStack,
+ size += cattrs.getSize(cw, code.data, code.length, maxStack,
maxLocals);
}
out.putShort(cw.newUTF8("Code")).putInt(size);
@@ -1950,10 +2227,8 @@ final void put(final ByteVector out) {
if (handlerCount > 0) {
Handler h = firstHandler;
while (h != null) {
- out.putShort(h.start.position)
- .putShort(h.end.position)
- .putShort(h.handler.position)
- .putShort(h.type);
+ out.putShort(h.start.position).putShort(h.end.position)
+ .putShort(h.handler.position).putShort(h.type);
h = h.next;
}
}
@@ -1970,6 +2245,12 @@ final void put(final ByteVector out) {
if (stackMap != null) {
++attributeCount;
}
+ if (ClassReader.ANNOTATIONS && ctanns != null) {
+ ++attributeCount;
+ }
+ if (ClassReader.ANNOTATIONS && ictanns != null) {
+ ++attributeCount;
+ }
if (cattrs != null) {
attributeCount += cattrs.getCount();
}
@@ -1995,31 +2276,45 @@ final void put(final ByteVector out) {
out.putInt(stackMap.length + 2).putShort(frameCount);
out.putByteArray(stackMap.data, 0, stackMap.length);
}
+ if (ClassReader.ANNOTATIONS && ctanns != null) {
+ out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+ ctanns.put(out);
+ }
+ if (ClassReader.ANNOTATIONS && ictanns != null) {
+ out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+ ictanns.put(out);
+ }
if (cattrs != null) {
cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out);
}
}
if (exceptionCount > 0) {
- out.putShort(cw.newUTF8("Exceptions"))
- .putInt(2 * exceptionCount + 2);
+ out.putShort(cw.newUTF8("Exceptions")).putInt(
+ 2 * exceptionCount + 2);
out.putShort(exceptionCount);
for (int i = 0; i < exceptionCount; ++i) {
out.putShort(exceptions[i]);
}
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && (cw.version & 0xffff) < Opcodes.V1_5)
- {
- out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
}
if (ClassReader.SIGNATURES && signature != null) {
- out.putShort(cw.newUTF8("Signature"))
- .putInt(2)
+ out.putShort(cw.newUTF8("Signature")).putInt(2)
.putShort(cw.newUTF8(signature));
}
+ if (methodParameters != null) {
+ out.putShort(cw.newUTF8("MethodParameters"));
+ out.putInt(methodParameters.length + 1).putByte(
+ methodParametersCount);
+ out.putByteArray(methodParameters.data, 0, methodParameters.length);
+ }
if (ClassReader.ANNOTATIONS && annd != null) {
out.putShort(cw.newUTF8("AnnotationDefault"));
out.putInt(annd.length);
@@ -2033,6 +2328,14 @@ final void put(final ByteVector out) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+ tanns.put(out);
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+ itanns.put(out);
+ }
if (ClassReader.ANNOTATIONS && panns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
AnnotationWriter.put(panns, synthetics, out);
@@ -2060,10 +2363,12 @@ final void put(final ByteVector out) {
* 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
* 32765. This, in turn, may require to increase the size of another jump
* instruction, and so on... All these operations are handled automatically
- * by this method.
This method must be called after all the method
- * that is being built has been visited. In particular, the
- * {@link Label Label} objects used to construct the method are no longer
- * valid after this method has been called.
+ * by this method.
+ *
+ * This method must be called after all the method that is being built
+ * has been visited. In particular, the {@link Label Label} objects used
+ * to construct the method are no longer valid after this method has been
+ * called.
*/
private void resizeInstructions() {
byte[] b = code.data; // bytecode of the method
@@ -2075,17 +2380,17 @@ private void resizeInstructions() {
* so on. The first step of the algorithm consists in finding all the
* instructions that need to be resized, without modifying the code.
* This is done by the following "fix point" algorithm:
- *
+ *
* Parse the code to find the jump instructions whose offset will need
* more than 2 bytes to be stored (the future offset is computed from
* the current offset and from the number of bytes that will be inserted
* or removed between the source and target instructions). For each such
* instruction, adds an entry in (a copy of) the indexes and sizes
* arrays (if this has not already been done in a previous iteration!).
- *
+ *
* If at least one entry has been added during the previous step, go
* back to the beginning, otherwise stop.
- *
+ *
* In fact the real algorithm is complicated by the fact that the size
* of TABLESWITCH and LOOKUPSWITCH instructions depends on their
* position in the bytecode (because of padding). In order to ensure the
@@ -2113,157 +2418,14 @@ private void resizeInstructions() {
int insert = 0; // bytes to be added after this instruction
switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- u += 1;
- break;
- case ClassWriter.LABEL_INSN:
- if (opcode > 201) {
- // converts temporary opcodes 202 to 217, 218 and
- // 219 to IFEQ ... JSR (inclusive), IFNULL and
- // IFNONNULL
- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
- label = u + readUnsignedShort(b, u + 1);
- } else {
- label = u + readShort(b, u + 1);
- }
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (newOffset < Short.MIN_VALUE
- || newOffset > Short.MAX_VALUE)
- {
- if (!resize[u]) {
- if (opcode == Opcodes.GOTO
- || opcode == Opcodes.JSR)
- {
- // two additional bytes will be required to
- // replace this GOTO or JSR instruction with
- // a GOTO_W or a JSR_W
- insert = 2;
- } else {
- // five additional bytes will be required to
- // replace this IFxxx instruction with
- // IFNOTxxx GOTO_W , where IFNOTxxx
- // is the "opposite" opcode of IFxxx (i.e.,
- // IFNE for IFEQ) and where designates
- // the instruction just after the GOTO_W.
- insert = 5;
- }
- resize[u] = true;
- }
- }
- u += 3;
- break;
- case ClassWriter.LABELW_INSN:
- u += 5;
- break;
- case ClassWriter.TABL_INSN:
- if (state == 1) {
- // true number of bytes to be added (or removed)
- // from this instruction = (future number of padding
- // bytes - current number of padding byte) -
- // previously over estimated variation =
- // = ((3 - newOffset%4) - (3 - u%4)) - u%4
- // = (-newOffset%4 + u%4) - u%4
- // = -(newOffset & 3)
- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
- insert = -(newOffset & 3);
- } else if (!resize[u]) {
- // over estimation of the number of bytes to be
- // added to this instruction = 3 - current number
- // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
- insert = u & 3;
- resize[u] = true;
- }
- // skips instruction
- u = u + 4 - (u & 3);
- u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
- break;
- case ClassWriter.LOOK_INSN:
- if (state == 1) {
- // like TABL_INSN
- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
- insert = -(newOffset & 3);
- } else if (!resize[u]) {
- // like TABL_INSN
- insert = u & 3;
- resize[u] = true;
- }
- // skips instruction
- u = u + 4 - (u & 3);
- u += 8 * readInt(b, u + 4) + 8;
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[u + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- u += 6;
- } else {
- u += 4;
- }
- break;
- case ClassWriter.VAR_INSN:
- case ClassWriter.SBYTE_INSN:
- case ClassWriter.LDC_INSN:
- u += 2;
- break;
- case ClassWriter.SHORT_INSN:
- case ClassWriter.LDCW_INSN:
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.TYPE_INSN:
- case ClassWriter.IINC_INSN:
- u += 3;
- break;
- case ClassWriter.ITFMETH_INSN:
- u += 5;
- break;
- // case ClassWriter.MANA_INSN:
- default:
- u += 4;
- break;
- }
- if (insert != 0) {
- // adds a new (u, insert) entry in the allIndexes and
- // allSizes arrays
- int[] newIndexes = new int[allIndexes.length + 1];
- int[] newSizes = new int[allSizes.length + 1];
- System.arraycopy(allIndexes,
- 0,
- newIndexes,
- 0,
- allIndexes.length);
- System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
- newIndexes[allIndexes.length] = u;
- newSizes[allSizes.length] = insert;
- allIndexes = newIndexes;
- allSizes = newSizes;
- if (insert > 0) {
- state = 3;
- }
- }
- }
- if (state < 3) {
- --state;
- }
- } while (state != 0);
-
- // 2nd step:
- // copies the bytecode of the method into a new bytevector, updates the
- // offsets, and inserts (or removes) bytes as requested.
-
- ByteVector newCode = new ByteVector(code.length);
-
- u = 0;
- while (u < code.length) {
- int opcode = b[u] & 0xFF;
- switch (ClassWriter.TYPE[opcode]) {
case ClassWriter.NOARG_INSN:
case ClassWriter.IMPLVAR_INSN:
- newCode.putByte(opcode);
u += 1;
break;
case ClassWriter.LABEL_INSN:
if (opcode > 201) {
- // changes temporary opcodes 202 to 217 (inclusive), 218
- // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+ // converts temporary opcodes 202 to 217, 218 and
+ // 219 to IFEQ ... JSR (inclusive), IFNULL and
// IFNONNULL
opcode = opcode < 218 ? opcode - 49 : opcode - 20;
label = u + readUnsignedShort(b, u + 1);
@@ -2271,100 +2433,78 @@ private void resizeInstructions() {
label = u + readShort(b, u + 1);
}
newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (resize[u]) {
- // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
- // with IFNOTxxx GOTO_W , where IFNOTxxx is
- // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
- // and where designates the instruction just after
- // the GOTO_W.
- if (opcode == Opcodes.GOTO) {
- newCode.putByte(200); // GOTO_W
- } else if (opcode == Opcodes.JSR) {
- newCode.putByte(201); // JSR_W
- } else {
- newCode.putByte(opcode <= 166
- ? ((opcode + 1) ^ 1) - 1
- : opcode ^ 1);
- newCode.putShort(8); // jump offset
- newCode.putByte(200); // GOTO_W
- // newOffset now computed from start of GOTO_W
- newOffset -= 3;
+ if (newOffset < Short.MIN_VALUE
+ || newOffset > Short.MAX_VALUE) {
+ if (!resize[u]) {
+ if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+ // two additional bytes will be required to
+ // replace this GOTO or JSR instruction with
+ // a GOTO_W or a JSR_W
+ insert = 2;
+ } else {
+ // five additional bytes will be required to
+ // replace this IFxxx instruction with
+ // IFNOTxxx GOTO_W , where IFNOTxxx
+ // is the "opposite" opcode of IFxxx (i.e.,
+ // IFNE for IFEQ) and where designates
+ // the instruction just after the GOTO_W.
+ insert = 5;
+ }
+ resize[u] = true;
}
- newCode.putInt(newOffset);
- } else {
- newCode.putByte(opcode);
- newCode.putShort(newOffset);
}
u += 3;
break;
case ClassWriter.LABELW_INSN:
- label = u + readInt(b, u + 1);
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- newCode.putByte(opcode);
- newCode.putInt(newOffset);
u += 5;
break;
case ClassWriter.TABL_INSN:
- // skips 0 to 3 padding bytes
- v = u;
- u = u + 4 - (v & 3);
- // reads and copies instruction
- newCode.putByte(Opcodes.TABLESWITCH);
- newCode.length += (4 - newCode.length % 4) % 4;
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- j = readInt(b, u);
- u += 4;
- newCode.putInt(j);
- j = readInt(b, u) - j + 1;
- u += 4;
- newCode.putInt(readInt(b, u - 4));
- for (; j > 0; --j) {
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
+ if (state == 1) {
+ // true number of bytes to be added (or removed)
+ // from this instruction = (future number of padding
+ // bytes - current number of padding byte) -
+ // previously over estimated variation =
+ // = ((3 - newOffset%4) - (3 - u%4)) - u%4
+ // = (-newOffset%4 + u%4) - u%4
+ // = -(newOffset & 3)
+ newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+ insert = -(newOffset & 3);
+ } else if (!resize[u]) {
+ // over estimation of the number of bytes to be
+ // added to this instruction = 3 - current number
+ // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
+ insert = u & 3;
+ resize[u] = true;
}
+ // skips instruction
+ u = u + 4 - (u & 3);
+ u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
break;
case ClassWriter.LOOK_INSN:
- // skips 0 to 3 padding bytes
- v = u;
- u = u + 4 - (v & 3);
- // reads and copies instruction
- newCode.putByte(Opcodes.LOOKUPSWITCH);
- newCode.length += (4 - newCode.length % 4) % 4;
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- j = readInt(b, u);
- u += 4;
- newCode.putInt(j);
- for (; j > 0; --j) {
- newCode.putInt(readInt(b, u));
- u += 4;
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
+ if (state == 1) {
+ // like TABL_INSN
+ newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+ insert = -(newOffset & 3);
+ } else if (!resize[u]) {
+ // like TABL_INSN
+ insert = u & 3;
+ resize[u] = true;
}
+ // skips instruction
+ u = u + 4 - (u & 3);
+ u += 8 * readInt(b, u + 4) + 8;
break;
case ClassWriter.WIDE_INSN:
opcode = b[u + 1] & 0xFF;
if (opcode == Opcodes.IINC) {
- newCode.putByteArray(b, u, 6);
u += 6;
} else {
- newCode.putByteArray(b, u, 4);
u += 4;
}
break;
case ClassWriter.VAR_INSN:
case ClassWriter.SBYTE_INSN:
case ClassWriter.LDC_INSN:
- newCode.putByteArray(b, u, 2);
u += 2;
break;
case ClassWriter.SHORT_INSN:
@@ -2372,18 +2512,178 @@ private void resizeInstructions() {
case ClassWriter.FIELDORMETH_INSN:
case ClassWriter.TYPE_INSN:
case ClassWriter.IINC_INSN:
- newCode.putByteArray(b, u, 3);
u += 3;
break;
case ClassWriter.ITFMETH_INSN:
- newCode.putByteArray(b, u, 5);
+ case ClassWriter.INDYMETH_INSN:
u += 5;
break;
- // case MANA_INSN:
+ // case ClassWriter.MANA_INSN:
default:
- newCode.putByteArray(b, u, 4);
u += 4;
break;
+ }
+ if (insert != 0) {
+ // adds a new (u, insert) entry in the allIndexes and
+ // allSizes arrays
+ int[] newIndexes = new int[allIndexes.length + 1];
+ int[] newSizes = new int[allSizes.length + 1];
+ System.arraycopy(allIndexes, 0, newIndexes, 0,
+ allIndexes.length);
+ System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
+ newIndexes[allIndexes.length] = u;
+ newSizes[allSizes.length] = insert;
+ allIndexes = newIndexes;
+ allSizes = newSizes;
+ if (insert > 0) {
+ state = 3;
+ }
+ }
+ }
+ if (state < 3) {
+ --state;
+ }
+ } while (state != 0);
+
+ // 2nd step:
+ // copies the bytecode of the method into a new bytevector, updates the
+ // offsets, and inserts (or removes) bytes as requested.
+
+ ByteVector newCode = new ByteVector(code.length);
+
+ u = 0;
+ while (u < code.length) {
+ int opcode = b[u] & 0xFF;
+ switch (ClassWriter.TYPE[opcode]) {
+ case ClassWriter.NOARG_INSN:
+ case ClassWriter.IMPLVAR_INSN:
+ newCode.putByte(opcode);
+ u += 1;
+ break;
+ case ClassWriter.LABEL_INSN:
+ if (opcode > 201) {
+ // changes temporary opcodes 202 to 217 (inclusive), 218
+ // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+ // IFNONNULL
+ opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+ label = u + readUnsignedShort(b, u + 1);
+ } else {
+ label = u + readShort(b, u + 1);
+ }
+ newOffset = getNewOffset(allIndexes, allSizes, u, label);
+ if (resize[u]) {
+ // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+ // with IFNOTxxx GOTO_W , where IFNOTxxx is
+ // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+ // and where designates the instruction just after
+ // the GOTO_W.
+ if (opcode == Opcodes.GOTO) {
+ newCode.putByte(200); // GOTO_W
+ } else if (opcode == Opcodes.JSR) {
+ newCode.putByte(201); // JSR_W
+ } else {
+ newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+ : opcode ^ 1);
+ newCode.putShort(8); // jump offset
+ newCode.putByte(200); // GOTO_W
+ // newOffset now computed from start of GOTO_W
+ newOffset -= 3;
+ }
+ newCode.putInt(newOffset);
+ } else {
+ newCode.putByte(opcode);
+ newCode.putShort(newOffset);
+ }
+ u += 3;
+ break;
+ case ClassWriter.LABELW_INSN:
+ label = u + readInt(b, u + 1);
+ newOffset = getNewOffset(allIndexes, allSizes, u, label);
+ newCode.putByte(opcode);
+ newCode.putInt(newOffset);
+ u += 5;
+ break;
+ case ClassWriter.TABL_INSN:
+ // skips 0 to 3 padding bytes
+ v = u;
+ u = u + 4 - (v & 3);
+ // reads and copies instruction
+ newCode.putByte(Opcodes.TABLESWITCH);
+ newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+ label = v + readInt(b, u);
+ u += 4;
+ newOffset = getNewOffset(allIndexes, allSizes, v, label);
+ newCode.putInt(newOffset);
+ j = readInt(b, u);
+ u += 4;
+ newCode.putInt(j);
+ j = readInt(b, u) - j + 1;
+ u += 4;
+ newCode.putInt(readInt(b, u - 4));
+ for (; j > 0; --j) {
+ label = v + readInt(b, u);
+ u += 4;
+ newOffset = getNewOffset(allIndexes, allSizes, v, label);
+ newCode.putInt(newOffset);
+ }
+ break;
+ case ClassWriter.LOOK_INSN:
+ // skips 0 to 3 padding bytes
+ v = u;
+ u = u + 4 - (v & 3);
+ // reads and copies instruction
+ newCode.putByte(Opcodes.LOOKUPSWITCH);
+ newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+ label = v + readInt(b, u);
+ u += 4;
+ newOffset = getNewOffset(allIndexes, allSizes, v, label);
+ newCode.putInt(newOffset);
+ j = readInt(b, u);
+ u += 4;
+ newCode.putInt(j);
+ for (; j > 0; --j) {
+ newCode.putInt(readInt(b, u));
+ u += 4;
+ label = v + readInt(b, u);
+ u += 4;
+ newOffset = getNewOffset(allIndexes, allSizes, v, label);
+ newCode.putInt(newOffset);
+ }
+ break;
+ case ClassWriter.WIDE_INSN:
+ opcode = b[u + 1] & 0xFF;
+ if (opcode == Opcodes.IINC) {
+ newCode.putByteArray(b, u, 6);
+ u += 6;
+ } else {
+ newCode.putByteArray(b, u, 4);
+ u += 4;
+ }
+ break;
+ case ClassWriter.VAR_INSN:
+ case ClassWriter.SBYTE_INSN:
+ case ClassWriter.LDC_INSN:
+ newCode.putByteArray(b, u, 2);
+ u += 2;
+ break;
+ case ClassWriter.SHORT_INSN:
+ case ClassWriter.LDCW_INSN:
+ case ClassWriter.FIELDORMETH_INSN:
+ case ClassWriter.TYPE_INSN:
+ case ClassWriter.IINC_INSN:
+ newCode.putByteArray(b, u, 3);
+ u += 3;
+ break;
+ case ClassWriter.ITFMETH_INSN:
+ case ClassWriter.INDYMETH_INSN:
+ newCode.putByteArray(b, u, 5);
+ u += 5;
+ break;
+ // case MANA_INSN:
+ default:
+ newCode.putByteArray(b, u, 4);
+ u += 4;
+ break;
}
}
@@ -2406,8 +2706,7 @@ private void resizeInstructions() {
* must therefore never have been called for this label.
*/
u = l.position - 3;
- if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u]))
- {
+ if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) {
getNewOffset(allIndexes, allSizes, l);
// TODO update offsets in UNINITIALIZED values
visitFrame(l.frame);
@@ -2463,10 +2762,11 @@ private void resizeInstructions() {
b = lineNumber.data;
u = 0;
while (u < lineNumber.length) {
- writeShort(b, u, getNewOffset(allIndexes,
- allSizes,
- 0,
- readUnsignedShort(b, u)));
+ writeShort(
+ b,
+ u,
+ getNewOffset(allIndexes, allSizes, 0,
+ readUnsignedShort(b, u)));
u += 4;
}
}
@@ -2488,9 +2788,11 @@ private void resizeInstructions() {
/**
* Reads an unsigned short value in the given byte array.
- *
- * @param b a byte array.
- * @param index the start index of the value to be read.
+ *
+ * @param b
+ * a byte array.
+ * @param index
+ * the start index of the value to be read.
* @return the read value.
*/
static int readUnsignedShort(final byte[] b, final int index) {
@@ -2499,9 +2801,11 @@ static int readUnsignedShort(final byte[] b, final int index) {
/**
* Reads a signed short value in the given byte array.
- *
- * @param b a byte array.
- * @param index the start index of the value to be read.
+ *
+ * @param b
+ * a byte array.
+ * @param index
+ * the start index of the value to be read.
* @return the read value.
*/
static short readShort(final byte[] b, final int index) {
@@ -2510,9 +2814,11 @@ static short readShort(final byte[] b, final int index) {
/**
* Reads a signed int value in the given byte array.
- *
- * @param b a byte array.
- * @param index the start index of the value to be read.
+ *
+ * @param b
+ * a byte array.
+ * @param index
+ * the start index of the value to be read.
* @return the read value.
*/
static int readInt(final byte[] b, final int index) {
@@ -2522,10 +2828,13 @@ static int readInt(final byte[] b, final int index) {
/**
* Writes a short value in the given byte array.
- *
- * @param b a byte array.
- * @param index where the first byte of the short value must be written.
- * @param s the value to be written in the given byte array.
+ *
+ * @param b
+ * a byte array.
+ * @param index
+ * where the first byte of the short value must be written.
+ * @param s
+ * the value to be written in the given byte array.
*/
static void writeShort(final byte[] b, final int index, final int s) {
b[index] = (byte) (s >>> 8);
@@ -2533,32 +2842,34 @@ static void writeShort(final byte[] b, final int index, final int s) {
}
/**
- * Computes the future value of a bytecode offset.
Note: it is possible
- * to have several entries for the same instruction in the indexes
- * and sizes: two entries (index=a,size=b) and (index=a,size=b')
- * are equivalent to a single entry (index=a,size=b+b').
- *
- * @param indexes current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its last
- * byte, plus one (or, in other words, by the index of the first
- * byte of the next instruction).
- * @param sizes the number of bytes to be added to the above
- * instructions. More precisely, for each i < len,
- * sizes[i] bytes will be added at the end of the
- * instruction designated by indexes[i] or, if
- * sizes[i] is negative, the last |sizes[i]|
- * bytes of the instruction will be removed (the instruction size
- * must not become negative or null).
- * @param begin index of the first byte of the source instruction.
- * @param end index of the first byte of the target instruction.
+ * Computes the future value of a bytecode offset.
+ *
+ * Note: it is possible to have several entries for the same instruction in
+ * the indexes and sizes: two entries (index=a,size=b) and
+ * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
+ *
+ * @param indexes
+ * current positions of the instructions to be resized. Each
+ * instruction must be designated by the index of its last
+ * byte, plus one (or, in other words, by the index of the
+ * first byte of the next instruction).
+ * @param sizes
+ * the number of bytes to be added to the above
+ * instructions. More precisely, for each i < len,
+ * sizes[i] bytes will be added at the end of the
+ * instruction designated by indexes[i] or, if
+ * sizes[i] is negative, the last |
+ * sizes[i]| bytes of the instruction will be removed
+ * (the instruction size must not become negative or
+ * null).
+ * @param begin
+ * index of the first byte of the source instruction.
+ * @param end
+ * index of the first byte of the target instruction.
* @return the future value of the given bytecode offset.
*/
- static int getNewOffset(
- final int[] indexes,
- final int[] sizes,
- final int begin,
- final int end)
- {
+ static int getNewOffset(final int[] indexes, final int[] sizes,
+ final int begin, final int end) {
int offset = end - begin;
for (int i = 0; i < indexes.length; ++i) {
if (begin < indexes[i] && indexes[i] <= end) {
@@ -2574,25 +2885,26 @@ static int getNewOffset(
/**
* Updates the offset of the given label.
- *
- * @param indexes current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its last
- * byte, plus one (or, in other words, by the index of the first
- * byte of the next instruction).
- * @param sizes the number of bytes to be added to the above
- * instructions. More precisely, for each i < len,
- * sizes[i] bytes will be added at the end of the
- * instruction designated by indexes[i] or, if
- * sizes[i] is negative, the last |sizes[i]|
- * bytes of the instruction will be removed (the instruction size
- * must not become negative or null).
- * @param label the label whose offset must be updated.
- */
- static void getNewOffset(
- final int[] indexes,
- final int[] sizes,
- final Label label)
- {
+ *
+ * @param indexes
+ * current positions of the instructions to be resized. Each
+ * instruction must be designated by the index of its last
+ * byte, plus one (or, in other words, by the index of the
+ * first byte of the next instruction).
+ * @param sizes
+ * the number of bytes to be added to the above
+ * instructions. More precisely, for each i < len,
+ * sizes[i] bytes will be added at the end of the
+ * instruction designated by indexes[i] or, if
+ * sizes[i] is negative, the last |
+ * sizes[i]| bytes of the instruction will be removed
+ * (the instruction size must not become negative or
+ * null).
+ * @param label
+ * the label whose offset must be updated.
+ */
+ static void getNewOffset(final int[] indexes, final int[] sizes,
+ final Label label) {
if ((label.status & Label.RESIZED) == 0) {
label.position = getNewOffset(indexes, sizes, 0, label.position);
label.status |= Label.RESIZED;
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
index 57974d732..82ce5c52a 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,12 +37,17 @@
* opcodes are therefore not defined in this interface. Likewise for LDC,
* automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and
* JSR_W.
- *
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
public interface Opcodes {
+ // ASM API versions
+
+ int ASM4 = 4 << 16 | 0 << 8 | 0;
+ int ASM5 = 5 << 16 | 0 << 8 | 0;
+
// versions
int V1_1 = 3 << 16 | 45;
@@ -51,6 +56,8 @@ public interface Opcodes {
int V1_4 = 0 << 16 | 48;
int V1_5 = 0 << 16 | 49;
int V1_6 = 0 << 16 | 50;
+ int V1_7 = 0 << 16 | 51;
+ int V1_8 = 0 << 16 | 52;
// access flags
@@ -58,7 +65,7 @@ public interface Opcodes {
int ACC_PRIVATE = 0x0002; // class, field, method
int ACC_PROTECTED = 0x0004; // class, field, method
int ACC_STATIC = 0x0008; // field, method
- int ACC_FINAL = 0x0010; // class, field, method
+ int ACC_FINAL = 0x0010; // class, field, method, parameter
int ACC_SUPER = 0x0020; // class
int ACC_SYNCHRONIZED = 0x0020; // method
int ACC_VOLATILE = 0x0040; // field
@@ -69,13 +76,14 @@ public interface Opcodes {
int ACC_INTERFACE = 0x0200; // class
int ACC_ABSTRACT = 0x0400; // class, method
int ACC_STRICT = 0x0800; // method
- int ACC_SYNTHETIC = 0x1000; // class, field, method
+ int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
int ACC_ANNOTATION = 0x2000; // class
int ACC_ENUM = 0x4000; // class(?) field inner
+ int ACC_MANDATED = 0x8000; // parameter
// ASM specific pseudo access flags
- int ACC_DEPRECATED = 131072; // class, field, method
+ int ACC_DEPRECATED = 0x20000; // class, field, method
// types for NEWARRAY
@@ -88,6 +96,18 @@ public interface Opcodes {
int T_INT = 10;
int T_LONG = 11;
+ // tags for Handle
+
+ int H_GETFIELD = 1;
+ int H_GETSTATIC = 2;
+ int H_PUTFIELD = 3;
+ int H_PUTSTATIC = 4;
+ int H_INVOKEVIRTUAL = 5;
+ int H_INVOKESTATIC = 6;
+ int H_INVOKESPECIAL = 7;
+ int H_NEWINVOKESPECIAL = 8;
+ int H_INVOKEINTERFACE = 9;
+
// stack map frame types
/**
@@ -322,7 +342,7 @@ public interface Opcodes {
int INVOKESPECIAL = 183; // -
int INVOKESTATIC = 184; // -
int INVOKEINTERFACE = 185; // -
- // int UNUSED = 186; // NOT VISITED
+ int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
int NEW = 187; // visitTypeInsn
int NEWARRAY = 188; // visitIntInsn
int ANEWARRAY = 189; // visitTypeInsn
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
index 098a8530c..8abeff621 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,9 +33,9 @@
import java.lang.reflect.Method;
/**
- * A Java type. This class can be used to make it easier to manipulate type and
- * method descriptors.
- *
+ * A Java field or method type. This class can be used to make it easier to
+ * manipulate type and method descriptors.
+ *
* @author Eric Bruneton
* @author Chris Nokleberg
*/
@@ -92,54 +92,68 @@ public class Type {
public static final int ARRAY = 9;
/**
- * The sort of object reference type. See {@link #getSort getSort}.
+ * The sort of object reference types. See {@link #getSort getSort}.
*/
public static final int OBJECT = 10;
+ /**
+ * The sort of method types. See {@link #getSort getSort}.
+ */
+ public static final int METHOD = 11;
+
/**
* The void type.
*/
- public static final Type VOID_TYPE = new Type(VOID);
+ public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24)
+ | (5 << 16) | (0 << 8) | 0, 1);
/**
* The boolean type.
*/
- public static final Type BOOLEAN_TYPE = new Type(BOOLEAN);
+ public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24)
+ | (0 << 16) | (5 << 8) | 1, 1);
/**
* The char type.
*/
- public static final Type CHAR_TYPE = new Type(CHAR);
+ public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24)
+ | (0 << 16) | (6 << 8) | 1, 1);
/**
* The byte type.
*/
- public static final Type BYTE_TYPE = new Type(BYTE);
+ public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24)
+ | (0 << 16) | (5 << 8) | 1, 1);
/**
* The short type.
*/
- public static final Type SHORT_TYPE = new Type(SHORT);
+ public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24)
+ | (0 << 16) | (7 << 8) | 1, 1);
/**
* The int type.
*/
- public static final Type INT_TYPE = new Type(INT);
+ public static final Type INT_TYPE = new Type(INT, null, ('I' << 24)
+ | (0 << 16) | (0 << 8) | 1, 1);
/**
* The float type.
*/
- public static final Type FLOAT_TYPE = new Type(FLOAT);
+ public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24)
+ | (2 << 16) | (2 << 8) | 1, 1);
/**
* The long type.
*/
- public static final Type LONG_TYPE = new Type(LONG);
+ public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24)
+ | (1 << 16) | (1 << 8) | 2, 1);
/**
* The double type.
*/
- public static final Type DOUBLE_TYPE = new Type(DOUBLE);
+ public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24)
+ | (3 << 16) | (3 << 8) | 2, 1);
// ------------------------------------------------------------------------
// Fields
@@ -157,14 +171,15 @@ public class Type {
private final char[] buf;
/**
- * The offset of the internal name of this Java type in {@link #buf buf}.
- * This field is only used for reference types.
+ * The offset of the internal name of this Java type in {@link #buf buf} or,
+ * for primitive types, the size, descriptor and getOpcode offsets for this
+ * type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset
+ * for IALOAD or IASTORE, byte 3 the offset for all other instructions).
*/
private final int off;
/**
- * The length of the internal name of this Java type. This field is only
- * used for reference types.
+ * The length of the internal name of this Java type.
*/
private final int len;
@@ -172,25 +187,19 @@ public class Type {
// Constructors
// ------------------------------------------------------------------------
- /**
- * Constructs a primitive type.
- *
- * @param sort the sort of the primitive type to be constructed.
- */
- private Type(final int sort) {
- this(sort, null, 0, 1);
- }
-
/**
* Constructs a reference type.
- *
- * @param sort the sort of the reference type to be constructed.
- * @param buf a buffer containing the descriptor of the previous type.
- * @param off the offset of this descriptor in the previous buffer.
- * @param len the length of this descriptor.
- */
- private Type(final int sort, final char[] buf, final int off, final int len)
- {
+ *
+ * @param sort
+ * the sort of the reference type to be constructed.
+ * @param buf
+ * a buffer containing the descriptor of the previous type.
+ * @param off
+ * the offset of this descriptor in the previous buffer.
+ * @param len
+ * the length of this descriptor.
+ */
+ private Type(final int sort, final char[] buf, final int off, final int len) {
this.sort = sort;
this.buf = buf;
this.off = off;
@@ -199,8 +208,9 @@ private Type(final int sort, final char[] buf, final int off, final int len)
/**
* Returns the Java type corresponding to the given type descriptor.
- *
- * @param typeDescriptor a type descriptor.
+ *
+ * @param typeDescriptor
+ * a field or method type descriptor.
* @return the Java type corresponding to the given type descriptor.
*/
public static Type getType(final String typeDescriptor) {
@@ -209,8 +219,9 @@ public static Type getType(final String typeDescriptor) {
/**
* Returns the Java type corresponding to the given internal name.
- *
- * @param internalName an internal name.
+ *
+ * @param internalName
+ * an internal name.
* @return the Java type corresponding to the given internal name.
*/
public static Type getObjectType(final String internalName) {
@@ -218,13 +229,42 @@ public static Type getObjectType(final String internalName) {
return new Type(buf[0] == '[' ? ARRAY : OBJECT, buf, 0, buf.length);
}
+ /**
+ * Returns the Java type corresponding to the given method descriptor.
+ * Equivalent to Type.getType(methodDescriptor).
+ *
+ * @param methodDescriptor
+ * a method descriptor.
+ * @return the Java type corresponding to the given method descriptor.
+ */
+ public static Type getMethodType(final String methodDescriptor) {
+ return getType(methodDescriptor.toCharArray(), 0);
+ }
+
+ /**
+ * Returns the Java method type corresponding to the given argument and
+ * return types.
+ *
+ * @param returnType
+ * the return type of the method.
+ * @param argumentTypes
+ * the argument types of the method.
+ * @return the Java type corresponding to the given argument and return
+ * types.
+ */
+ public static Type getMethodType(final Type returnType,
+ final Type... argumentTypes) {
+ return getType(getMethodDescriptor(returnType, argumentTypes));
+ }
+
/**
* Returns the Java type corresponding to the given class.
- *
- * @param c a class.
+ *
+ * @param c
+ * a class.
* @return the Java type corresponding to the given class.
*/
- public static Type getType(final Class c) {
+ public static Type getType(final Class> c) {
if (c.isPrimitive()) {
if (c == Integer.TYPE) {
return INT_TYPE;
@@ -250,11 +290,34 @@ public static Type getType(final Class c) {
}
}
+ /**
+ * Returns the Java method type corresponding to the given constructor.
+ *
+ * @param c
+ * a {@link Constructor Constructor} object.
+ * @return the Java method type corresponding to the given constructor.
+ */
+ public static Type getType(final Constructor> c) {
+ return getType(getConstructorDescriptor(c));
+ }
+
+ /**
+ * Returns the Java method type corresponding to the given method.
+ *
+ * @param m
+ * a {@link Method Method} object.
+ * @return the Java method type corresponding to the given method.
+ */
+ public static Type getType(final Method m) {
+ return getType(getMethodDescriptor(m));
+ }
+
/**
* Returns the Java types corresponding to the argument types of the given
* method descriptor.
- *
- * @param methodDescriptor a method descriptor.
+ *
+ * @param methodDescriptor
+ * a method descriptor.
* @return the Java types corresponding to the argument types of the given
* method descriptor.
*/
@@ -288,13 +351,14 @@ public static Type[] getArgumentTypes(final String methodDescriptor) {
/**
* Returns the Java types corresponding to the argument types of the given
* method.
- *
- * @param method a method.
+ *
+ * @param method
+ * a method.
* @return the Java types corresponding to the argument types of the given
* method.
*/
public static Type[] getArgumentTypes(final Method method) {
- Class[] classes = method.getParameterTypes();
+ Class>[] classes = method.getParameterTypes();
Type[] types = new Type[classes.length];
for (int i = classes.length - 1; i >= 0; --i) {
types[i] = getType(classes[i]);
@@ -305,8 +369,9 @@ public static Type[] getArgumentTypes(final Method method) {
/**
* Returns the Java type corresponding to the return type of the given
* method descriptor.
- *
- * @param methodDescriptor a method descriptor.
+ *
+ * @param methodDescriptor
+ * a method descriptor.
* @return the Java type corresponding to the return type of the given
* method descriptor.
*/
@@ -318,8 +383,9 @@ public static Type getReturnType(final String methodDescriptor) {
/**
* Returns the Java type corresponding to the return type of the given
* method.
- *
- * @param method a method.
+ *
+ * @param method
+ * a method.
* @return the Java type corresponding to the return type of the given
* method.
*/
@@ -328,52 +394,97 @@ public static Type getReturnType(final Method method) {
}
/**
- * Returns the Java type corresponding to the given type descriptor.
- *
- * @param buf a buffer containing a type descriptor.
- * @param off the offset of this descriptor in the previous buffer.
+ * Computes the size of the arguments and of the return value of a method.
+ *
+ * @param desc
+ * the descriptor of a method.
+ * @return the size of the arguments of the method (plus one for the
+ * implicit this argument), argSize, and the size of its return
+ * value, retSize, packed into a single int i =
+ * (argSize << 2) | retSize (argSize is therefore equal to
+ * i >> 2, and retSize to i & 0x03).
+ */
+ public static int getArgumentsAndReturnSizes(final String desc) {
+ int n = 1;
+ int c = 1;
+ while (true) {
+ char car = desc.charAt(c++);
+ if (car == ')') {
+ car = desc.charAt(c);
+ return n << 2
+ | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
+ } else if (car == 'L') {
+ while (desc.charAt(c++) != ';') {
+ }
+ n += 1;
+ } else if (car == '[') {
+ while ((car = desc.charAt(c)) == '[') {
+ ++c;
+ }
+ if (car == 'D' || car == 'J') {
+ n -= 1;
+ }
+ } else if (car == 'D' || car == 'J') {
+ n += 2;
+ } else {
+ n += 1;
+ }
+ }
+ }
+
+ /**
+ * Returns the Java type corresponding to the given type descriptor. For
+ * method descriptors, buf is supposed to contain nothing more than the
+ * descriptor itself.
+ *
+ * @param buf
+ * a buffer containing a type descriptor.
+ * @param off
+ * the offset of this descriptor in the previous buffer.
* @return the Java type corresponding to the given type descriptor.
*/
private static Type getType(final char[] buf, final int off) {
int len;
switch (buf[off]) {
- case 'V':
- return VOID_TYPE;
- case 'Z':
- return BOOLEAN_TYPE;
- case 'C':
- return CHAR_TYPE;
- case 'B':
- return BYTE_TYPE;
- case 'S':
- return SHORT_TYPE;
- case 'I':
- return INT_TYPE;
- case 'F':
- return FLOAT_TYPE;
- case 'J':
- return LONG_TYPE;
- case 'D':
- return DOUBLE_TYPE;
- case '[':
- len = 1;
- while (buf[off + len] == '[') {
- ++len;
- }
- if (buf[off + len] == 'L') {
- ++len;
- while (buf[off + len] != ';') {
- ++len;
- }
- }
- return new Type(ARRAY, buf, off, len + 1);
- // case 'L':
- default:
- len = 1;
+ case 'V':
+ return VOID_TYPE;
+ case 'Z':
+ return BOOLEAN_TYPE;
+ case 'C':
+ return CHAR_TYPE;
+ case 'B':
+ return BYTE_TYPE;
+ case 'S':
+ return SHORT_TYPE;
+ case 'I':
+ return INT_TYPE;
+ case 'F':
+ return FLOAT_TYPE;
+ case 'J':
+ return LONG_TYPE;
+ case 'D':
+ return DOUBLE_TYPE;
+ case '[':
+ len = 1;
+ while (buf[off + len] == '[') {
+ ++len;
+ }
+ if (buf[off + len] == 'L') {
+ ++len;
while (buf[off + len] != ';') {
++len;
}
- return new Type(OBJECT, buf, off + 1, len - 1);
+ }
+ return new Type(ARRAY, buf, off, len + 1);
+ case 'L':
+ len = 1;
+ while (buf[off + len] != ';') {
+ ++len;
+ }
+ return new Type(OBJECT, buf, off + 1, len - 1);
+ // case '(':
+ default:
+ return new Type(METHOD, buf, off, buf.length - off);
}
}
@@ -383,12 +494,12 @@ private static Type getType(final char[] buf, final int off) {
/**
* Returns the sort of this Java type.
- *
- * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
- * {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
- * {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
- * {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY} or
- * {@link #OBJECT OBJECT}.
+ *
+ * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR},
+ * {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT},
+ * {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE},
+ * {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD
+ * METHOD}.
*/
public int getSort() {
return sort;
@@ -397,7 +508,7 @@ public int getSort() {
/**
* Returns the number of dimensions of this array type. This method should
* only be used for an array type.
- *
+ *
* @return the number of dimensions of this array type.
*/
public int getDimensions() {
@@ -411,7 +522,7 @@ public int getDimensions() {
/**
* Returns the type of the elements of this array type. This method should
* only be used for an array type.
- *
+ *
* @return Returns the type of the elements of this array type.
*/
public Type getElementType() {
@@ -419,39 +530,41 @@ public Type getElementType() {
}
/**
- * Returns the name of the class corresponding to this type.
- *
- * @return the fully qualified name of the class corresponding to this type.
+ * Returns the binary name of the class corresponding to this type. This
+ * method must not be used on method types.
+ *
+ * @return the binary name of the class corresponding to this type.
*/
public String getClassName() {
switch (sort) {
- case VOID:
- return "void";
- case BOOLEAN:
- return "boolean";
- case CHAR:
- return "char";
- case BYTE:
- return "byte";
- case SHORT:
- return "short";
- case INT:
- return "int";
- case FLOAT:
- return "float";
- case LONG:
- return "long";
- case DOUBLE:
- return "double";
- case ARRAY:
- StringBuffer b = new StringBuffer(getElementType().getClassName());
- for (int i = getDimensions(); i > 0; --i) {
- b.append("[]");
- }
- return b.toString();
- // case OBJECT:
- default:
- return new String(buf, off, len).replace('/', '.');
+ case VOID:
+ return "void";
+ case BOOLEAN:
+ return "boolean";
+ case CHAR:
+ return "char";
+ case BYTE:
+ return "byte";
+ case SHORT:
+ return "short";
+ case INT:
+ return "int";
+ case FLOAT:
+ return "float";
+ case LONG:
+ return "long";
+ case DOUBLE:
+ return "double";
+ case ARRAY:
+ StringBuffer b = new StringBuffer(getElementType().getClassName());
+ for (int i = getDimensions(); i > 0; --i) {
+ b.append("[]");
+ }
+ return b.toString();
+ case OBJECT:
+ return new String(buf, off, len).replace('/', '.');
+ default:
+ return null;
}
}
@@ -460,20 +573,55 @@ public String getClassName() {
* array type. The internal name of a class is its fully qualified name (as
* returned by Class.getName(), where '.' are replaced by '/'. This method
* should only be used for an object or array type.
- *
+ *
* @return the internal name of the class corresponding to this object type.
*/
public String getInternalName() {
return new String(buf, off, len);
}
+ /**
+ * Returns the argument types of methods of this type. This method should
+ * only be used for method types.
+ *
+ * @return the argument types of methods of this type.
+ */
+ public Type[] getArgumentTypes() {
+ return getArgumentTypes(getDescriptor());
+ }
+
+ /**
+ * Returns the return type of methods of this type. This method should only
+ * be used for method types.
+ *
+ * @return the return type of methods of this type.
+ */
+ public Type getReturnType() {
+ return getReturnType(getDescriptor());
+ }
+
+ /**
+ * Returns the size of the arguments and of the return value of methods of
+ * this type. This method should only be used for method types.
+ *
+ * @return the size of the arguments (plus one for the implicit this
+ * argument), argSize, and the size of the return value, retSize,
+ * packed into a single
+ * int i = (argSize << 2) | retSize
+ * (argSize is therefore equal to i >> 2,
+ * and retSize to i & 0x03).
+ */
+ public int getArgumentsAndReturnSizes() {
+ return getArgumentsAndReturnSizes(getDescriptor());
+ }
+
// ------------------------------------------------------------------------
// Conversion to type descriptors
// ------------------------------------------------------------------------
/**
* Returns the descriptor corresponding to this Java type.
- *
+ *
* @return the descriptor corresponding to this Java type.
*/
public String getDescriptor() {
@@ -485,16 +633,16 @@ public String getDescriptor() {
/**
* Returns the descriptor corresponding to the given argument and return
* types.
- *
- * @param returnType the return type of the method.
- * @param argumentTypes the argument types of the method.
+ *
+ * @param returnType
+ * the return type of the method.
+ * @param argumentTypes
+ * the argument types of the method.
* @return the descriptor corresponding to the given argument and return
* types.
*/
- public static String getMethodDescriptor(
- final Type returnType,
- final Type[] argumentTypes)
- {
+ public static String getMethodDescriptor(final Type returnType,
+ final Type... argumentTypes) {
StringBuffer buf = new StringBuffer();
buf.append('(');
for (int i = 0; i < argumentTypes.length; ++i) {
@@ -508,46 +656,21 @@ public static String getMethodDescriptor(
/**
* Appends the descriptor corresponding to this Java type to the given
* string buffer.
- *
- * @param buf the string buffer to which the descriptor must be appended.
+ *
+ * @param buf
+ * the string buffer to which the descriptor must be appended.
*/
private void getDescriptor(final StringBuffer buf) {
- switch (sort) {
- case VOID:
- buf.append('V');
- return;
- case BOOLEAN:
- buf.append('Z');
- return;
- case CHAR:
- buf.append('C');
- return;
- case BYTE:
- buf.append('B');
- return;
- case SHORT:
- buf.append('S');
- return;
- case INT:
- buf.append('I');
- return;
- case FLOAT:
- buf.append('F');
- return;
- case LONG:
- buf.append('J');
- return;
- case DOUBLE:
- buf.append('D');
- return;
- case ARRAY:
- buf.append(this.buf, off, len);
- return;
- // case OBJECT:
- default:
- buf.append('L');
- buf.append(this.buf, off, len);
- buf.append(';');
+ if (this.buf == null) {
+ // descriptor is in byte 3 of 'off' for primitive types (buf ==
+ // null)
+ buf.append((char) ((off & 0xFF000000) >>> 24));
+ } else if (sort == OBJECT) {
+ buf.append('L');
+ buf.append(this.buf, off, len);
+ buf.append(';');
+ } else { // sort == ARRAY || sort == METHOD
+ buf.append(this.buf, off, len);
}
}
@@ -560,21 +683,23 @@ private void getDescriptor(final StringBuffer buf) {
* Returns the internal name of the given class. The internal name of a
* class is its fully qualified name, as returned by Class.getName(), where
* '.' are replaced by '/'.
- *
- * @param c an object or array class.
+ *
+ * @param c
+ * an object or array class.
* @return the internal name of the given class.
*/
- public static String getInternalName(final Class c) {
+ public static String getInternalName(final Class> c) {
return c.getName().replace('.', '/');
}
/**
* Returns the descriptor corresponding to the given Java type.
- *
- * @param c an object class, a primitive class or an array class.
+ *
+ * @param c
+ * an object class, a primitive class or an array class.
* @return the descriptor corresponding to the given class.
*/
- public static String getDescriptor(final Class c) {
+ public static String getDescriptor(final Class> c) {
StringBuffer buf = new StringBuffer();
getDescriptor(buf, c);
return buf.toString();
@@ -582,12 +707,13 @@ public static String getDescriptor(final Class c) {
/**
* Returns the descriptor corresponding to the given constructor.
- *
- * @param c a {@link Constructor Constructor} object.
+ *
+ * @param c
+ * a {@link Constructor Constructor} object.
* @return the descriptor of the given constructor.
*/
- public static String getConstructorDescriptor(final Constructor c) {
- Class[] parameters = c.getParameterTypes();
+ public static String getConstructorDescriptor(final Constructor> c) {
+ Class>[] parameters = c.getParameterTypes();
StringBuffer buf = new StringBuffer();
buf.append('(');
for (int i = 0; i < parameters.length; ++i) {
@@ -598,12 +724,13 @@ public static String getConstructorDescriptor(final Constructor c) {
/**
* Returns the descriptor corresponding to the given method.
- *
- * @param m a {@link Method Method} object.
+ *
+ * @param m
+ * a {@link Method Method} object.
* @return the descriptor of the given method.
*/
public static String getMethodDescriptor(final Method m) {
- Class[] parameters = m.getParameterTypes();
+ Class>[] parameters = m.getParameterTypes();
StringBuffer buf = new StringBuffer();
buf.append('(');
for (int i = 0; i < parameters.length; ++i) {
@@ -616,12 +743,14 @@ public static String getMethodDescriptor(final Method m) {
/**
* Appends the descriptor of the given class to the given string buffer.
- *
- * @param buf the string buffer to which the descriptor must be appended.
- * @param c the class whose descriptor must be computed.
- */
- private static void getDescriptor(final StringBuffer buf, final Class c) {
- Class d = c;
+ *
+ * @param buf
+ * the string buffer to which the descriptor must be appended.
+ * @param c
+ * the class whose descriptor must be computed.
+ */
+ private static void getDescriptor(final StringBuffer buf, final Class> c) {
+ Class> d = c;
while (true) {
if (d.isPrimitive()) {
char car;
@@ -668,69 +797,38 @@ private static void getDescriptor(final StringBuffer buf, final Class c) {
// ------------------------------------------------------------------------
/**
- * Returns the size of values of this type.
- *
+ * Returns the size of values of this type. This method must not be used for
+ * method types.
+ *
* @return the size of values of this type, i.e., 2 for long and
- * double, and 1 otherwise.
+ * double, 0 for void and 1 otherwise.
*/
public int getSize() {
- return sort == LONG || sort == DOUBLE ? 2 : 1;
+ // the size is in byte 0 of 'off' for primitive types (buf == null)
+ return buf == null ? (off & 0xFF) : 1;
}
/**
- * Returns a JVM instruction opcode adapted to this Java type.
- *
- * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
- * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
- * ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
+ * Returns a JVM instruction opcode adapted to this Java type. This method
+ * must not be used for method types.
+ *
+ * @param opcode
+ * a JVM instruction opcode. This opcode must be one of ILOAD,
+ * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG,
+ * ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
* @return an opcode that is similar to the given opcode, but adapted to
* this Java type. For example, if this type is float and
* opcode is IRETURN, this method returns FRETURN.
*/
public int getOpcode(final int opcode) {
if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
- switch (sort) {
- case BOOLEAN:
- case BYTE:
- return opcode + 5;
- case CHAR:
- return opcode + 6;
- case SHORT:
- return opcode + 7;
- case INT:
- return opcode;
- case FLOAT:
- return opcode + 2;
- case LONG:
- return opcode + 1;
- case DOUBLE:
- return opcode + 3;
- // case ARRAY:
- // case OBJECT:
- default:
- return opcode + 4;
- }
+ // the offset for IALOAD or IASTORE is in byte 1 of 'off' for
+ // primitive types (buf == null)
+ return opcode + (buf == null ? (off & 0xFF00) >> 8 : 4);
} else {
- switch (sort) {
- case VOID:
- return opcode + 5;
- case BOOLEAN:
- case CHAR:
- case BYTE:
- case SHORT:
- case INT:
- return opcode;
- case FLOAT:
- return opcode + 2;
- case LONG:
- return opcode + 1;
- case DOUBLE:
- return opcode + 3;
- // case ARRAY:
- // case OBJECT:
- default:
- return opcode + 4;
- }
+ // the offset for other instructions is in byte 2 of 'off' for
+ // primitive types (buf == null)
+ return opcode + (buf == null ? (off & 0xFF0000) >> 16 : 4);
}
}
@@ -740,10 +838,12 @@ public int getOpcode(final int opcode) {
/**
* Tests if the given object is equal to this type.
- *
- * @param o the object to be compared to this type.
+ *
+ * @param o
+ * the object to be compared to this type.
* @return true if the given object is equal to this type.
*/
+ @Override
public boolean equals(final Object o) {
if (this == o) {
return true;
@@ -755,7 +855,7 @@ public boolean equals(final Object o) {
if (sort != t.sort) {
return false;
}
- if (sort == OBJECT || sort == ARRAY) {
+ if (sort >= ARRAY) {
if (len != t.len) {
return false;
}
@@ -770,12 +870,13 @@ public boolean equals(final Object o) {
/**
* Returns a hash code value for this type.
- *
+ *
* @return a hash code value for this type.
*/
+ @Override
public int hashCode() {
int hc = 13 * sort;
- if (sort == OBJECT || sort == ARRAY) {
+ if (sort >= ARRAY) {
for (int i = off, end = i + len; i < end; i++) {
hc = 17 * (hc + buf[i]);
}
@@ -785,9 +886,10 @@ public int hashCode() {
/**
* Returns a string representation of this type.
- *
+ *
* @return the descriptor of this type.
*/
+ @Override
public String toString() {
return getDescriptor();
}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/TypePath.java b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/TypePath.java
new file mode 100644
index 000000000..9111b4213
--- /dev/null
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/TypePath.java
@@ -0,0 +1,193 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2013 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jersey.repackaged.org.objectweb.asm;
+
+/**
+ * The path to a type argument, wildcard bound, array element type, or static
+ * inner type within an enclosing type.
+ *
+ * @author Eric Bruneton
+ */
+public class TypePath {
+
+ /**
+ * A type path step that steps into the element type of an array type. See
+ * {@link #getStep getStep}.
+ */
+ public final static int ARRAY_ELEMENT = 0;
+
+ /**
+ * A type path step that steps into the nested type of a class type. See
+ * {@link #getStep getStep}.
+ */
+ public final static int INNER_TYPE = 1;
+
+ /**
+ * A type path step that steps into the bound of a wildcard type. See
+ * {@link #getStep getStep}.
+ */
+ public final static int WILDCARD_BOUND = 2;
+
+ /**
+ * A type path step that steps into a type argument of a generic type. See
+ * {@link #getStep getStep}.
+ */
+ public final static int TYPE_ARGUMENT = 3;
+
+ /**
+ * The byte array where the path is stored, in Java class file format.
+ */
+ byte[] b;
+
+ /**
+ * The offset of the first byte of the type path in 'b'.
+ */
+ int offset;
+
+ /**
+ * Creates a new type path.
+ *
+ * @param b
+ * the byte array containing the type path in Java class file
+ * format.
+ * @param offset
+ * the offset of the first byte of the type path in 'b'.
+ */
+ TypePath(byte[] b, int offset) {
+ this.b = b;
+ this.offset = offset;
+ }
+
+ /**
+ * Returns the length of this path.
+ *
+ * @return the length of this path.
+ */
+ public int getLength() {
+ return b[offset];
+ }
+
+ /**
+ * Returns the value of the given step of this path.
+ *
+ * @param index
+ * an index between 0 and {@link #getLength()}, exclusive.
+ * @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE
+ * INNER_TYPE}, {@link #WILDCARD_BOUND WILDCARD_BOUND}, or
+ * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
+ */
+ public int getStep(int index) {
+ return b[offset + 2 * index + 1];
+ }
+
+ /**
+ * Returns the index of the type argument that the given step is stepping
+ * into. This method should only be used for steps whose value is
+ * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
+ *
+ * @param index
+ * an index between 0 and {@link #getLength()}, exclusive.
+ * @return the index of the type argument that the given step is stepping
+ * into.
+ */
+ public int getStepArgument(int index) {
+ return b[offset + 2 * index + 2];
+ }
+
+ /**
+ * Converts a type path in string form, in the format used by
+ * {@link #toString()}, into a TypePath object.
+ *
+ * @param typePath
+ * a type path in string form, in the format used by
+ * {@link #toString()}. May be null or empty.
+ * @return the corresponding TypePath object, or null if the path is empty.
+ */
+ public static TypePath fromString(final String typePath) {
+ if (typePath == null || typePath.length() == 0) {
+ return null;
+ }
+ int n = typePath.length();
+ ByteVector out = new ByteVector(n);
+ out.putByte(0);
+ for (int i = 0; i < n;) {
+ char c = typePath.charAt(i++);
+ if (c == '[') {
+ out.put11(ARRAY_ELEMENT, 0);
+ } else if (c == '.') {
+ out.put11(INNER_TYPE, 0);
+ } else if (c == '*') {
+ out.put11(WILDCARD_BOUND, 0);
+ } else if (c >= '0' && c <= '9') {
+ int typeArg = c - '0';
+ while (i < n && (c = typePath.charAt(i)) >= '0' && c <= '9') {
+ typeArg = typeArg * 10 + c - '0';
+ i += 1;
+ }
+ out.put11(TYPE_ARGUMENT, typeArg);
+ }
+ }
+ out.data[0] = (byte) (out.length / 2);
+ return new TypePath(out.data, 0);
+ }
+
+ /**
+ * Returns a string representation of this type path. {@link #ARRAY_ELEMENT
+ * ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE
+ * INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps
+ * with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type
+ * argument index in decimal form.
+ */
+ @Override
+ public String toString() {
+ int length = getLength();
+ StringBuilder result = new StringBuilder(length * 2);
+ for (int i = 0; i < length; ++i) {
+ switch (getStep(i)) {
+ case ARRAY_ELEMENT:
+ result.append('[');
+ break;
+ case INNER_TYPE:
+ result.append('.');
+ break;
+ case WILDCARD_BOUND:
+ result.append('*');
+ break;
+ case TYPE_ARGUMENT:
+ result.append(getStepArgument(i));
+ break;
+ default:
+ result.append('_');
+ }
+ }
+ return result.toString();
+ }
+}
diff --git a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/package.html b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/package.html
index 85d8daa37..afbbbb53e 100644
--- a/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/package.html
+++ b/jersey-server/src/main/java/jersey/repackaged/org/objectweb/asm/package.html
@@ -1,7 +1,7 @@
diff --git a/samples/exceptions/pom.xml b/samples/exceptions/pom.xml
index 03312e94d..a936e89f1 100644
--- a/samples/exceptions/pom.xml
+++ b/samples/exceptions/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTexceptionsExceptions - Jersey sample
diff --git a/samples/extended-wadl-webapp/pom.xml b/samples/extended-wadl-webapp/pom.xml
index 6383a629f..e04c4ec26 100644
--- a/samples/extended-wadl-webapp/pom.xml
+++ b/samples/extended-wadl-webapp/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -45,7 +45,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTextended-wadl-webappExtended WADL WebApp - Jersey sample
diff --git a/samples/freemarker/pom.xml b/samples/freemarker/pom.xml
index 4e4301576..55e27ab59 100644
--- a/samples/freemarker/pom.xml
+++ b/samples/freemarker/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTfreemarkerFreemarker - Jersey sample
diff --git a/samples/generate-wadl/pom.xml b/samples/generate-wadl/pom.xml
index 9752fd88b..8a3e98903 100644
--- a/samples/generate-wadl/pom.xml
+++ b/samples/generate-wadl/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTgenerate-wadlGenerate WADL - Jersey sample
diff --git a/samples/groovy/pom.xml b/samples/groovy/pom.xml
index dba45cbdd..427068222 100644
--- a/samples/groovy/pom.xml
+++ b/samples/groovy/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTgroovyGroovy
diff --git a/samples/helloworld-osgi-webapp/functional-test/pom.xml b/samples/helloworld-osgi-webapp/functional-test/pom.xml
index 885dcf39e..ba3870cc1 100644
--- a/samples/helloworld-osgi-webapp/functional-test/pom.xml
+++ b/samples/helloworld-osgi-webapp/functional-test/pom.xml
@@ -50,7 +50,7 @@
com.sun.jersey.samples.helloworld-osgi-webappfunctional-test
- 1.18.1
+ 1.18.4-SNAPSHOTpomHelloworld OSGi WebApp - Jersey Sample Test
diff --git a/samples/helloworld-osgi-webapp/pom.xml b/samples/helloworld-osgi-webapp/pom.xml
index e8700063d..a162af744 100644
--- a/samples/helloworld-osgi-webapp/pom.xml
+++ b/samples/helloworld-osgi-webapp/pom.xml
@@ -49,13 +49,13 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOThelloworld-osgi-webappHelloworld OSGi WebApp - Jersey Sample
- 1.18.1
+ 1.18.4-SNAPSHOTpom
diff --git a/samples/helloworld-osgi-webapp/war-bundle/pom.xml b/samples/helloworld-osgi-webapp/war-bundle/pom.xml
index 309763284..1bf0ab890 100644
--- a/samples/helloworld-osgi-webapp/war-bundle/pom.xml
+++ b/samples/helloworld-osgi-webapp/war-bundle/pom.xml
@@ -49,7 +49,7 @@
com.sun.jersey.samples.helloworld-osgi-webappwar-bundle
- 1.18.1
+ 1.18.4-SNAPSHOTHelloworld OSGi WebApp - Jersey Sample WAR
diff --git a/samples/helloworld-webapp/pom.xml b/samples/helloworld-webapp/pom.xml
index bedb3a574..0bce21e92 100644
--- a/samples/helloworld-webapp/pom.xml
+++ b/samples/helloworld-webapp/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOThelloworld-webappHelloworld WebApp - Jersey Sample
diff --git a/samples/helloworld/pom.xml b/samples/helloworld/pom.xml
index 0541f9994..b83368866 100644
--- a/samples/helloworld/pom.xml
+++ b/samples/helloworld/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOThelloworldHelloworld - Jersey sample
diff --git a/samples/https-clientserver-grizzly/pom.xml b/samples/https-clientserver-grizzly/pom.xml
index b5670ec2f..a11a4d5a7 100644
--- a/samples/https-clientserver-grizzly/pom.xml
+++ b/samples/https-clientserver-grizzly/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -45,7 +45,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOThttps-clientserver-grizzlyHTTPS Client/Server - Jersey sample - Grizzly
diff --git a/samples/https-server-glassfish/pom.xml b/samples/https-server-glassfish/pom.xml
index 4c13039b9..6b74a693e 100644
--- a/samples/https-server-glassfish/pom.xml
+++ b/samples/https-server-glassfish/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOThttps-server-glassfishHTTPS Server - Jersey sample - GlassFish
diff --git a/samples/jacksonjsonprovider/pom.xml b/samples/jacksonjsonprovider/pom.xml
index 8ae49cda8..a5a35f94b 100644
--- a/samples/jacksonjsonprovider/pom.xml
+++ b/samples/jacksonjsonprovider/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
jersey-samplescom.sun.jersey.samples
- 1.18.1
+ 1.18.4-SNAPSHOT4.0.0jacksonjsonprovider
diff --git a/samples/jaxb/pom.xml b/samples/jaxb/pom.xml
index d7a268c7a..9e24d371d 100644
--- a/samples/jaxb/pom.xml
+++ b/samples/jaxb/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTjaxbJAXB - Jersey sample
diff --git a/samples/jersey-cdi/pom.xml b/samples/jersey-cdi/pom.xml
index cc279c4eb..c7f4c523c 100644
--- a/samples/jersey-cdi/pom.xml
+++ b/samples/jersey-cdi/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-cdiJersey CDI - Jersey Sample
diff --git a/samples/jersey-ejb/pom.xml b/samples/jersey-ejb/pom.xml
index 647b2934f..3ca600437 100644
--- a/samples/jersey-ejb/pom.xml
+++ b/samples/jersey-ejb/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-ejbJersey EJB - Jersey Sample
diff --git a/samples/jersey-guice-filter/pom.xml b/samples/jersey-guice-filter/pom.xml
index 74c218b84..dbd7f0a25 100644
--- a/samples/jersey-guice-filter/pom.xml
+++ b/samples/jersey-guice-filter/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTguicefilter-webappGuiceFilter WebApp - Jersey Sample
diff --git a/samples/jersey-server-linking-sample/pom.xml b/samples/jersey-server-linking-sample/pom.xml
index fa6bb3a17..a0e358194 100644
--- a/samples/jersey-server-linking-sample/pom.xml
+++ b/samples/jersey-server-linking-sample/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTjersey-server-linking-sampleDeclarative Hyperlinking - Jersey Sample
diff --git a/samples/json-from-jaxb/pom.xml b/samples/json-from-jaxb/pom.xml
index a2ee184fc..8212baeed 100644
--- a/samples/json-from-jaxb/pom.xml
+++ b/samples/json-from-jaxb/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTjson-from-jaxbJSON From JAXB - Jersey sample
diff --git a/samples/jsonp/pom.xml b/samples/jsonp/pom.xml
index c9922fc10..e064a81ef 100644
--- a/samples/jsonp/pom.xml
+++ b/samples/jsonp/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTjsonpJSONP - Jersey sample
diff --git a/samples/managed-beans-webapp/pom.xml b/samples/managed-beans-webapp/pom.xml
index d5a3ea62f..1156eac9d 100644
--- a/samples/managed-beans-webapp/pom.xml
+++ b/samples/managed-beans-webapp/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTmanaged-beans-webappManaged Beans WebApp - Jersey Sample
diff --git a/samples/mandel/pom.xml b/samples/mandel/pom.xml
index 8975045d2..9925b168e 100644
--- a/samples/mandel/pom.xml
+++ b/samples/mandel/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTmandelMandel -- Jersey sample
diff --git a/samples/moxy-oxm-mapping/beans/pom.xml b/samples/moxy-oxm-mapping/beans/pom.xml
index bb0e38c72..7c51465c1 100644
--- a/samples/moxy-oxm-mapping/beans/pom.xml
+++ b/samples/moxy-oxm-mapping/beans/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.samplesmoxy-oxm-mapping
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.samples.moxy-oxm-mappingbeans
diff --git a/samples/moxy-oxm-mapping/pom.xml b/samples/moxy-oxm-mapping/pom.xml
index c4586b78d..0471d7500 100644
--- a/samples/moxy-oxm-mapping/pom.xml
+++ b/samples/moxy-oxm-mapping/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -50,13 +50,13 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTmoxy-oxm-mappingMOXy OXM Mapping - Jersey Sample
- 1.18.1
+ 1.18.4-SNAPSHOTpom
diff --git a/samples/moxy-oxm-mapping/webapp/pom.xml b/samples/moxy-oxm-mapping/webapp/pom.xml
index ebfa8d995..fedaeee34 100644
--- a/samples/moxy-oxm-mapping/webapp/pom.xml
+++ b/samples/moxy-oxm-mapping/webapp/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.samplesmoxy-oxm-mapping
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.samples.moxy-oxm-mappingmoxy-oxm-mapping-webapp
@@ -172,6 +172,6 @@
- 1.18.1
+ 1.18.4-SNAPSHOT
diff --git a/samples/moxy/pom.xml b/samples/moxy/pom.xml
index 559e163be..2cedc0621 100644
--- a/samples/moxy/pom.xml
+++ b/samples/moxy/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTmoxywar
@@ -171,6 +171,6 @@
- 1.18.1
+ 1.18.4-SNAPSHOT
diff --git a/samples/multipart-webapp/pom.xml b/samples/multipart-webapp/pom.xml
index c936313bc..05717e059 100644
--- a/samples/multipart-webapp/pom.xml
+++ b/samples/multipart-webapp/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTmultipart-webappMultipart WebApp - Jersey Sample
diff --git a/samples/oauth-client-twitter/pom.xml b/samples/oauth-client-twitter/pom.xml
index 885e1ef5e..70fd40d33 100644
--- a/samples/oauth-client-twitter/pom.xml
+++ b/samples/oauth-client-twitter/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -47,7 +47,7 @@
jersey-samplescom.sun.jersey.samples
- 1.18.1
+ 1.18.4-SNAPSHOToauth-client-twitterTwitter Client using OAuth
diff --git a/samples/optimistic-concurrency/pom.xml b/samples/optimistic-concurrency/pom.xml
index e272f1cbb..f751930df 100644
--- a/samples/optimistic-concurrency/pom.xml
+++ b/samples/optimistic-concurrency/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -45,7 +45,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOToptimistic-concurrencyOptimistic Concurrency - Jersey sample
diff --git a/samples/osgi-http-service/bundle/pom.xml b/samples/osgi-http-service/bundle/pom.xml
index af3a3a94b..6e7586ddd 100644
--- a/samples/osgi-http-service/bundle/pom.xml
+++ b/samples/osgi-http-service/bundle/pom.xml
@@ -46,7 +46,7 @@
com.sun.jersey.samplesosgi-http-service
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.samples.osgi-http-service
diff --git a/samples/osgi-http-service/functional-test/pom.xml b/samples/osgi-http-service/functional-test/pom.xml
index 60439cbcd..26f7bcf05 100644
--- a/samples/osgi-http-service/functional-test/pom.xml
+++ b/samples/osgi-http-service/functional-test/pom.xml
@@ -48,7 +48,7 @@
com.sun.jersey.samplesosgi-http-service
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.samples.osgi-http-service
diff --git a/samples/osgi-http-service/pom.xml b/samples/osgi-http-service/pom.xml
index ee3b13448..68fec4f2a 100644
--- a/samples/osgi-http-service/pom.xml
+++ b/samples/osgi-http-service/pom.xml
@@ -50,13 +50,13 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTosgi-http-serviceOSGi HttpService - Jersey Sample
- 1.18.1
+ 1.18.4-SNAPSHOTpom
diff --git a/samples/pom.xml b/samples/pom.xml
index 9af5a734f..1dfbdffe4 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,11 +46,11 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTAll Jersey samples
Samples that show how to use jersey.
diff --git a/samples/scala-helloworld-webapp/pom.xml b/samples/scala-helloworld-webapp/pom.xml
index e69ccf08c..8825796c1 100644
--- a/samples/scala-helloworld-webapp/pom.xml
+++ b/samples/scala-helloworld-webapp/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -46,7 +46,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTscala-helloworld-webappScala Helloworld WebApp - Jersey sample
diff --git a/samples/simple-atom-server/pom.xml b/samples/simple-atom-server/pom.xml
index 23650bae5..a0b11ca4e 100644
--- a/samples/simple-atom-server/pom.xml
+++ b/samples/simple-atom-server/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -45,7 +45,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTsimple-atom-serverSimple Atom Server - Jersey sample
diff --git a/samples/simple-console/pom.xml b/samples/simple-console/pom.xml
index 766fb9210..c2ff1e50f 100644
--- a/samples/simple-console/pom.xml
+++ b/samples/simple-console/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -45,7 +45,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTsimple-consoleSimple Console - Jersey sample
diff --git a/samples/simple-servlet/pom.xml b/samples/simple-servlet/pom.xml
index 44e90fcda..9e9b4e30e 100644
--- a/samples/simple-servlet/pom.xml
+++ b/samples/simple-servlet/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTsimple-servletSimple Servlet - Jersey sample
diff --git a/samples/sparklines/pom.xml b/samples/sparklines/pom.xml
index cfdbae993..266aef9ba 100644
--- a/samples/sparklines/pom.xml
+++ b/samples/sparklines/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTsparklinesSparklines - Jersey sample
diff --git a/samples/spring-annotations/pom.xml b/samples/spring-annotations/pom.xml
index fa90f29a8..82476473b 100644
--- a/samples/spring-annotations/pom.xml
+++ b/samples/spring-annotations/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTspring-annotationsSpring Annotations WebApp - Jersey sample
diff --git a/samples/storage-service/pom.xml b/samples/storage-service/pom.xml
index 49426b9bf..95e4d4d05 100644
--- a/samples/storage-service/pom.xml
+++ b/samples/storage-service/pom.xml
@@ -3,7 +3,7 @@
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
@@ -45,7 +45,7 @@
com.sun.jersey.samplesjersey-samples
- 1.18.1
+ 1.18.4-SNAPSHOTstorage-serviceStorage Service - Jersey sample
diff --git a/tests/functional/end-to-end-tests/exceptions/pom.xml b/tests/functional/end-to-end-tests/exceptions/pom.xml
index 64b4af685..7901d6840 100644
--- a/tests/functional/end-to-end-tests/exceptions/pom.xml
+++ b/tests/functional/end-to-end-tests/exceptions/pom.xml
@@ -48,7 +48,7 @@
com.sun.jersey.test.functionalend-to-end-tests
- 1.18.1
+ 1.18.4-SNAPSHOTexceptions
diff --git a/tests/functional/end-to-end-tests/listeners-test/pom.xml b/tests/functional/end-to-end-tests/listeners-test/pom.xml
index e4b63f049..764436f4b 100644
--- a/tests/functional/end-to-end-tests/listeners-test/pom.xml
+++ b/tests/functional/end-to-end-tests/listeners-test/pom.xml
@@ -126,6 +126,6 @@
- 1.18.1
+ 1.18.4-SNAPSHOT
diff --git a/tests/functional/pom.xml b/tests/functional/pom.xml
index 46030bc43..831514349 100644
--- a/tests/functional/pom.xml
+++ b/tests/functional/pom.xml
@@ -46,7 +46,7 @@
com.sun.jersey.testfunctional-tests
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.test.functionaljersey-qe-tests
@@ -54,7 +54,7 @@
pom
- 1.18.1
+ 1.18.4-SNAPSHOTJersey QE Tests
diff --git a/tests/grizzly2/pom.xml b/tests/grizzly2/pom.xml
index a53eb8794..c65cd61ae 100644
--- a/tests/grizzly2/pom.xml
+++ b/tests/grizzly2/pom.xml
@@ -47,7 +47,7 @@
com.sun.jersey.testfunctional-tests
- 1.18.1
+ 1.18.4-SNAPSHOTgrizzly2-testspom
diff --git a/tests/pom.xml b/tests/pom.xml
index 7fa0927be..10024b808 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -48,11 +48,11 @@
com.sun.jerseyjersey-project
- 1.18.1
+ 1.18.4-SNAPSHOTcom.sun.jersey.testfunctional-tests
- 1.18.1
+ 1.18.4-SNAPSHOTpomProject Jersey tests