diff --git a/make/build.properties b/make/build.properties --- a/make/build.properties +++ b/make/build.properties @@ -95,6 +95,7 @@ javac.includes = \ javax/annotation/processing/ \ javax/lang/model/ \ javax/tools/ \ + java/dyn/ \ com/sun/source/ com/sun/tools/javac/ javac.tests = \ diff --git a/src/share/classes/com/sun/tools/javac/code/Flags.java b/src/share/classes/com/sun/tools/javac/code/Flags.java --- a/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -216,6 +216,16 @@ public class Flags { * Flag that marks a Sun proprietary class. */ public static final long PROPRIETARY = 1L<<38; + + /** + * Flag that marks a method that should be invoked dynamically . + */ + public static final long INVOKEDYNAMIC = 1L<<43; + + /** + * Flag that marks a method that should be invoked dynamically . + */ + public static final long BOOTSTRAPINVOKEDYNAMIC = 1L<<44; /** Modifier masks. */ diff --git a/src/share/classes/com/sun/tools/javac/code/Symtab.java b/src/share/classes/com/sun/tools/javac/code/Symtab.java --- a/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -139,6 +139,9 @@ public class Symtab { public final Type iteratorType; public final Type annotationTargetType; public final Type overrideType; + public final Type dynamicType; + public final Type linkageType; + public final Type invokeDynamicType; public final Type retentionType; public final Type deprecatedType; public final Type suppressWarningsType; @@ -379,6 +382,9 @@ public class Symtab { iteratorType = enterClass("java.util.Iterator"); annotationTargetType = enterClass("java.lang.annotation.Target"); overrideType = enterClass("java.lang.Override"); + dynamicType = enterClass("java.dyn.InvokeDynamic"); + linkageType = enterClass("java.dyn.Linkage"); + invokeDynamicType = enterClass("java.dyn.InvokeDynamic"); retentionType = enterClass("java.lang.annotation.Retention"); deprecatedType = enterClass("java.lang.Deprecated"); suppressWarningsType = enterClass("java.lang.SuppressWarnings"); diff --git a/src/share/classes/com/sun/tools/javac/comp/Check.java b/src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -1714,6 +1714,12 @@ public class Check { if (!isOverrider(s)) log.error(a.pos(), "method.does.not.override.superclass"); } + + if (a.annotationType.type.tsym == syms.invokeDynamicType.tsym) { + //TODO Remi check if its a non static method + s.flags_field |= Flags.INVOKEDYNAMIC; + s.owner.flags_field |= Flags.BOOTSTRAPINVOKEDYNAMIC; + } } /** Is s a method symbol that overrides a method in a superclass? */ diff --git a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -649,6 +649,12 @@ public class ClassWriter extends ClassFi endAttr(alenIdx); acount++; } + if ((flags & BOOTSTRAPINVOKEDYNAMIC) != 0) { + int alenIdx = writeAttr(names.BootstrapInvokeDynamic); + databuf.appendChar(pool.put(syms.linkageType.tsym)); + endAttr(alenIdx); + acount++; + } return acount; } diff --git a/src/share/classes/com/sun/tools/javac/jvm/Items.java b/src/share/classes/com/sun/tools/javac/jvm/Items.java --- a/src/share/classes/com/sun/tools/javac/jvm/Items.java +++ b/src/share/classes/com/sun/tools/javac/jvm/Items.java @@ -491,7 +491,11 @@ public class Items { Item invoke() { MethodType mtype = (MethodType)member.externalType(types); int rescode = Code.typecode(mtype.restype); - if ((member.owner.flags() & Flags.INTERFACE) != 0) { + //XXX Remi ugly hack + if ((member.flags() & Flags.INVOKEDYNAMIC) != 0) { + member.owner = syms.dynamicType.tsym; + code.emitInvokeinterface(pool.put(member), mtype); + } else if ((member.owner.flags() & Flags.INTERFACE) != 0) { code.emitInvokeinterface(pool.put(member), mtype); } else if (nonvirtual) { code.emitInvokespecial(pool.put(member), mtype); diff --git a/src/share/classes/com/sun/tools/javac/util/Name.java b/src/share/classes/com/sun/tools/javac/util/Name.java --- a/src/share/classes/com/sun/tools/javac/util/Name.java +++ b/src/share/classes/com/sun/tools/javac/util/Name.java @@ -437,6 +437,7 @@ public class Name implements javax.lang. java_lang_Cloneable = fromString("java.lang.Cloneable"); java_io_Serializable = fromString("java.io.Serializable"); java_lang_Enum = fromString("java.lang.Enum"); + java_dyn_Dynamic = fromString("java.dyn.Dynamic"); package_info = fromString("package-info"); serialVersionUID = fromString("serialVersionUID"); ConstantValue = fromString("ConstantValue"); @@ -466,6 +467,7 @@ public class Name implements javax.lang. RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations"); Value = fromString("Value"); EnclosingMethod = fromString("EnclosingMethod"); + BootstrapInvokeDynamic = fromString("BootstrapInvokeDynamic"); desiredAssertionStatus = fromString("desiredAssertionStatus"); @@ -571,6 +573,7 @@ public class Name implements javax.lang. public final Name java_io_Serializable; public final Name serialVersionUID; public final Name java_lang_Enum; + public final Name java_dyn_Dynamic; public final Name package_info; public final Name ConstantValue; public final Name LineNumberTable; @@ -600,6 +603,7 @@ public class Name implements javax.lang. public final Name Value; public final Name EnclosingMethod; + public final Name BootstrapInvokeDynamic; public final Name desiredAssertionStatus; diff --git a/src/share/classes/java/dyn/Dynamic.java b/src/share/classes/java/dyn/Dynamic.java new file mode 100644 --- /dev/null +++ b/src/share/classes/java/dyn/Dynamic.java @@ -0,0 +1,5 @@ +package java.dyn; + +public interface Dynamic { + +} diff --git a/src/share/classes/java/dyn/InvokeDynamic.java b/src/share/classes/java/dyn/InvokeDynamic.java new file mode 100644 --- /dev/null +++ b/src/share/classes/java/dyn/InvokeDynamic.java @@ -0,0 +1,12 @@ +package java.dyn; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface InvokeDynamic { + // marker annotation +} diff --git a/src/share/classes/java/dyn/Linkage.java b/src/share/classes/java/dyn/Linkage.java new file mode 100644 --- /dev/null +++ b/src/share/classes/java/dyn/Linkage.java @@ -0,0 +1,5 @@ +package java.dyn; + +public class Linkage { + +}