Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/shared/Printer.java
41161 views
/*1* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package vm.runtime.defmeth.shared;2425import java.util.List;26import java.util.ArrayList;27import static jdk.internal.org.objectweb.asm.Opcodes.*;2829import vm.runtime.defmeth.shared.data.*;30import vm.runtime.defmeth.shared.data.method.*;31import vm.runtime.defmeth.shared.data.method.body.*;32import vm.runtime.defmeth.shared.data.method.param.*;33import vm.runtime.defmeth.shared.data.method.result.*;3435import static java.lang.String.*;36import nsk.share.Pair;373839/**40* Construct text representation of a class.41* Used to print generated class hierarchies.42*/43public class Printer implements Visitor {4445private StringBuilder sb = new StringBuilder();46private Tester t;4748private String output() {49return sb.toString();50}5152static private String printAcc(int acc) {53List<String> flags = new ArrayList<>();54if ((acc & ACC_STATIC) != 0) {55flags.add("static");56}57if ((acc & ACC_PUBLIC) != 0) {58flags.add("public");59}60if ((acc & ACC_PRIVATE) != 0) {61flags.add("private");62}63if ((acc & ACC_PROTECTED) != 0) {64flags.add("protected");65}66if ((acc & ACC_PUBLIC) == 0 &&67(acc & ACC_PRIVATE) == 0 &&68(acc & ACC_PROTECTED) == 0) {69flags.add("package");70}71if ((acc & ACC_SYNCHRONIZED) != 0) {72flags.add("synchronized");73}74return Util.intersperse(" ", flags.toArray(new String[0]));75}7677static public String print(Clazz clz) {78Printer p = new Printer();79clz.visit(p);80return p.output();81}8283static public String print(Method m) {84Printer p = new Printer();85m.visit(p);86return p.output();87}8889@Override90public void visitClass(Clazz clz) {91throw new IllegalStateException("More specific method should be called");92}9394@Override95public void visitMethod(Method m) {96sb.append(String.format(97"%s%s",98m.name(), m.desc()));99100if (m.sig() != null) {101sb.append("/* <").append(m.sig()).append("> */");102}103}104105@Override106public void visitConcreteClass(ConcreteClass clz) {107sb.append("class ").append(clz.name()).append(" ");108109if (!clz.parent().name().equals("java.lang.Object")) {110sb.append("extends ").append(clz.parent().name()).append(" ");111}112113if (clz.interfaces().length > 0) {114sb.append("implements ");115sb.append(Util.intersperse(", ", Util.asStrings(clz.interfaces())));116sb.append(" ");117}118119Method[] methods = clz.methods();120121sb.append("{");122if (methods.length > 0) {123for (Method m : methods) {124sb.append("\n ");125m.visit(this);126}127sb.append("\n");128}129sb.append("}");130}131132@Override133public void visitInterface(Interface intf) {134sb.append("interface ").append(intf.name())135.append(" ");136137if (intf.parents().length > 0) {138sb.append("extends ");139sb.append(Util.intersperse(", ", Util.asStrings(intf.parents())));140sb.append(" ");141}142143Method[] methods = intf.methods();144145sb.append("{");146if (methods.length > 0) {147for (Method m : methods) {148sb.append("\n ");149m.visit(this);150}151sb.append("\n");152}153sb.append("}");154}155@Override156157/* ====================================================================== */158159public void visitTester(Tester t) {160this.t = t;161162//sb.append(t.name()).append(": ");163sb.append("TEST: ");164165//t.getCall().visit(this);166CallMethod call = t.getCall();167168// call.receiverClass() is null when a .staticCallSite() invoke is169// used. There is a staticClass but no receiverClass.170sb.append(format("%s o = new %s(); o.%s%s",171call.staticClass().name(),172(call.receiverClass() == null ? "" : call.receiverClass().name()),173call.methodName(),174call.methodDesc()));175176sb.append(" ");177178t.getResult().visit(this);179180this.t = null;181}182183/* ====================================================================== */184185@Override186public void visitAbstractMethod(AbstractMethod m) {187Pair<String[],String> desc = Util.parseDesc(m.desc());188189sb.append(format(190"abstract %s %s %s(%s);",191printAcc(m.acc()),192Util.decodeClassName(desc.second),193m.name(),194Util.intersperse(", ", desc.first)));195196if (m.sig() != null) {197sb.append("<").append(m.sig()).append(">");198}199}200201@Override202public void visitConcreteMethod(ConcreteMethod m) {203Pair<String[],String> desc = Util.parseDesc(m.desc());204205sb.append(format(206"%s %s %s(%s)",207printAcc(m.acc()),208Util.decodeClassName(desc.second),209m.name(),210Util.intersperse(", ", desc.first)));211212if (m.sig() != null) {213sb.append("<").append(m.sig()).append(">");214}215216sb.append(" ");217218sb.append(" { ");219m.body().visit(this);220sb.append(" }");221}222223@Override224public void visitDefaultMethod(DefaultMethod m) {225Pair<String[],String> desc = Util.parseDesc(m.desc());226227sb.append(format(228"default %s %s %s(%s)",229printAcc(m.acc()),230Util.decodeClassName(desc.second),231m.name(),232Util.intersperse(", ", desc.first)));233234if (m.sig() != null) {235sb.append("<").append(m.sig()).append(">");236}237238sb.append(" { ");239m.body().visit(this);240sb.append(" }");241}242243/* ====================================================================== */244245@Override246public void visitThrowExBody(ThrowExBody body) {247sb.append(String.format(248"throw new %s();", body.getExc().name()));249}250251@Override252public void visitReturnIntBody(ReturnIntBody body) {253sb.append(String.format(254"return %d;", body.getValue()));255}256257@Override258public void visitReturnNullBody(ReturnNullBody body) {259sb.append("return null;");260}261262@Override263public void visitEmptyBody(EmptyBody aThis) {264}265266/* ====================================================================== */267268@Override269public void visitResultIgnore() {270sb.append("/* result ignored */");271}272273@Override274public void visitResultInt(IntResult res) {275sb.append("== ").append(res.getExpected());276}277278@Override279public void visitResultThrowExc(ThrowExResult res) {280sb.append(String.format(281"throws %s%s",282abbreviateExcName(res.getExc().name()),283res.getMessage() != null ? "(\"" + res.getMessage() + "\")" : ""));284}285286private String abbreviateExcName(String name) {287switch(name) {288case "java.lang.AbstractMethodError" : return "AME";289case "java.lang.NoSuchMethodError" : return "NSME";290default: return name.replaceAll("java\\.lang\\.", "");291}292}293/* ====================================================================== */294295@Override296public void visitParamInt(IntParam param) {297sb.append(param.value());298}299300@Override301public void visitParamString(StringParam param) {302sb.append(param.value());303}304305@Override306public void visitParamNull() {307sb.append("null");308}309@Override310public void visitParamLong(LongParam param) {311sb.append(param.value());312}313314@Override315public void visitParamFloat(FloatParam param) {316sb.append(param.value());317}318319@Override320public void visitParamDouble(DoubleParam param) {321sb.append(param.value());322}323324@Override325public void visitParamNewInstance(NewInstanceParam param) {326sb.append(String.format(327"new %s()",328param.clazz().name()));329}330331@Override332public void visitCallMethod(CallMethod call) {333String[] paramTypes = Util.parseDesc(call.methodDesc()).first;334335if (paramTypes.length != call.params().length) {336throw new IllegalStateException();337}338339//sb.append("{ ");340if (!call.popReturnValue()) {341sb.append("return ");342}343344switch (call.invokeInsn()) {345case VIRTUAL: case INTERFACE:346sb.append(String.format(347"((%s)%s).%s(",348call.staticClass().name(),349call.receiverClass() != null ? call.receiverClass().name() : "this",350call.methodName()));351break;352case STATIC:353sb.append(String.format(354"%s.%s(",355call.staticClass().name(),356call.methodName()));357break;358case SPECIAL:359sb.append(String.format(360"%s.super.%s(",361call.staticClass().name(),362call.methodName()));363break;364default:365throw new IllegalStateException();366}367368for (int i = 0; i<paramTypes.length; i++) {369sb.append(String.format(370"(%s)", paramTypes[i]));371372call.params()[i].visit(this);373374if (i+1 < paramTypes.length) {375sb.append(", ");376}377}378379//sb.append("); }");380sb.append(");");381}382383@Override384public void visitReturnNewInstanceBody(ReturnNewInstanceBody body) {385sb.append(String.format(386"return new %s();",387body.getType().name()));388}389}390391392