diff --git a/src/jdk.incubator.code/share/classes/jdk/incubator/code/Op.java b/src/jdk.incubator.code/share/classes/jdk/incubator/code/Op.java index b5a5b1455bb..0facc946f3f 100644 --- a/src/jdk.incubator.code/share/classes/jdk/incubator/code/Op.java +++ b/src/jdk.incubator.code/share/classes/jdk/incubator/code/Op.java @@ -31,21 +31,15 @@ import com.sun.tools.javac.api.JavacScope; import com.sun.tools.javac.api.JavacTrees; -import com.sun.tools.javac.code.Source; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.comp.Attr; -import com.sun.tools.javac.comp.Modules; -import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Names; import jdk.incubator.code.internal.ReflectMethods; import jdk.incubator.code.op.CoreOp.FuncOp; -import jdk.incubator.code.op.ExtendedOp; -import jdk.incubator.code.parser.OpParser; import jdk.incubator.code.type.FunctionType; import jdk.incubator.code.type.MethodRef; import jdk.incubator.code.writer.OpWriter; @@ -54,7 +48,6 @@ import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; -import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.util.*; @@ -495,39 +488,27 @@ public static Optional<FuncOp> ofMethod(Method method) { } private static Optional<FuncOp> createCodeModel(Method method) { - Class<?> dc = method.getDeclaringClass(); char[] sig = MethodRef.method(method).toString().toCharArray(); for (int i = 0; i < sig.length; i++) { switch (sig[i]) { case '.', ';', '[', '/': sig[i] = '$'; } } - String fieldName = new String(sig) + "$" + "op"; - Field f; + String opMethodName = "method$op$" + new String(sig); + Method opMethod; try { - f = dc.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { + // @@@ Use method handle with full power mode + opMethod = method.getDeclaringClass().getDeclaredMethod(opMethodName); + } catch (NoSuchMethodException e) { return Optional.empty(); } - - String modelText; + opMethod.setAccessible(true); try { - // @@@ Use method handle with full power mode - f.setAccessible(true); - modelText = (String) f.get(null); - } catch (IllegalAccessException e) { + FuncOp funcOp = (FuncOp) opMethod.invoke(null); + return Optional.of(funcOp); + } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } - - FuncOp op; - try { - List<jdk.incubator.code.Op> ops = OpParser.fromString(ExtendedOp.FACTORY, modelText); - op = (FuncOp) ops.get(0); - } catch (RuntimeException e) { - // @@@ Error or Exception? - throw e; - } - return Optional.of(op); } /** diff --git a/src/jdk.incubator.code/share/classes/jdk/incubator/code/internal/CodeReflectionSymbols.java b/src/jdk.incubator.code/share/classes/jdk/incubator/code/internal/CodeReflectionSymbols.java index 4619b214bb7..0cb623f82d3 100644 --- a/src/jdk.incubator.code/share/classes/jdk/incubator/code/internal/CodeReflectionSymbols.java +++ b/src/jdk.incubator.code/share/classes/jdk/incubator/code/internal/CodeReflectionSymbols.java @@ -46,6 +46,8 @@ public class CodeReflectionSymbols { public final MethodSymbol opInterpreterInvoke; public final MethodSymbol opParserFromString; public final MethodSymbol methodHandlesLookup; + public final Type opType; + public final Type funcOpType; CodeReflectionSymbols(Context context) { Symtab syms = Symtab.instance(context); @@ -55,7 +57,8 @@ public class CodeReflectionSymbols { quotedType = syms.enterClass(jdk_incubator_code, "jdk.incubator.code.Quoted"); quotableType = syms.enterClass(jdk_incubator_code, "jdk.incubator.code.Quotable"); Type opInterpreterType = syms.enterClass(jdk_incubator_code, "jdk.incubator.code.interpreter.Interpreter"); - Type opType = syms.enterClass(jdk_incubator_code, "jdk.incubator.code.Op"); + opType = syms.enterClass(jdk_incubator_code, "jdk.incubator.code.Op"); + funcOpType = syms.enterClass(jdk_incubator_code, "jdk.incubator.code.op.CoreOp$FuncOp"); opInterpreterInvoke = new MethodSymbol(PUBLIC | STATIC | VARARGS, names.fromString("invoke"), new MethodType(List.of(syms.methodHandleLookupType, opType, new ArrayType(syms.objectType, syms.arrayClass)), syms.objectType, @@ -67,7 +70,7 @@ public class CodeReflectionSymbols { new MethodType(List.of(syms.stringType), opType, List.nil(), syms.methodClass), opParserType.tsym); - methodHandlesLookup = new MethodSymbol(PUBLIC | STATIC, + methodHandlesLookup = new MethodSymbol(PUBLIC | STATIC, names.fromString("lookup"), new MethodType(List.nil(), syms.methodHandleLookupType, List.nil(), syms.methodClass), diff --git a/src/jdk.incubator.code/share/classes/jdk/incubator/code/internal/ReflectMethods.java b/src/jdk.incubator.code/share/classes/jdk/incubator/code/internal/ReflectMethods.java index 9a5dc7dcb31..8b67add25d6 100644 --- a/src/jdk.incubator.code/share/classes/jdk/incubator/code/internal/ReflectMethods.java +++ b/src/jdk.incubator.code/share/classes/jdk/incubator/code/internal/ReflectMethods.java @@ -101,6 +101,8 @@ import static com.sun.tools.javac.code.Flags.NOOUTERTHIS; import static com.sun.tools.javac.code.Flags.PARAMETER; +import static com.sun.tools.javac.code.Flags.PUBLIC; +import static com.sun.tools.javac.code.Flags.STATIC; import static com.sun.tools.javac.code.Flags.SYNTHETIC; import static com.sun.tools.javac.code.Kinds.Kind.MTH; import static com.sun.tools.javac.code.Kinds.Kind.TYP; @@ -203,9 +205,8 @@ public void visitMethodDef(JCMethodDecl tree) { // dump the method IR if requested log.note(MethodIrDump(tree.sym.enclClass(), tree.sym, funcOp.toText())); } - // create a static final field holding the op' string text. - // The name of the field is foo$op, where 'foo' is the name of the corresponding method. - classOps.add(opFieldDecl(methodName(bodyScanner.symbolToErasedMethodRef(tree.sym)), tree.getModifiers().flags, funcOp)); + // create a static method that returns the op + classOps.add(opMethodDecl(methodName(bodyScanner.symbolToErasedMethodRef(tree.sym)), funcOp)); } catch (UnsupportedASTException ex) { // whoops, some AST node inside the method body were not supported. Log it and move on. log.note(ex.tree, MethodIrSkip(tree.sym.enclClass(), tree.sym, ex.tree.getTag().toString())); @@ -401,6 +402,21 @@ private JCVariableDecl opFieldDecl(Name prefix, long flags, CoreOp.FuncOp op) { return opFieldTree; } + private JCMethodDecl opMethodDecl(Name methodName, CoreOp.FuncOp op) { + var mt = new MethodType(com.sun.tools.javac.util.List.nil(), crSyms.funcOpType, + com.sun.tools.javac.util.List.nil(), syms.methodClass); + var mn = names.fromString("method$op$").append(methodName); + var ms = new MethodSymbol(PUBLIC | STATIC | SYNTHETIC, mn, mt, currentClassSym); + currentClassSym.members().enter(ms); + + var opFromStr = make.App(make.Ident(crSyms.opParserFromString), + com.sun.tools.javac.util.List.of(make.Literal(op.toText()))); + var ret = make.Return(make.TypeCast(crSyms.funcOpType, opFromStr)); + + var md = make.MethodDef(ms, make.Block(0, com.sun.tools.javac.util.List.of(ret))); + return md; + } + public JCTree translateTopLevelClass(JCTree cdef, TreeMaker make) { // note that this method does NOT support recursion. this.make = make; diff --git a/src/jdk.incubator.code/share/classes/jdk/incubator/code/parser/OpParser.java b/src/jdk.incubator.code/share/classes/jdk/incubator/code/parser/OpParser.java index 9d67c1ae98a..ac8de78ea54 100644 --- a/src/jdk.incubator.code/share/classes/jdk/incubator/code/parser/OpParser.java +++ b/src/jdk.incubator.code/share/classes/jdk/incubator/code/parser/OpParser.java @@ -162,6 +162,7 @@ public static List<Op> fromString(OpFactory opFactory, TypeElementFactory typeFa * @param in the input string * @return the func operation */ + //@@@ visit return type public static Op fromStringOfFuncOp(String in) { Op op = fromString(ExtendedOp.FACTORY, in).get(0); if (!(op instanceof CoreOp.FuncOp)) {