aoqi@0: aoqi@0: /* aoqi@0: * @test /nodynamiccopyright/ aoqi@0: * @bug 7190862 7109747 aoqi@0: * @summary javap shows an incorrect type for operands if the 'wide' prefix is used aoqi@0: */ aoqi@0: aoqi@0: import com.sun.source.util.JavacTask; aoqi@0: import com.sun.tools.javap.JavapFileManager; aoqi@0: import com.sun.tools.javap.JavapTask; aoqi@0: import java.io.PrintWriter; aoqi@0: import java.io.StringWriter; aoqi@0: import java.net.URI; aoqi@0: import java.util.Arrays; aoqi@0: import java.util.List; aoqi@0: import java.util.Locale; aoqi@0: import javax.tools.Diagnostic; aoqi@0: import javax.tools.DiagnosticCollector; aoqi@0: import javax.tools.JavaCompiler; aoqi@0: import javax.tools.JavaFileManager; aoqi@0: import javax.tools.JavaFileObject; aoqi@0: import javax.tools.SimpleJavaFileObject; aoqi@0: import javax.tools.ToolProvider; aoqi@0: aoqi@0: public class T7190862 { aoqi@0: aoqi@0: enum TypeWideInstructionMap { aoqi@0: INT("int", new String[]{"istore_w", "iload_w"}), aoqi@0: LONG("long", new String[]{"lstore_w", "lload_w"}), aoqi@0: FLOAT("float", new String[]{"fstore_w", "fload_w"}), aoqi@0: DOUBLE("double", new String[]{"dstore_w", "dload_w"}), aoqi@0: OBJECT("Object", new String[]{"astore_w", "aload_w"}); aoqi@0: aoqi@0: String type; aoqi@0: String[] instructions; aoqi@0: aoqi@0: TypeWideInstructionMap(String type, String[] instructions) { aoqi@0: this.type = type; aoqi@0: this.instructions = instructions; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: JavaSource source; aoqi@0: aoqi@0: public static void main(String[] args) { aoqi@0: JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); aoqi@0: new T7190862().run(comp); aoqi@0: } aoqi@0: aoqi@0: private void run(JavaCompiler comp) { aoqi@0: String code; aoqi@0: for (TypeWideInstructionMap typeInstructionMap: TypeWideInstructionMap.values()) { aoqi@0: if (typeInstructionMap != TypeWideInstructionMap.OBJECT) { aoqi@0: code = createWideLocalSource(typeInstructionMap.type, 300); aoqi@0: } else { aoqi@0: code = createWideLocalSourceForObject(300); aoqi@0: } aoqi@0: source = new JavaSource(code); aoqi@0: compile(comp); aoqi@0: check(typeInstructionMap.instructions); aoqi@0: } aoqi@0: aoqi@0: //an extra test for the iinc instruction aoqi@0: code = createIincSource(); aoqi@0: source = new JavaSource(code); aoqi@0: compile(comp); aoqi@0: check(new String[]{"iinc_w"}); aoqi@0: } aoqi@0: aoqi@0: private void compile(JavaCompiler comp) { aoqi@0: JavacTask ct = (JavacTask)comp.getTask(null, null, null, null, null, Arrays.asList(source)); aoqi@0: try { aoqi@0: if (!ct.call()) { aoqi@0: throw new AssertionError("Error thrown when compiling the following source:\n" + source.getCharContent(true)); aoqi@0: } aoqi@0: } catch (Throwable ex) { aoqi@0: throw new AssertionError("Error thrown when compiling the following source:\n" + source.getCharContent(true)); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: private void check(String[] instructions) { aoqi@0: String out = javap(Arrays.asList("-c"), Arrays.asList("Test.class")); aoqi@0: for (String line: out.split(System.getProperty("line.separator"))) { aoqi@0: line = line.trim(); aoqi@0: for (String instruction: instructions) { aoqi@0: if (line.contains(instruction) && line.contains("#")) { aoqi@0: throw new Error("incorrect type for operands for instruction " + instruction); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: private String javap(List args, List classes) { aoqi@0: DiagnosticCollector dc = new DiagnosticCollector(); aoqi@0: StringWriter sw = new StringWriter(); aoqi@0: PrintWriter pw = new PrintWriter(sw); aoqi@0: JavaFileManager fm = JavapFileManager.create(dc, pw); aoqi@0: JavapTask t = new JavapTask(pw, fm, dc, args, classes); aoqi@0: if (t.run() != 0) aoqi@0: throw new Error("javap failed unexpectedly"); aoqi@0: aoqi@0: List> diags = dc.getDiagnostics(); aoqi@0: for (Diagnostic d: diags) { aoqi@0: if (d.getKind() == Diagnostic.Kind.ERROR) aoqi@0: throw new Error(d.getMessage(Locale.ENGLISH)); aoqi@0: } aoqi@0: return sw.toString(); aoqi@0: aoqi@0: } aoqi@0: aoqi@0: private String createWideLocalSource(String type, int numberOfVars) { aoqi@0: String result = " " + type + " x0 = 0;\n"; aoqi@0: for (int i = 1; i < numberOfVars; i++) { aoqi@0: result += " " + type + " x" + i + " = x" + (i - 1) + " + 1;\n"; aoqi@0: } aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: private String createWideLocalSourceForObject(int numberOfVars) { aoqi@0: String result = " Object x0 = new Object();\n"; aoqi@0: for (int i = 1; i < numberOfVars; i++) { aoqi@0: result += " Object x" + i + " = x0;\n"; aoqi@0: } aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: private String createIincSource() { aoqi@0: return " int i = 0;\n" aoqi@0: + " i += 1;\n" aoqi@0: + " i += 51;\n" aoqi@0: + " i += 101;\n" aoqi@0: + " i += 151;\n"; aoqi@0: } aoqi@0: aoqi@0: class JavaSource extends SimpleJavaFileObject { aoqi@0: aoqi@0: String template = "class Test {\n" + aoqi@0: " public static void main(String[] args)\n" + aoqi@0: " {\n" + aoqi@0: " #C" + aoqi@0: " }\n" + aoqi@0: "}"; aoqi@0: aoqi@0: String source; aoqi@0: aoqi@0: public JavaSource(String code) { aoqi@0: super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE); aoqi@0: source = template.replaceAll("#C", code); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public CharSequence getCharContent(boolean ignoreEncodingErrors) { aoqi@0: return source; aoqi@0: } aoqi@0: } aoqi@0: }