1 2 /* 3 * @test /nodynamiccopyright/ 4 * @bug 7190862 7109747 5 * @summary javap shows an incorrect type for operands if the 'wide' prefix is used 6 * @modules jdk.jdeps 7 */ 8 9 import com.sun.source.util.JavacTask; 10 import com.sun.tools.javap.JavapFileManager; 11 import com.sun.tools.javap.JavapTask; 12 import java.io.PrintWriter; 13 import java.io.StringWriter; 14 import java.net.URI; 15 import java.util.Arrays; 16 import java.util.List; 17 import java.util.Locale; 18 import javax.tools.Diagnostic; 19 import javax.tools.DiagnosticCollector; 20 import javax.tools.JavaCompiler; 21 import javax.tools.JavaFileManager; 22 import javax.tools.JavaFileObject; 23 import javax.tools.SimpleJavaFileObject; 24 import javax.tools.ToolProvider; 25 26 public class T7190862 { 27 28 enum TypeWideInstructionMap { 29 INT("int", new String[]{"istore_w", "iload_w"}), 30 LONG("long", new String[]{"lstore_w", "lload_w"}), 31 FLOAT("float", new String[]{"fstore_w", "fload_w"}), 32 DOUBLE("double", new String[]{"dstore_w", "dload_w"}), 33 OBJECT("Object", new String[]{"astore_w", "aload_w"}); 34 35 String type; 36 String[] instructions; 37 38 TypeWideInstructionMap(String type, String[] instructions) { 39 this.type = type; 40 this.instructions = instructions; 41 } 42 } 43 44 JavaSource source; 45 46 public static void main(String[] args) { 47 JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); 48 new T7190862().run(comp); 49 } 50 51 private void run(JavaCompiler comp) { 52 String code; 53 for (TypeWideInstructionMap typeInstructionMap: TypeWideInstructionMap.values()) { 54 if (typeInstructionMap != TypeWideInstructionMap.OBJECT) { 55 code = createWideLocalSource(typeInstructionMap.type, 300); 56 } else { 57 code = createWideLocalSourceForObject(300); 58 } 59 source = new JavaSource(code); 60 compile(comp); 61 check(typeInstructionMap.instructions); 62 } 63 64 //an extra test for the iinc instruction 65 code = createIincSource(); 66 source = new JavaSource(code); 67 compile(comp); 68 check(new String[]{"iinc_w"}); 69 } 70 71 private void compile(JavaCompiler comp) { 72 JavacTask ct = (JavacTask)comp.getTask(null, null, null, null, null, Arrays.asList(source)); 73 try { 74 if (!ct.call()) { 75 throw new AssertionError("Error thrown when compiling the following source:\n" + source.getCharContent(true)); 76 } 77 } catch (Throwable ex) { 78 throw new AssertionError("Error thrown when compiling the following source:\n" + source.getCharContent(true)); 79 } 80 } 81 82 private void check(String[] instructions) { 83 String out = javap(Arrays.asList("-c"), Arrays.asList("Test.class")); 84 for (String line: out.split(System.getProperty("line.separator"))) { 85 line = line.trim(); 86 for (String instruction: instructions) { 87 if (line.contains(instruction) && line.contains("#")) { 88 throw new Error("incorrect type for operands for instruction " + instruction); 89 } 90 } 91 } 92 } 93 94 private String javap(List<String> args, List<String> classes) { 95 DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<JavaFileObject>(); 96 StringWriter sw = new StringWriter(); 97 PrintWriter pw = new PrintWriter(sw); 98 JavaFileManager fm = JavapFileManager.create(dc, pw); 99 JavapTask t = new JavapTask(pw, fm, dc, args, classes); 100 if (t.run() != 0) 101 throw new Error("javap failed unexpectedly"); 102 103 List<Diagnostic<? extends JavaFileObject>> diags = dc.getDiagnostics(); 104 for (Diagnostic<? extends JavaFileObject> d: diags) { 105 if (d.getKind() == Diagnostic.Kind.ERROR) 106 throw new Error(d.getMessage(Locale.ENGLISH)); 107 } 108 return sw.toString(); 109 110 } 111 112 private String createWideLocalSource(String type, int numberOfVars) { 113 String result = " " + type + " x0 = 0;\n"; 114 for (int i = 1; i < numberOfVars; i++) { 115 result += " " + type + " x" + i + " = x" + (i - 1) + " + 1;\n"; 116 } 117 return result; 118 } 119 120 private String createWideLocalSourceForObject(int numberOfVars) { 121 String result = " Object x0 = new Object();\n"; 122 for (int i = 1; i < numberOfVars; i++) { 123 result += " Object x" + i + " = x0;\n"; 124 } 125 return result; 126 } 127 128 private String createIincSource() { 129 return " int i = 0;\n" 130 + " i += 1;\n" 131 + " i += 51;\n" 132 + " i += 101;\n" 133 + " i += 151;\n"; 134 } 135 136 class JavaSource extends SimpleJavaFileObject { 137 138 String template = "class Test {\n" + 139 " public static void main(String[] args)\n" + 140 " {\n" + 141 " #C" + 142 " }\n" + 143 "}"; 144 145 String source; 146 147 public JavaSource(String code) { 148 super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE); 149 source = template.replaceAll("#C", code); 150 } 151 152 @Override 153 public CharSequence getCharContent(boolean ignoreEncodingErrors) { 154 return source; 155 } 156 } 157 }